Using TFS to Build and Deploy during the Build Process with MS Deploy

Often on projects nowadays, having an automated build and deployment process is a must. Depending on the maturity of the environment there are actually a lot of different ways to achieve these goals, but this post is about one of the simplest ways to get going using a minimum amount of brittle batch/command line tools. For the purpose of this article, I’m assuming you want to use MS Deploy to deploy a web application to in house environments.

Ingredients (what you need):

  • TFS and Team Build
  • Web Deploy Installed on Target Servers
  • Comfort with a little XML editing.

Step 1: Install Web Deploy on Server

Using MS Deploy is extremely convenient – you can package up a website and send it to a server and have it installed with dependencies with minimal effort. Before following this post, you’ll want to install Web Deploy on the target servers.

Step 2: Ensure you have the proper “Configurations” to deploy with

Using Solution/Project Configurations. Typically when you create a new project/solution, you get two configurations: Debug and Release. If you’re using Team Build to perform the deployment, it can be helpful to create a configuration per environment: Dev, Test, QA, Production, etc. To do this, right click on the solution and select “Configuration Manager…” Then select <New> in the Active Solution Configuration. It will prompt you for a name and if you want to copy settings from an existing configuration (such as Debug / Release). Pick one of those.

Step 3: Edit your project file manually

Then you need to modify your csproj (or vbproj) file. Normally you’d expect to use the UI to make project property changes, but in this case, these properties have not been given places in the Visual Studio UI yet. Notice how the project file starts out with <PropertyGroup>s – one that is global, and several (one for each configuration). Find the first one in the file and add these lines of XML in the middle.

These settings will be set for all configurations, even “Debug” which is usually the configuration you use for local development. But because the “DeployOnBuild” property is set to false, msbuild doesn’t do anything with these values.

Next it’s time to modify the configuration that you plan to use for deployment. Look in that file, and you’ll find a line like the following: <PropertyGroup Condition= ‘$(Configuration)|$(Platform)’ == ‘Dev|AnyCPU’ >
assuming “Dev” was the configuration you want to deploy with.

Now, we just need to add two lines inside of that PropertyGroup:

<DeployIisAppPath>MyApplicationDev</DeployIisAppPath>
<MsDeployServiceUrl>http://myserver.local</MsDeployServiceUrl>

 

DeploymentIisAppPath – this the “Web Site” name and virtual directoy path that exists within your IIS Server. Do not confuse this with physical file system path.

MsDeployServiceUrl – this is the name of the server – which is all you need in this case, MSDeploy automatically uses the default port of 1872 with SSL to connect and deploy this application.

Step 4: Modify your Team Build Definition

Edit the build definition, go to the “Process” tab. Find “3. Advanced” and you’ll find a place to specify “MSBuild Arguments” – just add the following on that line:

/P:CreatePackageOnPublish=true /P:DeployOnBuild=true

Conclusions

This approach is useful only when you need/can deploy and build on the same action. Some environments require build and deployment to be separate actions such that the compiled bits are identical between environments. This solution does not achieve that – you technically should have a build definition per environment in this case. It has the benefit of being very declarative, plays nice with web config transforms, and overall very easy to implement. Lab Management – a feature of VS/TFS is another way to achieve this – when virtualization can be used – and is relatively easy to set up in 2012.

Please note: I reserve the right to delete comments that are offensive or off-topic.

Leave a Reply

Your email address will not be published. Required fields are marked *

9 thoughts on “Using TFS to Build and Deploy during the Build Process with MS Deploy

  1. Thanks very much for this post. I’m new to these topics in the Windows universe. your post has been very helpful.

    How would you handle production and testing environment differences?

    Let’s say, for example, that testing and production each have their own DBs, and that the connection info is specified in the web.config file. I could set up two builds, one for testing and one for production, using the method outlined here. But wouldn’t they both end up with the same web.config file, and connect to the same db?

    The ability to handle this sort of thing appears to be baked into ms-deploy, but I’m not sure how you’d tie it into the automated build/deploy process.

    Again, thanks very much for your post.

  2. Alex S – you’d be right – but there’s one thing that goes along with this – that i didn’t cover in too much detail – and that was the “config transforms” – if you’re using VS 2010 or VS 2012 – you can right click on your web.config and select “Add Config Transforms” – and it will add an override config file for each of the environments you have.

  3. Trying to get this to work for a solution that contains multiple web projects that we need to deploy. No matter what I do, it seems to be ignoring the parameters I put in the specific configuration property group of the csproj files.

    I get this error for each project I’m trying to deploy:
    Web Deploy publish/package validating error: Missing or Invalid property value for $(MsDeployServiceUrl)

    So I tried defining the MsDeployServiceUrl in the MSBuild Arguments of the build definition instead of in the csproj files. This solved the above error, but then I get this error:
    The “ConcatFullServiceUrlWithSiteName” task was not given a value for the required parameter “SiteAppName”.

    So its not reading the DeployIisAppPath parameter from the csproj file either, and I can’t move that to the MSBuild Arguments line because its different for each project I’m trying to deploy.

    Its almost as if the deployment process is unaware of which configuration I’m building, so it can’t find the correct PropertyGroup in the csproj files to read the paramters from. However, I have specified the configuration in the “Configurations to Build” line of the build definition, and I’ve also tried adding /p:Configuration=MyConfig to the MSBuild Arguments line, and that doesn’t seem to solve the problem.

  4. Very useful site. I could follow the steps easily and automated deployment across multiple target environments. Really appreciate the author.

  5. This is a non-starter. This requires a csproj file and my VS 2015 web site doesn’t have one. It has a publlishproj file … perhaps you need to update this article.