Skip to main content

Quickly and Easily Deploy Websites/Web Services with TFS Build via Web Deploy (MSDeploy)

 

When I first started deploying code from TFS I took the simple approach and created a batch file and deployed the websites via RoboCopy. I’m a very “Keep it simple” kind of guy, so this worked for us for a long time and so nothing was changed.

With my most recent project however, we were deploying code over a slow VPN tunnel from our servers in Chicago to servers located in Europe. Due to this, the RoboCopy was taking over 4.5 hours to complete. I needed a better/faster way so I started looking into Web Deploy (MSDeploy). I was able to get it working fairly easily and I was pleasantly surprised how easy it was to get it working, and how much time its saved me! I can now deploy the code in less than 20 minutes!

I’ve outlined the process in detail below, but in general you only need to do this:

  • Add MSBuild parameters to your automated build
  • Customize the deployment parameters for the website
  • Create a batch file to an auto-generated MSDeploy script
  • Execute the batch file from the automated build

 

Note: In order to use MSDeploy, you need to install MSDeploy on the destination server. Details can be found on the Web Deploy/MSDeploy website here:

http://www.iis.net/learn/install/installing-publishing-technologies/installing-and-configuring-web-deploy

Step 1: Create an automated Build in TFS

This is obvious, but worth mentioning. If you don’t have an automated build, you can’t do automated deployment. here is an MSDN Article that walks you through it: http://msdn.microsoft.com/en-us/library/ms181716.aspx

Kick off your build and verify that it builds and deploys the websites properly. You can do this by making sure the build completes properly and that the code is moved out to the code drop location. The code should be in the following location:

<Code Drop Location from Build Defaults Tab>\<Build Name>\<BuildName>_<timestamp>\PublishedWebsites

Example:

image

Step 2: Customize the build for MSDeploy

After the build is created, there are a few MSDeploy specific changes you need to do.

1. For the Default Template, create a new template by clicking on “New…”, selecting the Default template, naming it and clicking “OK”. This is the template we’ll be editing later on.

image

2. On the “Process” tab, you need to enter the following for the MSBuild Arguments:

/p:DeployOnBuild=True /p:Configuration=Release

image

Step 3: Kick off the build and verify MSBuild Arguments:

Now that the MSDeploy stuff has been added, you want to kick off another build. When it completes you should now start seeing some “_Package” folders in the Code Drop Location:

image

If you don’t see these, then go back to steps 1 and 2 and make sure you’ve got everything set up properly.

Take a look at the contents. You can see that TFS/MSBuild take care of a lot of the heavy lifting.

image

  • Deploy.cmd: This is a batch file that can be executed to publish code to a server that has Web Deploy installed on it. You can open it and take a look to get an idea of what its doing. Its some pretty cool stuff
  • SetParameters.xml: This is an xml file that allows you to set some specific parameters for the deployment  like IISWebsite name, etc. We’ll be using this file later to tell MSDeploy where to put the code.
  • Sourcemanifest.xml: Config file used by MSDeploy to Locate where the code files are
  • zip file: Compressed version of the published website. This is what is deployed to the server during deployments

 

Step 4: Save off “SetParameters.xml” files

I like using batch files for deployments and I like to save them on the build server so they are easily executed during deployments. When I do this, I add folders into the Code drop location for each build definition and create a new folder called “Batches”. We’ll need to save off the SetParameters.xml files as well, so lets create another folder in the Batches folder called SetParameters. Grab the SetParameters.xml file from step 3 and copy it into this folder.

image

Now we need to customize this XML file for our deployment.

Open the SetParameters.xml file in a text editor. You’ll see a “setParameter” XML node where the IIS Web Application name is being set. Update this to match the Website/Web app in IIS on the server where this will be deployed:

In my example, the WebService is actually deployed on the server to the Default Web Site –> NewsService location

IIS on the server:

image

WebService.Setparameters.xml:

image

Step 5: Create a batch file to execute the Deployment

Now that we have the Package folder being created and we’ve customized our XML file, we need to set up a batch file to execute MSDeploy and have it published to the server. The auto generated deploy.cmd file comes in extremely handy.

Again, we’ll leverage the “Batches” folder on the build server.

Create a new batch file called “RunDeployment.cmd” in the Batches folder and add the following lines into it:

image

  1. Here we set up variables used to execute the MSDeploy. I use variables so that we can easily change things like server names, etc. without changing the actual MSDeploy calls
    • _xcopyFlag: normal xCopy flags used to silently overwrite files via batch files
    • _location: this trims extra quotes from the location parameter passed in. (We’ll pass in this from the Deployment workflow later on)
    • _logfile: Sets up a log file. Very useful for troubleshooting/verification of deployments
    • _Server: name of the server were this will be deployed
    • svcname: name of the website/web service that is being deployed
  2. This moves the customized SetParameters.xml file back into the _Package folder to overwrite the auto generated one.
  3. This calls the deploy cmd file to execute the deployment.
    1. In my example, I’ve got a few extra flags for usename/password for security.
    2. There are other flags that can be used such as “-skip:objectName” that will ignore folders, but in this case we’ll keep it simple.

Step 7: Modify the Build workflow:

Now we need to make a few simple additions to the build workflow to call the batch file.

Open the Build template XAML file that was created in step 2. Typically these are stored in Source Control at $Project\BuildProcessTemplates:

When the workflow opens, add a new Sequence workflow after “Check in gated Changes..” step named “Deploy to Servers”

image

Open the Sequence object and drag an “InvokeProcess” task onto the surface:

image

Right click and select properties and enter the following information:

image

  • Arguments:The arguments we want to pass into the batch file
    • Example: """" + BuildDetail.DropLocation + "\_PublishedWebsites\" + """"
  • FileName:The location of the batch file created in step 5
    • Example: <Code Drop Location>\<BuildDefinition>\Batches\RunDeployment.bat”

 

Step 8: Run the build

Run the build and check your server. If the bits have been updated, you’ve been successful. If not, check the log file created by the batch file(filecopy.txt) and troubleshoot.

Important: Before you run the build, please make sure to backup the deployed folder on the server if you are concerned about losing anything. MSDeploy cleans up files on the server that aren’t part of the deployment, so if you have images or other files that are not part of the build, they will be deleted from the server. Also, run this on non-production environments first and hone this process down before you use it in production. If you build the batch files with parameters and variables, using MSDeploy in Staging/production environments will be easy.

 

Summary:

While the information above may seem complex, most of the work is done by the auto generated files. Basically you only need to update your build with the MSBuild parameters, create a batch file and execute the batch file from the build.

there is a lot of power in MSDeploy that is not being used at this point, but I’ll post something else if I come across anything else useful

Enjoy!

Comments

  1. Shouldnt there be an easy way to preserve the etParameters.xml by now? I find it odd that I need to manually swap that out every time i run a build.

    ReplyDelete
  2. I believe so, at least for some of them. I think you can pass some of the values in as parameters to the MSDeploy Script.

    ReplyDelete

Post a Comment

Popular posts from this blog

Executing .ps1 files in a DockerFile

This week I was trying to containerize an existing java application. Part of "installing" the application  on the container required executing an PowerShell script in the container during the Image build. Based on the documentation here  I thought i could add the following command to my dockerfile and it would work: RUN install.ps1 However, when I went to build the image, it just hung on that step. I tried several other variations of the run command including: RUN ["Powershell", ".\install.ps1"] which resulted in the following error: '["Powershell"' is not recognized as an internal or external command,operable program or batch file. RUN ["Powershell.exe", ".\install.ps1"] which returned the same error as above. I was about to give up and move the PowerShell commands from the .ps1 file directly into the dockerfile itself as described here , but I had an "A HA!" moment and decided to give a simpler a

Get NodeAuthorization working in Kubernetes with acs-engine

Node Authorization in k8s I'm starting to get into the container world and I'm loving it. Recently we helped a client build out and deploy a micro-services application in Kubernetes. We created the cluster in Azure using the open source project  acs-engine . After we got the cluster set up, our client asked for some updates to the cluster for security reasons. One of those updates was to enable Node Authorization . What is Node Authorization? Node Authorization locks down each Node in the cluster to only be able to do actions on itself. If this is not turned on, its possible for a malicious pod to take actions on any other node, including reading secrets, deleting pods, etc. There is an excellent post by Antoine Cotten that explains this very well ( as well as RBAC, which is a different subject altogether). How do I set it up? Based on the current documentation, it looks like setting up Node Authorization should be easy. Basically follow these steps Turn on TLS

Build/Deploy Windows service with TFS

Building and deploying a web service or website via TFS is pretty straight forward, but automatically deploying a windows service or console application takes a b it of setup. I’ve outlined the steps below to get your service deployed. Step 1: Set up Automated Build and MSDeploy on the Target server. If you are doing any sort of automated build/deploy I recommend using MSDeploy. You can follow steps 1-3 from a previous post here . Step 2: Edit the .csproj file The project file for the app you are trying to deploy needs to be edited so that TFS will create a directory for the output of the project. Otherwise the project will be built, but the assemblies will be placed in the code drop location with no organization to it. To edit the file, go to the open file dialog and locate the csproj file. Select it but don’t click “Open. Instead click on the dropdown arrow next to the Open button, select “Open with”, and choose the XML (Text) editor as shown: Once the file is open, add the fo