I am using msDeploy (3.0) to deploy my MVC applicaiton. I have a build pipeline that generates build artifacts for msdeploy and my deploy pipeline applies appropriate web.config transforms on the Web.config before deploying it to the production instances. One of the transforms includes changes to connection string. However, looking at the deployed instances, it seems like my web.config transforms are being overriden by the parameters in setParameters.xml in my build artifacts.
Ideal behavior would be that I would be to avoid adding any Connection string to the SetParameter.xml so that all my connection string overrides will be controlled by my deployment pipeline only. How do I achieve that?
Below is a sample of SetParameters.xml file
<parameters>
<setParameter name="IIS Web Application Name" value="Default/Foo"/>
<setParameter name="Foo-Web.config Connection String" value="Server=Foo,1433;Database=Bar;Integrated Security=SSPI;MultiSubnetFailover=True;App=Something;Connection Timeout=25"/>
</parameters>
Ideally it would look something like
<parameters>
<setParameter name="IIS Web Application Name" value="Default/Foo"/>
</parameters>
I have already tried passing a parameters.xml file to the msbuild step that does not contain the connectsion string parameter but that did not work
After bang my head against the wall for several hours, I finally figured out the solution. MsBuild takes in a parameter - p:AutoParameterizationWebConfigConnectionStrings=false that prevents the connection strings from being parameterized. Unfortunately, there is little or no documentation on this parameter.
You can also set this on a per project basis adding
<AutoParameterizationWebConfigConnectionStrings>false</AutoParameterizationWebConfigConnectionStrings>
to the PropertyGroup of your build configuration.
Related
I use MSBuild to build and deploy a web application.
MSBuild.exe MySite.csproj /p:DeployOnBuild=True /p:WebPublishMethod=MSDeploy /p:MSDeployServiceURL=mysite.example.com
My site connects to a SQL Server database.
<connectionStrings>
<add name="dbconnection"
connectionString ="Data Source=(local);Initial Catalog=MySite;Integrated Security=SSPI;"
providerName="System.Data.SqlClient" />
</connectionStrings>
I develop against a local database, but the connection string needs to be changed when the site is deployed to test or production servers.
I have declared a deployment parameter named dbconnection in a file named parameters.xml
<parameter name="dbconnection"
defaultValue="Data Source={server};Initial Catalog={database};Integrated Security=SSPI;"
tags="DBConnectionString">
<parameterEntry type="XmlFile"
scope="\\Web.config$"
match="/configuration/connectionStrings/add[#name='dbconnection']/#connectionString"/>
</parameter>
I could easily create a parameterized web deploy package and deploy it with msdeploy.
msdeploy -verb:sync
-source:package:MySite.zip
-dest:iisApp="Site1/MySite"
-setParam:name=dbconnection,value="Data Source=.\SQLEXPRESS;Initial Catalog=MySiteTest;Integrated Security=SSPI"
However, I'd really like to be able to do everything in MSBuild. What is the MSBuild equivalent of -setParam?
Parameterization is not used when debugging locally. So all you should have to do is set the defaultValue in your parameters.xml file to your desired connection string.
We create a SetParameters file for each environment (DEV, QA, MOCK, PROD) and call MSDeploy after MSBuild creates a WebDeploy package with the appropriate setParam file. I don't believe there is way to use a custom SetParameters file when deploying directly from MSBuild.
Here is a post that further describes parameterization:
http://dotnetcatch.com/2014/09/08/parameterizationpreview-visual-studio-extension/
UPDATE:
Steven and I worked further outside of SO to understand his use cases better. We confirmed again the MSDeployPublish target does not support setting parameter value overrides. To solve his use case I wrote some MSBuild script to provide the functionality he was looking for and wrote a blog post about it -
http://dotnetcatch.com/2016/04/27/setparameters-via-msbuild-commandline/
It basically works by passing a SetParameters file or list of key/value pairs via MSBuild Properties on the MSBuild.exe commandline. The MSBuild script parses that out and overrides the parameters by setting the MsDeployDeclareParameters ItemGroup.
msdeploy.exe ... /p:MSDeployPublishSetParametersFile=SetParameters.Test.xml
msdeploy.exe ... /p:MSDeployPublishSetParameters=testSetting='changed_fromSetParam';IIS Web Application Name='Default Web Site/app13'
I can't get MS Build to output a transformed Web.Config file. I've setup the build project using NuGet package restore as described in the NuGet docs. Every part of the build works (package restore, CI, web deploy packages) except for the transform. I have tried the base setup and a custom project file as well as lot of other options and I haven't gotten anywhere.
I've done config transform setups before without issue. I have Slow Cheetah installed and can preview my current transform and see that it works. When I run the build locally via MSBuild.exe, the transform actually happens:
TransformWebConfigCore:
Transforming Source File: G:\MyProject\Web.config
Applying Transform File: G:\MyProject\Web.Debug.config
Output File: obj\Debug\TransformWebConfig\transformed\Web.config
Transformation succeeded
(If I look at the -v output I can see the individual transform run)
Then Web Deploy parameterizes my web.config:
Transformed Web.config using G:\MyProject\Web.Debug.config into obj\Debug\TransformWebConfig\transformed\Web.config.
PipelineTransformPhase:
Publish Pipeline Transform Phase
PreAutoParameterizationWebConfigConnectionStrings:
Creating directory "G:\MyProject\obj\Debug\CSAutoParameterize\transformed\Views\".
Copying obj\Debug\TransformWebConfig\transformed\Web.config to obj\Debug\CSAutoParameterize\original\Web.config.
AutoParameterizationWebConfigConnectionStringsCore:
Transforming Source File: G:\MyProject\Views\Web.config
Applying Transform File: <?xml version="1.0"?>
<configuration xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform">
<connectionStrings>
<add
connectionString="{% token='$(ReplacableToken_#(parameter)_#(tokennumber))' xpathlocator='name' parameter='$(name)-Web.config Connection String' description='$(name) Connection String used in web.config by the application to access the database.' defaultValue='$(connectionString)' tags='SqlConnectionString' %}"
xdt:Transform="SetTokenizedAttributes(connectionString)" xdt:SupressWarnings="True" />
</connectionStrings>
</configuration>
No element in the source document matches '/configuration/connectionStrings'
Not executing SetTokenizedAttributes (transform line 6, 15)
Output File: obj\Debug\CSAutoParameterize\transformed\Views\Web.config
Transformation succeeded
PostAutoParameterizationWebConfigConnectionStrings:
Auto ConnectionString Transformed obj\Debug\TransformWebConfig\transformed\Web.config into obj\Debug\CSAutoParameterize\transformed\Web.config.
The parameterized file is then moved into the package and the transformed file is deleted.
Copying obj\Debug\CSAutoParameterize\transformed\Web.config to obj\Debug\Package\PackageTmp\Web.config.
Deleting file "obj\Debug\CSAutoParameterize\transformed\Web.config".
So I have a transformed web.config file that doesn't end up in my build output. Why does the transform happen but not get copied to the output directory or the web deploy package?
I had the same issue here. This is caused by the Web Deploy Pattern. It uses the "project name".SetParameters.xml in the Web_Package to replace values on Deploy.
Since you want to use SlowCheetah you need to circumvent this.
You can accomplish this by replacing the connectionstrings setting in your web.config by:
<connectionStrings configSource="connectionStrings.config">
</connectionStrings>
Of course you will need the connectionStrings.config file. You van create this manually and put in the originasl connectionStrings section.
The node should be the only node in the file.
Now you can add SlowCheetah Transform on your connectionStrings.config file.
Our web.config needs a database password.
How can we specify this password while building the msdeploy (aka Web Deploy) package or when actually deploying?
We build the msdeploy package using msbuild (/p:DeployOnBuild=true) and web.config transformations for environment-specific details.
Web.config transformations are, by design, build time transformations. I tend to only use them for "everything but debug" changes.
What you want is an MSDeploy parameter. Assuming you are using a pubxml publish profile, the generated package will automatically have a parameter named "Name-Web.config Connection String" (where "Name" matches the name attribute in web.config) that will apply to the connection string.
If you deploy the package, you can change the connection string by supplying the value using -setParam:
Website.deploy.cmd /Y ... ^
-setParam:name="Name-Web.config Connection String",value="connection_string"
If you deploy using a publish profile, you can set the value in the pubxml file by updating the MSDeployParameterValue value (you should see the correct value near the bottom of the file):
<MSDeployParameterValue Include="$(DeployParameterPrefix)DBName-Web.config Connection String">
<ParameterValue>connection_string</ParameterValue>
</MSDeployParameterValue>
I'm currently using MSBuild to create an MSDeploy package by passing in arguments:
/p:DeployOnBuild=true;DeployTarget=Package
I'm using a parameters.xml file (placed at the root of my website). Another SO question I found tries to set up the application pool.
My parameters.xml file:
<parameters>
<parameter name="Application Pool Name" description="Application Pool for this site" tags="" defaultValue="ASP.NET v4.0">
<parameterEntry kind="DeploymentObjectAttribute"
scope="application"
match="/application/#applicationPool" />
</parameter>
...
</parameters>
but it seems that the archive.xml file inside the msdeploy package generated by the msbuild doesn't have an section with an applicationPool element
How can I get the archive.xml to be generated with this section so that I can set the application pool?
The app pool I want to set will exist already, so I'm not concerned with MSDeploy synching or creating app pools here.
Edit:
I have found this question How do I control the AppPool used for deploy through VS & MSDeploy settings which hints at using wpp.targets to generate a custom provider. I'm exploring how to use this approach to modify the archive.xml file
Assuming you have the correct IIS settings on your project and are running as Administrator, you should be able to specify IncludeIisSettings=true to have the settings included in the zip.
If you need the actual AppPool definition included (so it can be created), you should also set IncludeAppPool=true.
I've been using web.config transforms for a while now, for deployment on a few of our projects. What I'm now trying to achieve, is to have Web Deploy's 'Import Package' screen to prompt to check & update several of the variables in , adjusted for each environment.
I know I can use Parameters.xml to introduce these editable variables, but I haven't yet found how to have the defaults updated for different environment targets.
Consider the following neat, but non-overlapping example of wanting to have the user edit the 'specialServer' AppSetting, and have it present a different default when compiled for the NewEnv target:
Sample entry in Parameters.xml:
<parameter name="Special server" description="" tags="" defaultValue="server1-dev.domain">
<parameterEntry kind="XmlFile" scope="\\web.config$" match="/configuration/appSettings/add[#key='specialServer']/#value" />
</parameter>
Sample transform for Web.NewEnv.config, setting a different value for
<appSettings>
<add key="specialServer"
value="other-server.domain2"
xdt:Transform="SetAttributes" xdt:Locator="Match(key)"/>
</appSettings>
Sample of the prompt in Web Deploy:
Any suggestions as to how to update the default value for different build targets?
Thanks.
You would have to generate and new parameters definition file and embed it in your WebDeploy package for each environment.
This would give you different deploy packages per environment and would allow you to specify different default values for those parameters. Obviously doing so undermines the point if parameter transforms and you essentially end up baking in your config, but it's the only way to achieve what you want.
I don't recommend the approach but it may fit your needs.
We use a batch script to call msdeploy. It allows for a parm to specify the Parameters.xml file. Then with multiple Parameters.xml files (one per environment), you can just call msdeploy like:
"C:\Program Files\IIS\Microsoft Web Deploy V3\msdeploy.exe" -source:package='D:\mysite.zip' -dest:auto,computerName="testcomp1",includeAcls="False" -verb:sync -disableLink:AppPoolExtension -disableLink:ContentExtension -disableLink:CertificateExtension -setParamFile:"D:\mysite.test.SetParameters.xml"