Deploying Microsoft Dynamics CRM 4.0
At a Glance:
- Software components of a CRM system
- The development lifecycle
- Elements of a CRM solution
- A look at multi-tenancy
The Solution Development Lifecycle
Elements of a CRM Solution
What about Multi-Tenancy?
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:
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.
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.
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.
Aaron Elder (Microsoft Dynamics CRM MVP) works for Ascentium, a technology consulting and interactive marketing agency. Visit the Ascentium blog atascentium.com/blog/crm.