Avoiding repeated Web.config transformations in Azure Devops pipelines
I recently experienced an issue where the way I was doing web.config transformations was resulting in duplicated lines in the transformed file, after it was pumped through an Azure DevOps pipeline build and release.
In the build pipeline, as defined in azure-pipelines.yaml, I have a step to publish the web project to a folder, which then later gets zipped up and deployed.
The configuration is being set to Release.
When this step is run, it will GENERATE a Web.config file if one does not already exist. If you have no Web.config or Web.XXXX.config files, then it will most likely look something like this, defining the hosting model as “inprocess”:
Now in my case, I’m going to host the production version of this site on Azure, and I wanted some extra congiguration added, for rewrite rules (they could be configured in code in the new .NET Core project, but I’m going through a migration from .NET Framework and I just wanted to move across all my existing rules for now).
So I created a Web.Release.config file, in which I set up a “insert” transformation, like this:
Don’t worry about the rewrite rules themslves, just note that I had it set to do an “Insert” type of transformation.
As a result of this, if I ran dotnet publish
as per above with the configuration set to “Release”, I would end up with a transformed Web.config file, that also included the rewrite section.
So I thought I was winning!
Sad face: downtime as a result of deployment
The next step was for my release pipeline to run.
I am running all this in production on an Azure App Service. I have an older .NET Framework app running in another app service, and I’m using YARP as a revesre proxy to allow me to migration from Framework to Core see my other articles about this.
Now, since I was creating this .NET Core project deployment very similarly to my old .NET Framework one, when I added in my new .NET Core app service deploy step, I copied the setting across under “File Transforms & Variable Substitution Options” for XML Transform – setting it to “true”.
The problem is, by the time the file gets to the point of being deployed to my production environment, the Web.config file has already had that transformation applied to it, so I was ending up with two rewrite
sections:
And naturally that was causing the site to fall over.
The solution was simple: when doing the deploy to production, do NOT check the option for “XML Transform”.
But what about for test enviornments along the way?
For my test environments along the way (e.g. “staging”), I may still want to run a transformation (although in .NET Core land, I am obviously trying to move away from using web.config at all - so for now it really is only the rewrite section that I have to worry about). So I tried creating a Web.
The problem is, in the Azure Pipeline, the abovementioned “XML Transform” option will do a transformation with Web.Release.config and THEN do the Web.
In my case, I’m not too worried about leaving the rewrite
section in these test environments, because of the types of rewrites I’m doing, but this will depend on what you have in your web.config.
My solution fr now is that I’m just going to turn off the XML Transform on all the environment deploys, and not have any transformation for any environments or configurations other than Release.
There’s another option that I could explore if I really needed special transformations to run on those test environments: using Web.Production.config instead of Web.Release.config for my production environment specific transformations. That could work, but again I’m not too worried about this for now. If you’re interested in doing this but not sure how to, let me know and I can addd it in - it’s how I’ve done it in the past when using other deploy tools that did transformations a little differently.