The issue began when we tried to deploy. We set up different Redis caches for the different environments (dev/qa, staging and prod). We didn’t want to store the access key in source control, so we did our usual of putting the keys in our Azure Key Value and then pulling the keys in via release definition variable groups. We’ve done this loads of times to swap out app settings, connection strings, etc. I’ve written about web.config transforms before; the only added step is to also check “XML variable substitution” on your deployment task. Variable substitution is well documented here.

Anyway, it became clear that I would not be able to swap out the Redis configuration for the access key that way. Searching around on Google, I couldn’t find an easy or out of the box way to do this. So I did it myself.

The release task takes your artifact zip, unzips it and pushes it to your Azure app. It’s pretty simple, except when you need to modify artifacts INSIDE the zip. Therefore, we have to do the following steps:

Unzip the artifact

Figure out where the web.config is inside of the unziped result

Perform the replacement of the access key

Re-zip the folder structure and replace the original zip

Fortunately, this can be cobbled together with a handful of tasks available on VSTS. You will, however, have to install this guy so we can use the Tokenizer task found within.

Step 3: Tokenize what you need to replace

We need to tokenize the values we want to replace throughout the web.config. The way I did it was by using my web.config transform method I talked about earlier. I created a web.tokenize.config that targeted my access key and replaced it with a token. My transform file looks like this:

Note: $(webRoot) is using the trans-task variable output from the PS task in step 2. Your variable name may differ.

Working folder – $(webRoot)

Transformations – Web.Tokenize.config => Web.config

Step 4 – Run a tokenizer

The tokenizer from the utility pack I had you install works pretty simply: it finds tokens like __token__ and tries to match it up with a value you provide. You can specify these values via JSON configuration, but since I’m trying to use variables from my Azure Key Vault, I don’t need the JSON configuration. Instead, I added a variable to my release definition called “redisAccessKey” that pulled from the Azure Key Vault. Mind you, your variable should be named “redisAccessKey”, not “__redisAccessKey__”.

Add the Tokenizer task.

Source filename – $(webRoot)/Web.config

Destintation filename – $(webRoot)/Web.config

As you can see, we want to overwrite the web.config once the tokens have been replaced.

Step 5 – Re-zip it

Finally, we can re-zip it for deployment. Add an “Archive files” task.

Conclusion

Obviously, I’d love to get rid of this if the deployment task would include the ability to do this. For now, this will work. Also, this can clearly be applied to all sorts of things, not just web.config attributes. Good luck!