VSTS Replace Tokens task is not replacing ConnectionString

06 Mar 2019

Replace Tokens is a Visual Studio Team Services (VSTS) build and release extension that can replace the text tokens in a file with the defined pipeline variable. This extension comes as a handy task to replace tokens in .config files with a deployment zone (Dev, QA, Staging & Live or Location specific settings) configurations like database connection strings, API keys, application configuration keys etc.,

Substituting the application config/setting values based on server to be deployed, usually happens during release pipeline. So, I've added Replace Token task to my release pipeline tasks and replaced few application settings and connection strings with release variables. Most of the tokens got replaced/transformed as expected, except the tokens within the <ConnectionString> tag.

Build

Here is my default web.config file setup,

<!-- Web.Config -->
<connectionStrings>
<add name="myconnectionstring" connectionString="data source= ....;"/>
</connectionStrings>

Then on the web.release.config, I've used XML Document Transformation (XDT) to transform the connection string in web.config file with replaceable string token(#{myconnectionstring}#) to make it suitable for Replace Tokens to do its magic.

<!-- Web.Release.Config -->
<connectionStrings>
<add name="myconnectionstring" connectionString="#{myconnectionstring}#" xdt:Transform="SetAttributes" xdt:Locator="Match(name)"/>
</connectionStrings>

So after performing MSBuild with release configuration, the web.config gets transformed with the tokens from the release config. The resultant web.config is as follows 

<!-- Web.Config after build in release configuration-->
<connectionStrings>
<add name="myconnectionstring" connectionString="#{myconnectionstring}#"/>
</connectionStrings>

Release

In the release pipeline, Replace Tokens task was added right before IIS web application deploy task. After deployment to server, I was surprised to see the token text sitting in the value attribute intact. I tried changing the text cases, trim spaces, etc., if it changes the replace output without any success.

 After series of random config change and application release try-outs, finally I made a decision to look at the actual build artifact. I had downloaded the artifact from the Build Summary, and extracted it to my local system. Looking at web.config file within extracted zip folder showed me a different issue or feature less known to us. 

<!-- Web.Config within build artifact-->
<connectionStrings>
<add name="myconnectionstring" connectionString="$(ReplacableToken_myconnectionstring-Web.config Connection String_0)"/>
</connectionStrings>

Microsoft has a different approach for tokenizing the connectionStrings, and this feature is ON by default. So, all replaceable parameters are extracted to a separate XML file named parameters.xml making it easier for customizing based on environment and those placeholders are filled with $(ReplaceableToken_name-Web.Config Connection String_0). This actually hinders with the job performed by the Replace Tokens task.

If you are happier with default MS provided solution you can opt to do that way - just replace the parameters.xml based on the release zone i.e., QA or Live.

Or else, if you want the Replace Tokens extension to work... then you can simply disable this auto parameterization by specifying following in the application .csproj.

<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
...
<AutoParameterizationWebConfigConnectionStrings>False</AutoParameterizationWebConfigConnectionStrings>
  ...
</PropertyGroup>

So after above change, my replace tokens within web.config were replaced as expected.

Hope this article gives you an idea on what happens behind the hood and saves your time. Happy Hacking!