Friday, November 27, 2015

Sitecore Deployments using OctopusDeploy - Part 3 (Handling environment specific Configuration)

Part 1 | Part 2 | Part 3 | Part 4

This is my third post in this series and I am going to talk about different ways to handle configuration changes specific to each environment OR even each role within an environment.

While handling deployments in multiple environments, it is always a question with respect to how to handle environment specific configuration changes? This is not a new problem to solve for !!

There are primarily two stages wherein you can handle environment specific configurations in automated way (without relying on error prone manual editing of configurations by logging into specific environments and performing live changes).

Handling transformations during the build phase
Handling it at the time of build phase through your continuous integration platform. Problem with this approach is for each environment, you need to run a separate build to ensure the transformations are run for that specific environment and the resulting packages include relevant configurations. With this approach, you are deploying different packages in different environment (though you would have ensured to take the artifacts from the same tag to ensure you are building the right code and packaging the right configurations.

Handling transformations during the deployment phase
Other way to handle this is during deployments. You create a package once and you promote it to various environments as it is. Package contains all the configuration transformation rules you need for each environment right from the beginning. Platforms like OctopusDeploy has a built in support for doing transformations at the time of deploying a release. Alternatively, for some of the common configurations such as AppSettings and ConnectionStrings you can choose the configuration variable replacement concept at the time of deployment. You can read more about it here.

Approach adopted to handle environment specific configuration differences

  1. Configurations that go under sitecore configuration element, Sitecore already has a patching logic which works similar to configuration transformation and Sitecore handles that pretty well. We did not want to re-invent the wheel to do it using our own / visual studio style, also for a reason that we started on handling environment related configurations in automated way little later. This is not to say that what we did was not right, perhaps you may want to keep it the same way even if you are starting your engagement just now.

  2. Handling configurations other than Sitecore (such as web.config / other configuration files)
    • One of the hurdles and debate we came across is - should we include web.config in our package? Usually this is provided by Sitecore as a product and it’s a bad idea to deploy your own web.config will all changes incorporated in it. We wanted to stay away from that by just keeping the config transform rules on top of web.config and not touching the original web.config. But OctopusDeploy does not run the transformation rules if original web.config is not part of the package (because when Octopus extracts the Nuget package, it first runs the transformations before it copies over to the destination folder).
    • We thought of an alternative. OctopusDeploy raises lot of events as part of Nuget package deployment task and as a pre-deploy event, we thought of picking up the original file from the root directory before OctopusDeploy runs the transformation. We realized that as soon as you transform the web.config, you don’t have original web.config anymore at the root !! You can find more about OctopusDeploy feature ordering here
    • We finally decided to include web.config that comes as part of Sitecore default installation (for the Sitecore version we use) and took a cautious call to change it whenever we upgrade to newer version of Sitecore.
    • Few scenarios where this would be handy is appsetting configurations, logging configurations

  3. Handling connectionstrings
    • Connectionstrings contain sensitive information and you can either encrypt whole connectionstrings section using standard ASP.NET / IIS configuration encryption mechanism. You can find more information here on this
    • Challenge was, someone still needs to maintain it in the source control repository and they have to decrypt, change and encrypt it again.
    • OctopusDeploy, as stated earlier, provides a nice feature to replace connectionstrings by means of variable feature, at the time of deployment.

Few considerations :

    • OctopusDeploy handles transformation at the deployment time but it runs it only at an environment level and not at the role level. In our situation, and probably any Sitecore deployment situation, we had several roles as stated in my previous blog, and it was unfortunate that we could not do transformation rules execution at the role level (such as CM / CD, Job etc.).
    • The way we handled it then was either using Sitecore patching logic OR if certain configuration was not relevant for a specific role (such as switchonrebuild / switchtojobserver etc.) then we had a cleanup task after package deployment which was deleting unnecessary files not relevant for that role. We maintained this list of files in an Octopus variable

Happy Deployments !!