If you're used to thinking
of CRM as just a sales and marketing management tool, think again.
Microsoft Dynamics Customer Relationship Management is a platform for
developing applications that manage and track information and processes
related to real-world objects. Those objects might be customers, but
they can also be just about any entity (and related activities) that you
need to manage.
As
with any large-scale custom solution, there are some basics related to
deployment that need to be understood. In this article, I am going to
cover a few fundamental concepts related to Microsoft Dynamics CRM
deployment, including how these concepts can be used to support a full
product lifecycle deployment. I will also discuss managing multiple
deployments as part of a single-solution release, and how multi-tenancy
should and should not be used as part of the entire solution lifecycle.
I
want to make clear at the outset of this article that when I refer to a
Microsoft Dynamics CRM "solution," I mean the totality of all
customizations, extensions, custom coding, schema changes, and so forth.
A solution is not just one thing; it is all of your changes together.
Behind
the scenes, a Microsoft Dynamics CRM solution is a standard ASP.NET 2.0
and Microsoft .NET Framework 3.5 data-driven Web application. The
three-tier system includes the following major components:
Data Tier SQL
Server 2005 or SQL Server 2008 database. Using SQL Server 2008 requires
a hot fix as described in the Knowledge Base article "Support for Running Microsoft Dynamics CRM 4.0 together with Microsoft SQL Server 2008."
Middle Tier Microsoft
Internet Information Services (IIS) 6.0 or later Web front end; SQL
Server Reporting Services (SRS) 2005 or SRS 2008; ASP.NET 3.5; custom
Windows Services.
Client Tier Microsoft
Internet Explorer 6.0 or later client; ASP.NET 2.0 or later; Microsoft
Office Outlook 2003 or Office 2007 client (with optional offline
access); others such as SDK consumers and third-party mobile clients.
Microsoft
Dynamics CRM also relies on a variety of external systems including
Microsoft Exchange Server 2003 or later and Active Directory.
The Solution Development Lifecycle
A
Microsoft Dynamics CRM solution goes through the same lifecycle that a
custom application development project would, which might look something
like the process depicted in Figure 1.
Figure 1 The application development cycle
This
entire process would be supported by several environments that together
comprise the development, test, and production systems. In the world of
any multifaceted enterprise application, this, of course, can turn out
to be surprisingly complex. If, for example, you were to mirror your
environments, you might end up with something that looks like Figure 2.
Figure 2 Mirroring your dev, test, and production environments
That's
three domains, three domain controllers, three mail servers, three Web
servers and three database servers—and this model assumes that SRS and
CRM are on the same box, and it does not take into account things such
as load balancing. Now let's imagine you add redundancy and a few
external services such as Microsoft Office SharePoint Services (MOSS),
and you could end up with a scheme like the one in Figure 3.
Figure 3 Increasing complexity
For
cost and complexity reasons, trade-offs might be considered to balance
the need for environment isolation against the need to keep costs down
and manageability up. Organizations have thus looked to a variety of
techniques, such as virtualization and the Microsoft Dynamics CRM
built-in multi-tenancy features, to address these challenges.
When
designing a set of environments to support your CRM project's
lifecycle, there are several schools of thought and, depending on what
principles are important to you, you might choose to go one way or the
other. At one end of the spectrum, designers promote total isolation
using exact replication. These folks believe that the only way to
validate that something will work outside of production is to have a
test environment that is 100% identical to the production environment.
Every server, every bit, and every setting must be identical and
completely isolated from development and production for testers and IT
to accept and believe something will work in production.
In
contrast, others think that sort of isolation doesn't really matter at
all. If they could, they would develop and test directly in the
production environment. They tend to see the redundancy as a waste of
time and money, and they are certain delivery would be easier if they
could just get in there and make things work.
Hopefully,
you fall somewhere in between these extremes and will be open to the
idea that when it comes to a Microsoft Dynamics CRM-based solution, it
is possible to develop a hybrid that balances complexity, cost,
isolation, and manageability.
Elements of a CRM Solution
Microsoft
Dynamics CRM solutions components can be divided into four major
buckets, and your solution may include one, two, three, or all four.
Customizations They
include form, grid, schema, and metadata changes; security roles;
workflows; system settings; and templates. Microsoft Dynamics CRM
customizations are provided as one or more (typically one or two) zipped
XML files. They are imported into a CRM deployment via the Outlook or
Web client "Settings?|?Customization" area and then are "published" to
make them active. All of this can be automated using code that is
written against the Microsoft Dynamics CRM SDK.
Extensions These
include reports and custom code such as plug-ins that must be deployed
separately from the customizations. Plug-in registration information is
stored as an XML file and can be deployed via either a command-line or
Windows Form application provided by Microsoft. This also can be
automated via code written against the Microsoft Dynamics CRM SDK.
Custom Code Anything
developed as part of your solution, and it might consist of external
Web services, custom Web application components, and so forth. The rules
and practices for deploying the custom code should be no different than
for any other custom Web application.
Data Any
information that needs to be imported into an environment for that
environment to function. This might include domain data (such as a list
of product codes) or users. The data that your solution needs can be
deployed into your Microsoft Dynamics CRM instance using scripted code
or CRM's Bulk Import feature, or with some form of external process
using BizTalk or other ETL (extract, transform, load) tool. Some data,
such as Users, needs to be created manually or through Microsoft
Dynamics CRM SDK calls.
I
like to think of CRM solution deployments just as though they were
custom application development deployments. This means that during
development and test, each new build of the solution is installed from a
clean base system and the process is as repeatable and scripted as
possible.
What about Multi-Tenancy?
Now
let's discuss what the environment you are going to deploy them into
should look like. You may have read about the Enterprise Edition of
Microsoft Dynamics CRM 4.0 support for a feature called multi-tenancy,
which lets you partition multiple instances of Microsoft Dynamics CRM
within a single deployment. This means that several completely distinct
organizations with their own reports, workflow, customizations, and
schemas can be run on the same set of hardware using the same physical
servers and the same database instances and IIS Web sites.
At
first glance, this might appear to be the panacea that solves all of
our manageability, isolation, and cost conundrums. Such a solution might
be visualized as in Figure 4.
Figure 4 A multi-tenancy-only solution
This
seems logical because each organization gets its own physical database
on the shared SQL Server or instance (which includes customizations,
workflows, users, roles, and settings) and its own SQL Reporting
Services folder.
This
model works perfectly well if those distinct organizations are part of
different team or departmental solutions. This, after all, is what
multi-tenancy was designed for. While it is true that each organization
(or tenant) gets its own database, they all share the same
organizational unit (OU) and Active Directory groups, and they will all
share the same platform services and front-end application as well. This
means that the same asynchronous service and IIS Web site will be
shared among organizations. The front-end servers are able to "host"
these different organizations through a URL provider that determines,
based on the URL, which organization to host.
Take
these URLs as an example: crmserver/ContosoDevOrg/loader.aspx and
crmserver/ContosoTestOrg/loader.aspx. The CRM server looks at the root
directory to determine the name of the organization to serve up. If no
root organization name is found, as in the case of
crmserver/loader.aspx, the server defaults to the first organization
created in the deployment or the one where the calling user has access.
Because
the same Web site is used for both organizations, if you have custom
code as part of your solution, it too will be shared by both
organizations; for example,
crmserver/ContosoDevOrg/ISV/mycustomdialog.aspx and
crmserver/ContosoTestOrg/ISV/mycustomdialog.aspx.
Both
point to the same physical file on disk, such as
C:\inetpub\wwwroot\isv\mycustomdialog.aspx. Since it is likely that the
version of a custom extension would be different between Dev, Test, and
Production, this can pose a serious problem. Let's assume, for example,
that Build 11 of your application is currently being developed, while
Build 9 is in UAT (user acceptance testing) for test. If you attempt to
use multi-tenancy to solve your environment problem, you will have a
hard time isolating these two builds. In such situations, some of you
might be tempted to try the solution shown in Figure 5.
Figure 5 Attempting to use different IIS servers to segregate your custom solutions code
In that model (if you are no longer using the Network Load Balancing address), users might hit a URL that looks like this:
Development 192.168.1.100/ContosoDevOrg/loader.aspx
Test 192.168.1.105/ContosoTestOrg/loader.aspx
Production 192.168.1.110/Contoso/loader.aspx
This
model lets you have three separate front-end servers, hosting three
different organizations, with three different code bases on disk. As
long as a user doesn't inadvertently hit the wrong organization on the
wrong server, everything should work out perfectly.
Unfortunately,
since all front-end servers are considered a part of the same
deployment, difficulties start to arise a little further downstream than
you might realize at first glance. This really becomes a challenge if
your solution uses asynchronous plug-ins or workflows, because while you
can control which servers your users hit, you cannot control which
asynchronous service will process events and requests for which
organizations.
This
is because all asynchronous services in a deployment work in a
round-robin manner, and, as such, your development server's asynchronous
service might process a workflow, system job, or asynchronous plug-in
response to a request from your test server, thus blowing the isolation
requirement right out of the water. In addition, if your custom code
that is run by this asynchronous process relies on files that must be
deployed on disk to the server (such as a configuration file or a file
in the Global Assembly Cache, or GAC), you will get version conflicts.
It
is important to note that, for the most part, these challenges arise
only when you are writing custom code that needs to be deployed on disk
or if your custom code relies on resources that would be available only
on or from a particular server. If your solution is simple and only uses
customizations (schemas, forms, views, and so forth), workflows, and
reports, you won't have any problems using the approach in Figure 4.
So
what is multi-tenancy for and when is it a good solution for product
lifecycle environments? Multi-tenancy was originally designed to solve a
hardware problem related to the hosting of multiple distinct tenants in
a production environment, and it does this very well. Previously, in
Microsoft Dynamics CRM 3.0, each deployment, or tenant, had to have its
own dedicated SQL Server or SQL Server instance, as well as a front-end
server.
This
was true for many reasons, including the fact that deployment-specific
settings used to be stored in the registry and on disk. All of these
configurations have now moved to the database, so a single application
server is able to handle multiple organizations. Multi-tenancy comes in
handy for hosted versions of CRM including Microsoft Dynamics CRM
Online.
Design Considerations
Now
that you're aware of some potential issues, let's discuss some points
to keep in mind as you design your deployment. The answer, of course, is
that it depends. It is certainly possible to run a full CRM environment
(including the domain controller, SQL server, and Web server) on a
single box, as you can see on the Microsoft Dynamics CRM 4.0 Virtual
Machine demonstration (see the "CRM Resources" sidebar for the URL). It
is very common to use a single machine virtual image for a development
environment. For test, however, it is important to validate key
production environment challenges, and, for this reason, I recommend
having your test environment mirror your production environment in terms
of structure but not capacity. Your environment might look like the one
in Figure 6.
Figure 6 The test environment structure should mirror the production structure
In
this approach, you try to minimize physical hardware of the
infrastructure using virtualization and further attempt to minimize
virtualization resources by virtualizing only key scenarios that need to
be tested. You will be able to allow your developers to develop on a
single server image (or images, if they have their own virtual machine
on their personal desktops) if you ensure that they will pay attention
and be aware of the environment to which their solution will be
deployed. The issues that developers should be paying attention to are
the same issues you should be building your test environment to
validate, including:
Make the Settings Configurable Don't, for example, assume the server will respond to localhost or a particular port.
Be Aware of Multiple Servers Don't assume things will work without setting up proxy users or trust for delegation.
Keep Load Balancing in Mind Be
very careful with session state and caching. Note that Microsoft
Dynamics CRM is designed to be completely stateless and work well with a
round-robin load balancer.
Think about Multi-Tenancy When
multiple tenants are hosted on a single machine, they share the same
process space. This means that elements such as caches need to be keyed
by the organization name so that users from one organization will not
inadvertently utilize data from another organization. In addition, when
you have client-side code that has links or calls back to the server,
you need to be sure that the calls preserve the organization name in the
URL; otherwise, you might hit the default organization or an
organization you do not expect.
Key Takeaways
Isolation Is Important When
designing your solution, keep in mind which approach (as illustrated in
Figures 4, 5, or 6) will work best for you and be aware of when and
where your custom code might run. It's also worth noting when you do not
need to worry about such issues because of the type of extensions your
solution uses.
Virtualization Virtualization
helps reduce complexity in building an environment that mirrors key
test scenarios of production. Here is some guidance about the setup. Put
CRM and SQL Server on separate servers. This helps verify trust for
delegation and other related issues. CRM servers should be
load-balanced, which will help identify session, caching, and
cross-server issues. Finally, put the domain controller and e-mail on
separate servers; this helps in identifying connectivity issues.
Refresh Environment for Each Build As
a general rule, it's a good idea to create backups either of the
virtual environments or simply of the Microsoft Dynamics CRM databases
(Data and Config) that can then be restored to get the server back to a
"vanilla" state. You then do a full clean deployment into a fresh
environment each time, including custom code, customizations, plug-ins,
and domain data.
Redundancy/Performance Testing Can Be Done Separately Except
for very large organizations, you can usually tackle failover and
performance testing through isolated simulations and not through
"real-world" build-outs. This means that it is not necessary for you to
attempt to build out a test environment that enables testing of these
scenarios. As an alternative, you can rely on testing them either in
production or in separate one-off environments.
In
closing, Microsoft Dynamics CRM is a scalable, enterprise-class system
that, when appropriately configured and deployed, can handle small
teams, enterprise-wide solutions, and every option in between. Trying to
determine which product lifecycle environment is right for you will
depend on a variety of factors.
Generally
speaking, multi-tenancy is not an ideal way to address the product
lifecycle development challenges of complex solutions and is best used
when it is fully understood. Simple solutions that require only basic
customization or that make use of properly coded and isolated custom
extensions that don't rely on disk resources or server-specific access
should do just fine following the model depicted in Figure 4.
If
your solution demands more isolation, server-specific resources, or
access (perhaps an external service is only allowed through your VLAN
from one specific server to another), and so forth, I recommend going
with the model shown in Figure 6. And I'd recommend avoiding the approach that Figure 5 illustrates, as it is a hybrid hack at best.
Ultimately,
Microsoft Dynamics CRM can be deployed in thousands of configurations,
and exactly what is right for you will depend on what your solution
requires. With a better understanding of multi-tenancy, single-server
development environments, virtual test environments, and what testable
scenarios are important to you, you should be able to design a product
lifecycle deployment that is both functional and cost-effective.