In this blog I will explain how to separate your settings from your configuration files, when deploying from VSTS. I will show with an example how you can deploy your WebApp and store all variables in VSTS, eliminating the need for developers to have all settings and configurable values within Web.config transformation files.
When deploying your WebApp to various on-premise environments from VSTS, you can use Web.config transformations for separation of your various variables. But, sometimes, the *.Config transformations do not meet your needs.
For most .Net developers, using transformations is a standard procedure to separate your Debug and Release settings while deploying from Visual Studio. It is fully integrated in Visual Studio and is easy to use when deploying or creating packages from your code. These transformations can also be used within VSTS builds, but the disadvantage is that all settings should be present within your solution and code-base.
Take for example the following situation. Building a generic SQL server backed WebApp, releasing this app to your localhost, and Test, Staging and Production environments.
Testing your transformations is easy with the free online tool Web.config Transformation Tester.
In this example, a simple transformation can only be setup using more than one transformation if there are more than one database connection strings. In Visual Studio this can be resolved using the example below:
The example above shows the Release config, with the transformation (matched by name) of a ConnectionString. This has some disadvantages. First of all, for every new setting, each transformation file should be extended or modified. Secondly, every developer has access to all the settings, even for the production servers.
Using tokens in combination with transformation
This is where the tokens come in, and help you separate the settings of all different environments with your code-base. The transformation still can be used, but now we do not insert the actual values but token placeholders.
First of all, we do not necessarily have to use different transformations for different environments. In this example we will run Release builds for all environments, Test, Staging and Production.
Setup in VSTS
When running this example (using a Release build), the connectionString will be replaced with __ConnectionString__, which obviously will not work for your application. We will have to make sure these tokens are replaced with the correct values per environment.
You will need to install an extension by Guillaume Rouchon; Replace Tokens. There are more extensions that will do this task, and optionally you could write one yourself. I’m using this extension because it fits the needs perfectly and is free of charge.
After installing the extension, you should add the build step to your Build Definition in VSTS.
In the above example, the target files to process are all *Release.config files in all folders. For an elaboration of all values please see the documentation of the plugin. For this example the prefix and suffix are most important. These both are a double underscore, and those correspond to the value of our example __ConnectionString__ which is going to be replaced. You could choose any other string or character if you want.
Define variables in VSTS
The last step is to add the variables to VSTS. This is done in the ‘Variables’ tab of the Build Definition:
Please note that the variables do not have the prefix and suffix as used in the Web.Release.config files.
Everything is in place
When all steps are configured correctly, the system will execute the following steps:
- The ‘Replace Tokens’ extension will replace the __ConnectionString__ in Web.Release.Config with the actual value set in the variables section of your definition.
- The build solution step will execute the transform, as it would normally do. But in this case the first step has changed the token with the actual value to be deployed into your application
- Publishing your application with the correct ConnectionString in the Web.config ensures the target application will use the ConnectionString as defined in your Build Definition variables.
Using this setup, you are able to move the actual settings normally contained in your transformation files to your build definition in VSTS. In a fully automated CICD pipeline this enables you to shield settings from developers, and enable you to stop builds on missing variables.
Another advantage is that if a new environment is needed, like a Demo environment based on Production, only a Build Definition has to be added with new variables, and no additional transformation files are needed in your code-base.