Skip to content

Getting rid of transformations, allow the same build to run in any environment

Its always been a hassle for me to manage web.config transforms, and slow cheetah transformations for config files, it is annoying to have you build servers do multiple builds to essentially have the same code compile with a different set of variables.

I saw it solved in octopus deploy, by having the build agent replace tokens within configuration. however a cleaner option was added in .net 4.7.1, ConfigBuilders.

And while it opens up a whole set of options of where to save your configuration and secrets, Azure Storage and similar comes to mind. a handy alternative is to use Environment variables, specially for Sitecore where they can be set locally for the application pool in ApplicationHosts

Luckily Microsoft have an example of just that in a preview NuGet:

  • https://www.nuget.org/packages/Microsoft.Configuration.ConfigurationBuilders.Environment/
  • https://github.com/aspnet/MicrosoftConfigurationBuilders

 

Setting up the content builders in web.config

Add config builders to config sections:
<configSections>
<section name="configBuilders" type="System.Configuration.ConfigurationBuildersSection, System.Configuration, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" restartOnExternalChanges="false" requirePermission="false"/>
</configSections>

Add a new section defining your environment builder:
<configBuilders>
<builders>
<add name="Environment" type="Microsoft.Configuration.ConfigurationBuilders.EnvironmentConfigBuilder, Microsoft.Configuration.ConfigurationBuilders.Environment" />
</builders>
</configBuilders> 

Example appSettings using the environment builder:
<appSettings configBuilders="Environment">
<add key="role:define" value="SET env var" />
<add key="env:define" value="Set env var" />
<add key="search:define" value="Solr" />
</appSettings> 

Example App host:
<applicationPools>
<add name="DefaultAppPool" />
<add name="test" />
<add name="xx.xconnect" />
<add name="xx.local">
<environmentVariables>
<add name="role:define" value="Standalone" />
<add name="env:define" value="DEV" />
</environmentVariables>
</add>
<add name=".NET v4.5 Classic" managedRuntimeVersion="v4.0" managedPipelineMode="Classic" />
<add name=".NET v4.5" managedRuntimeVersion="v4.0" />
<applicationPoolDefaults managedRuntimeVersion="v4.0">
<processModel identityType="ApplicationPoolIdentity" loadUserProfile="true" setProfileEnvironment="false" />
</applicationPoolDefaults>
</applicationPools>

Added manually or trough APPCMD which can be easily appended into a Sitecore Installation Framework (SIF) installation. Only matched variables will be replaced in this configuration, there are options to add in new ones from environment automatically, and using prefixes etc. It can easily be expanded to work with connection strings as well, which is already supported from the NuGet package, either do multiple providers and prefix them or use the same one and match on names only. Combined with using the new layered configs from Sitecore version 9 there should be no reason to do transformations by hand.

See the env:define application variable can be used in the following way in Sitecore configuration files:
<?xml version="1.0"?>
<configuration xmlns:env="http://www.sitecore.net/xmlconfig/env/">
<sitecore>
<settings>
<setting name="Some setting" value="Value for development" env:require="DEV" />
<setting name="Some setting" value="Value for QA" env:require="QA" />
<setting name="Some setting" value="Value in production" env:require="Production" />
</settings>
</sitecore>
</configuration>