Thursday, February 27, 2014

Web Deploy / MS Deploy Connection String Parameterisation

MsDeploy/WebDeploy parameterisation is pretty useful.  It allows a decent amount of flexibility to deploy a single artefact to multiple environments. 

But it doesn’t always work quite as expected, specifically for Connection Strings in the configuration file.

Scenario:

If you create Parameter entries in parameters.xml, when you deploy a web application project you will receive a SetParameters.xml file with entries based on the parameters.xml.  When defining the parameters, you can give them friendly parameter names (and even prompt text which is used when deploying via IIS management screens).

However if you look at the parameters.xml file that is created in the zip manifest, you will see non-friendly parameter entries for the connection strings, and if you created a ‘friendly’ parameter in the source parameters.xml, this friendly entry will have no transformation rules applied.

This means during msdeploy, the friendly entries in your SetParameters file are ignored, so the connection strings are not updated in web.config during the deployment.

Details:

So if your source Parameters.xml contains
<parameter defaultvalue="" name="Connection String 1">
    <parameterentry match="/configuration/connectionStrings/add[@name='ConnectionString1']/@connectionString" scope="\\web.config$" type="XmlFile">
    </parameterentry>
</parameter>
<parameter defaultvalue="" name="Connection String 2">
    <parameterentry match="/configuration/connectionStrings/add[@name='ConnectionString2']/@connectionString" scope="\\web.config$" type="XmlFile">
    </parameterentry>
</parameter>

And the following in your SetParameters.xml file using your friendly names

<setparameter name="Connection String 1" value="{connection string you want}">
</setparameter>
<setparameter name="Connection String 2" value="{connection string you want}">
</setparameter>


The compiled manifest parameters.xml will look like
<parameter name="Connection String 1" defaultValue="" />
<parameter name="Connection String 2" defaultValue="" />

<parameter name="ConnectionString1-Web.config Connection String" description="ConnectionString1 Connection String used in web.config by the application to access the database." defaultValue="{default value here}" tags="SqlConnectionString">
<parameterEntry kind="XmlFile" scope="{magic string representing web.config}" match="/configuration/connectionStrings/add[@name='ConnectionString1']/@connectionString" />
</parameter>
<parameter name="ConnectionString2-Web.config Connection String" description="ConnectionString2 Connection String used in web.config by the application to access the database." defaultValue="{default value here}" tags="SqlConnectionString">
<parameterEntry kind="XmlFile" scope="{magic string representing web.config}" match="/configuration/connectionStrings/add[@name='ConnectionString2']/@connectionString" />
</parameter>

As you can see, the friendly name entries have no content, so when deploying your SetParameters values are read from the file, but never applied to the config file.

Resolution:

The fix is pretty simple – remove the friendly entries from source control in parameters.xml and setparameters.xxx.xml, and add non-friendly name entries just to the setparameters.xxx.xml – the non-friendly names are ‘predictable’ although if you are desparate, just check the parameters.xml in the manifest after a build.


1 comment:

  1. Thanks so much for posting this. I thought I was loosing my mind because the appSettings was updating but the connection string wasn't.

    ReplyDelete