Adfa

Deploying web applications with TFS and MSBuild

Published: 6/12/2013 10:43:33 PM

I'm administering a local TFS that hosts several web application projects. The projects are being built on each check-in, and the goal has always been to deploy the applications to various environments at the same time. Up until now I have achieved that by simply redirecting the build output in the build targets, but I have always felt like that was a dirty solution so the other day I finally decided to attempt to solve it in a better way.

I discussed the issue with a co-worker and was told to look into a deployment tool from Microsoft named "Web Deploy". Web Deploy is a free tool that can be downloaded here. Once installed properly you can use it in combination with msbuild by passing command line arguments. This makes it possible to utilize this tool from a TFS build since you can specify additional msbuild parameters in the build definition. Sounds good, right?

Now, the tricky part for me was to get the parameters right. Even though the goal is to integrate this into TFS builds I would strongly suggest that you try the parameters from a command prompt first. Once the parameters are tested and verified they can be copied to the build definition and everything should be fine. Please be aware that the parameters discussed in this post are only a subset of all available parameters, I will only touch the parameters that were required to get my builds deploying.

Local deploy

The first scenario I faced with the local deploys, where the application should be deployed to the local IIS running on the build server. After some experimenting in a command prompt ended up with the following command for my debug builds (line breaks have been added to improve readability):

c:\windows\Microsoft.NET\Framework\v4.0.30319\msbuild.exe LocalWebApp.sln 
/p:Configuration=Debug 
/p:Platform="Any CPU" 
/p:DeployOnBuild=True 
/p:CreatePackageOnPublish=True 
/p:MSDeployPublishMethod=InProc 
/p:DeployTarget=MSDeployPublish 
/p:MsDeployServiceUrl=localhost
/p:DeployIisAppPath="Default Web Site/MyLocalWebApp"

The key parameters are the /p:DeployOnBuild=True and the /p:MSDeployPublishMethod=InProc. This will instruct msbuild to deploy the site when it is built, and to do it "in process" or locally. The /p:DeployIisAppPath parameter determines the name of the application in IIS.

Remote deploy

The other scenario I needed to address was the remote deploys, where the application would be deployed to a remote IIS running somewhere else. Using the local deploy command as a template I soon ended up with the following command (line breaks have been added to improve readability):

c:\windows\Microsoft.NET\Framework\v4.0.30319\msbuild RemoteWebApp.sln 
/p:Configuration=Release 
/p:Platform="Any CPU" 
/p:DeployOnBuild=True 
/p:CreatePackageOnPublish=True 
/p:MSDeployPublishMethod=RemoteAgent 
/p:DeployTarget=MSDeployPublish 
/p:MsDeployServiceUrl=testserver 
/p:DeployIisAppPath="Default Web Site/MyRemoteWebApp" 
/p:username=

As you can see that the commands for local and remote deploys are quite similar, but there are some important differences (marked with red text). The most important difference is the /p:MSDeployPublishMethod parameter. For remote deploys this should be set to RemoteAgent. Another obvious difference is the /p:MsDeployServiceUrl which basically is the server to which the application should be deployed.

A not-so-obvious difference is the addition of the /p:username parameter. Normally you would add /p:username and /p:password and specify a username and password of a user to authenticate to the server, but I wanted a "Windows authentication" kind of authentication without having to provide a password. It turned out that if I simply added "/p:username=" without providing a username it just worked.

Please note that the Web Deploy tool should be installed on the remote server as well, and make sure to include "Web Deployment Remote Agent" during the installation.

Things worth mentioning

I thought I should mention some of the issues I faced during the configuration. The first thing I noticed was that the deploy didn't seem to work at all. No matter how I tweaked the parameters I just couldn't get a deploy. Msbuild didn't even create a package during the build. I found this odd because when I tried the same command line on a completely new web project it worked, but as soon as I used the existing web projects nothing happened. In the end it turned out that my dirty deploy solution was interfering with the web deploy. Remember that I had manipulated the build targets and redirected the build output? Once I restored the target files and removed my custom redirection the deploy started to work.

Another thing I noticed was that the applications are installed in IIS under the default application pool (the one "Default Web Site" uses), and I have not found a way to change this by using msbuild parameters. This might be an issue if you want two deploys to be deployed under different application pools, so it could be good to keep this in mind.

Got comments? Post them here!

Name:

Name is optional but recommended.

E-mail:

E-mail is optional and will not be shown in the comment. It will only be used if the comment requires me to contact you directly.

Comment:
Enter text:


Popular tags
Security (5)
IIS (4)
Troubleshooting (3)
MVC (2)
TFS 2012 (2)