Deploying the latest codebase of your Sitecore solution is rarely a worry-free process. There are many things that may go wrong, even if everything was fine on a staging environment. Read on to learn how to make deployments easier and painless for the benefit of both the developer and the client.
Blue-Green deployment
In every project there comes a time when you need to deploy the latest codebase to the production environment. This may lead to quite a few issues as usually the website needs to be taken down for a while to perform the deployment and sanity tests. Even if everything looks good on a staging environment, all sorts of problems may occur when going live. A proposed solution to this problem is Blue-Green deployment. This strategy is based on maintaining two identical environments, one called Blue and one called Green. At any point in time, one of them is used as a production and the other – as a staging environment.
The advantages of such an approach are plenty, most important of them being no downtime during deployment and simple rollback procedure. Another great reason to use Blue-Green deployment is the possibility to test the soon-to-be production environment before making the switch and warm it up.
But how to apply this approach to a site powered by Sitecore? How to handle connection strings, Solr cores, and application settings? Thanks to the possibility of hosting Sitecore in the PaaS (Platform-as-a-Service) model in Azure, all these problems become easy to solve.
Sitecore in PaaS context
For some time now, Sitecore has been available in a Platform-as-a-Service model in Microsoft’s cloud service, Azure. This solution has many benefits, such as the ability to auto-scale during periods of increased traffic on your site, integration of Azure Application Insights with your Sitecore solution, and Azure’s excellent availability and support.
Azure also provides a functionality called Deployment Slots, which allows for isolation of application environments such as production and staging and seamlessly swapping them. Microsoft enumerates some benefits of using the feature, such as:
- the ability to validate the changes before swapping a non-production application with the production one,
- warming up the site before swapping to eliminate downtime,
- easy rollback by swapping back the slots.
You might think that these benefits sound a lot like the benefits of Blue-Green deployment mentioned earlier, and you will be right. Azure's Deployment Slots provide a solid foundation for Blue-Green deployment. This means that by building our Sitecore platform on Azure, we already have a strong starting point towards a more streamlined and error-proof continuous delivery.
Problems to overcome
Trying to fit Sitecore into Blue-Green deployment and Azure PaaS may seem like a lot all at once. This is why it is important to identify the main issues and solve them one at a time. Below, is a list of common head-scratching problems.
Databases
In Sitecore, everything is content and all of Sitecore’s content, be it media files, pages and analytics, lives in its databases. While the Blue-Green strategy comes with many advantages, a smart approach to Sitecore databases is required. For example, analytics data collected on production should always come from the current production instance.
Sitecore 9 architecture may vary from project to project, but it always features databases such as Core, Master, Web, and Forms. Other databases such as Marketing Automation or xDB Reporting can be present, depending on the Sitecore products used. To prepare the databases for Blue-Green deployments, they can be assigned to a group depending on whether they contain data belonging to green/blue instance or staging/production app service slot.
This divides databases into two groups:
- Core, Master, and Web databases are assigned to either a Blue or Green environment,
- All remaining databases are connected to the role of the environment – Staging/Production – rather than the instance "colour".
This kind of separation ensures that data, which should stay on the production instance stays there, but the content depends on the environment being either Green or Blue.
Configuration
Because the two environments may be swapped at any time, the problem of keeping the configuration correct at any time becomes a real issue. In order to use the Blue-Green technique, configuration files should be prepared to work conditionally – based on the role the environment serves at the time. Thanks to Azure and Sitecore’s rule-based configuration approach, the solution is simpler than one might think.
Connection Strings
When preparing environments for swapping with Azure Deployment Slots feature, one might wonder how to keep connection
strings correct at all times. We have different sets of databases for Blue and Green environments, but those may be
swapped at any moment. The connection strings should change depending on the role of the environment. There is no way to
include this kind of conditionality into the ConnectionStrings.config
file.
Fortunately, Azure has a functionality that allows us to define connection strings inside the App Service itself. What’s even better is the fact that one can choose whether a connection string should be app service-specific or slot-specific.
An App Service-specific connection string always follows the App Service during a swap, while a Slot-specific one stays tied to the slot. More about this feature can be found at Set up staging environments in Azure App Service and Azure Web Sites: How Application Strings and Connection Strings Work.
The feature can be found in the Configuration tab of an App Service:
Sitecore Configuration
In some cases, it may occur that Sitecore configuration should be different when the environment is serving as a production instance rather than a staging one. One such example may be the analytics' cluster name.
Thankfully, since 9.0 Sitecore supports rule-based configuration, which solves the problem as configuration modifications can be applied conditionally. For example, we can describe every environment with a setting env which takes values such as Staging and Production. Then, we can apply Sitecore configuration patches based on that setting, e.g.:
<?xml version="1.0" encoding="utf-8" ?>
<configuration xmlns:patch="http://www.sitecore.net/xmlconfig/" xmlns:env="http://www.sitecore.net/xmlconfig/env/">
<sitecore>
<settings>
<setting name="Analytics.ClusterName" env:require="Production">
<patch:attribute name="value">www.cognifide.com</patch:attribute>
</setting>
<setting name="Analytics.ClusterName" env:require="Staging">
<patch:attribute name="value">stage.cognifide.com</patch:attribute>
</setting>
</settings>
</sitecore>
</configuration>
This great feature allows us a single configuration file for all environments, which makes changing configuration easier and less error-prone.
This means that if it was possible to change Application Settings during a swap, all Sitecore configuration files could be made simple and clear. Once again, Azure takes the wheel and solves this problem for us.
Application Settings
Azure allows defining Application Settings the same way as Connection Strings.
This amazing piece of functionality gives us all that is required to prepare our Sitecore solution for Blue-Green deployment. All configuration can be adapted to use either Azure solutions, Sitecore’s rule-based configuration, or both.
Solr
One more concern may appear – Solr cores. There are several of them and some are tied to the content, some to analytics etc. One solution might be to put indexes for both instances on one Solr server. Core names are stored in a Sitecore configuration file and shown above, they can use conditions to always be correct. For example, the Marketing Definitions core’s configuration may look like this:
<index id="sitecore_marketingdefinitions_master" … env:require="Staging">
<param desc="core" patch:instead="param[@desc='core']">staging.sitecore_marketingdefinitions_master</param>
</index>
<index id="sitecore_marketingdefinitions_master" … env:require="Production">
<param desc="core" patch:instead="param[@desc='core']">production.sitecore_marketingdefinitions_master</param>
</index>
And Master one's like this:
<index id="sitecore_master_index" … role:require="ContentManagement or Standalone" env:require="Staging or Prod" envcolour:require="Green">
<param desc="core" patch:instead="param[@desc='core']">green.sitecore_master_index</param>
</index>
<index id="sitecore_master_index" … role:require="ContentManagement or Standalone" env:require="Staging or Prod" envcolour:require="Blue">
<param desc="core" patch:instead="param[@desc='core']">blue.sitecore_master_index</param>
</index>
This way, each instance will use the correct cores after swapping the Deployment Slots.
Another option may utilize two or more separate Solr servers. In this case it is important to remember to set correct Solr connection strings in Azure for all app services (and their deployment slots) that use the indexing platform.
A final look at the architecture
With the discussed schema applied to databases and Solr cores, the final architecture may look like this:
This approach makes not only deploying easier but also introduces a kind of clarity and simplicity to configuration. In return, developers are happier and less prone to making mistakes.
Conclusion
Blue-Green deployment is a wonderful technique that saves time, energy and once done right will pay off during each deployment by allowing beforehand testing and no downtime. It is a truly amazing approach, which makes the previously dreaded Sitecore deployments nice and stress-free.
Hero image by Colin Watts, opens in a new window