# Wednesday, 25 November 2015

We’ve been on the preview of “Release” for a while now and have been using it for several deployments. Its a great product when you have figured out how it works and as the documentation improves this should become easier.

Currently we are using Release to publish the same ASP.NET MVC web application to 3 websites with different parameters in each config (replaced with tokenisation) and to drop a packaged version of our web app for download from an external website.

Sounds pretty cool doesn’t it? Well it took a lot of getting around and I am keen to hear back from anyone who may have better ways of handling the configuration file part. Much of what we have done so far has been trial and error mainly between my colleague Richard Erwin and myself.

In this article I will cover deployment to an Azure website. In a later article I will cover how we deployed to an IIS web server hosted on an Azure virtual machine followed by wrapping up software for download from your website. Just as a warning we use a self hosted Release Agent to do our deployments and this example will probably only work with a self hosted Release Agent.

Update note:
For the purposes of this article, I forgot to add that we made use of the Custom VSO-Tasks for Zip, Unzip and Tokenisation which you will need to install before hand.

Creating a parameterised deployment of an ASP.NET MVC application with Release to an Azure website


In the image above you can see the steps involved in Release.

Setting up a vNext Build with parameters

The first step we need to do before we get to Release is to create a Build in VSO that

  • Uses a parameterised xml file with tokens to replace the parameters in your web.config (or other configurations files).
  • Create an MSDeploy zip file as its output

If you have done all of the above and just want to get to the Release bit, scroll down to Setting up Release.

Custom Parameterized XML file with Tokens
As you can see in the image below I have a parameters.xml file in the route of my MVC application if you have not used this type of file before you can find out more about it here. Its a pretty standard part of MSDeploy which is what you are using behind the scenes.


The only difference in our file is that we have replaced the default values with tokens. Tokens are represented with the following syntax __MYTOKEN__ . These tokens will be replaced later by a process in a our Release workflow.  We are basically telling this file to replace the parameters (represented by the match statements) in our web.config and visualisation.config files above by the defaultValue which in this case we have placed our token in for replacement later by Release.

Create an MS Deploy zip file as the output of our build.
In VSO create a new vNext Build using the Visual Studio template


On the “Visual Studio Build” Step select your solution (you will be prompted to locate this in TFS version control (or GIT) when clicking the button with the 3 dots next to the option.


In your MSBuild arguments you will need to do the following

/p:DeployOnBuild=true /p:WebPublishMethod=Package /p:PackageAsSingleFile=true /p:SkipInvalidConfigurations=true

The DeployOnBuild and WebPublishMethod arguments tell the build to create the MSDeploy packages for us. This is simply a zip file that MSDeploy can use to deploy to an IIS box or an Azure website.

Further down in Publish Build Artifacts we tell the build what we want as an output from this build. In our case all we want is the MSDeploy zip file. In this case we represent this by asking the publish step to find a zip file for us in the build output using the following syntax “**\*.zip” (see image below)


Setting up Release
For the purposes of this article I am doing an Azure Web deployment first but will follow up with another article that will go through IIS deployments.

You will need to install the  Custom VSO-Tasks for Zip, Unzip and Tokenisation before continuing.

A note about Release Agents
This article makes the assumption that you have at least some familiarity with Release. In this section we are using our own release agent installed on a virtual machine. A release agent is basically the same concept as how a build in VSO can have its own agent that you can host yourself instead of using the hosted build agent. If you do not have your own Release Agent setup there is a guide here on how to do so. You basically run a PowerShell script on a machine you wish to act as your release agent. If you are experimenting you can even use your own desktop or laptop as a release agent. Release Agents will need Internet access and be located where they can see the target environment you are deploying to.

Go into your VSO project and select the Release tab. Create a new Release in this case we are doing an Azure Website Deployment.


The default release you will see only has two tasks inside it. For the purposes of our setup we had no need for the Visual Studio Test which can be deleted.


In our release we added the following tasks (see the image below) which I will go into more detail below.

Its a good idea now to set your environment to use your hosted Release Agent if you haven’t done so already. You can do so by clicking on the 3 dots next to the environment name and selecting Agent Options and setting the Default queue to your Release Agent.


To select the contents of the vNext build you created previously select the Artifacts tab and select “Link an artifact source” button. Basically you are releasing the contents of a build.


Unzip Task
Select the Environments tab again and Add a task this task will be under utilities and be called UnZip. You can drag this task to the top of the list by holding down on it with your mouse.

In your Unzip Task you can select the zip file that is provided by your build output (this is the step we did previously in creating a build above). The output of our build is a zip file used by MS Deploy. We are just telling the Unzip task to unzip this. Note you will have to run at least one successful build to see the contents of your build using the navigation used by the 3 dots button next to the option.


The target folder is a folder on our build agent. The above path comes from clicking on the 3 dots next to the target folder. In this case I have only gone one folder deep and placed my own folder name in there called “VSO” which the zip task will create and unzip the contents of the package to.

Tokenisation: Transform file
Add a tokenisation task in the same way you added an Unzip task above.

Remember the previous step we did above “Custom Parameterized XML file with Tokens”? All we are doing is telling our Tokenisation task to find that parameters.xml file  we created in that task in the folder that was created in Unzip task above. This task will replace the tokens in our parameters.xml file with our custom variables (you can read more about where to set these further down).


Batch Script
This is probably the least elegant part of my solution and I am open to any suggestions people might have to improving it. In order to make the MS Deploy package work again we need to zip it up, unfortunately we can’t just use the Zip task that is available to us as MS Deploy will for some reason ignore any zip file that was not created with MS Deploy! To get around this we had to install MS Deploy on the build agent box (this is why I am using our own build agent).


This batch script task basically tells Release to execute the batch file located on my build agent server with three parameters. The script is listed below and lives in a path on the build agent indicated in the image above.

"C:\Program Files\IIS\Microsoft Web Deploy V3\msdeploy.exe"  -verb:sync -source:archiveDir=%1 -dest:package=%2 -declareParam:name="IIS Web Application Name",defaultValue=%3,tags="IisApp" ^
-declareParam:name="IIS Web Application Name",type="ProviderPath",scope="IisApp",match="^.*PackageTmp$" ^
-declareParam:name="IIS Web Application Name",type="ProviderPath",scope="setAcl",match="^.*PackageTmp$"

All the batch file does is takes the 3 arguments which are

  • The working folder we unzipped our website to and ran the tokenisation task on
  • Where we would like to place our new MSDeploy package and call it, in this case its VBX.zip which we are placing in the working directory of our agent. In the example above ours is: $(Agent.ReleaseDirectory)\VisualisationBoard2015\VSO.zip
  • The name of our IIS website.

It uses these to recreate the MSDeploy package for us again.

Note arguments are separated by a space and each argument is placed inside quotes.

Azure Web App Deployment Task
Finally we get to the last task. If all went well in the batch file task above, we should be able to tell this task to use the MS Deploy package we just created in the previous step. In this case it is



Note if you are unsure how to setup your Azure subscription and website on the Azure deployment task you can find out how to do so here . If the Azure web App does not exist Release will create it for you.

Where do I put my parameters for tokenization?
While still in your Release click on the Configuration tab. This is where you enter the tokens you wish to replace in your parameters.xml file for example the parameter __AUTHENTICATION__ is simply represented by the name AUTHENTICATION without the underscores. The tokenisation task will look for these here.


The tokenisation task will also check your environment specific variables which can be found on each configured environment.


The beauty of this is that you can have a different set of variables per environment.

Once you are done you can now kick off a Release and see if it works!

Trouble Shooting
We have found when trouble shooting release. It helps to have access to the Release Agent machine you are using so you can see what is happening in its working directory. Usually an issue could be down to mistyping a name or getting a directory path wrong.

I am keen to hear back from anyone who has a better way of using release for tokenized website deployments.

Tags: TFS

Wednesday, 25 November 2015 14:31:53 (GMT Standard Time, UTC+00:00)  #    Comments [4]

Tuesday, 26 January 2016 09:04:05 (GMT Standard Time, UTC+00:00)
I'm just starting to scratch the surface of VSTS and Release Management. I was hoping it would be way more straight forward that this.
Tuesday, 26 January 2016 09:27:33 (GMT Standard Time, UTC+00:00)
Hey Milo

Yes I agree for tokenisation its pretty cumbersome and there is a chance to make a lot of mistakes, however the Microsoft Release Team are working on improving this bit of the product as its still early days. The older none VSTS version of release used to manage tokenisation a lot more seamlessly.
Thursday, 23 February 2017 16:16:05 (GMT Standard Time, UTC+00:00)
I am new to TFS and using TFS 2015 Update 3 vnext to build app and Package binaries by passing inline MSBuild Argument:
/p:DeployOnBuild=true /p:WebPublishMethod=Package /p:PackageAsSingleFile=true /p:SkipInvalidConfigurations=true /p:PackageLocation=$(build.artifactstagingdirectory)
Also used "Publish Build Artifact" task and provided path to publish as "$(build.artifactstagingdirectory)"
Binaries are copied as zip but with this lengthy folder path on build server; \$BuildServer\e$\WebWork\1\a\Content\E_C\WebWork\1\s\Dev\ProviderGeoSearch\obj\Release\Package\PackageTmp$Allbinarieshere.
Want to reduce this lengthy subfolders.
Thursday, 23 February 2017 16:25:15 (GMT Standard Time, UTC+00:00)
Hi Sam,

If you are using Release Hub to finally deploy your build it doesn't matter too much on the length of the path. You may find one of my newer blog articles on the subject more up to date on how to do this.


It refers to VSTS but the component are very much the same as TFS 2015 Update 3. If you use the Copy Files Path you can also reduce what is brought across.

All comments require the approval of the site owner before being displayed.
Home page

Comment (Some html is allowed: a@href@title, strike) where the @ means "attribute." For example, you can use <a href="" title=""> or <blockquote cite="Scott">.  

Enter the code shown (prevents robots):

Live Comment Preview