Rules to Better Continuous Deployment with TFS

​​Since 1990, SSW has supported the developer community by publishing all our best practices and rules for everyone to see. 

If you still need help, visit Application Lifecycle Management and book in a consultant.

Hold on a second! How would you like to view this content?
Just the title! A brief blurb! Gimme everything!
​​​Rules to Better Continuous Deployment with TFS 2012, TFS 2013 and TFS 2015
  1. Do You Publish Simple Websites Directly to Windows Azure from Visual Studio Online?

    ​​TFS and Windows Azure work wonderfully together. It only takes a minute to configure continuous deployment from Visual Studio Online (visualstudio.com) to a Windows Azure Web Site or Cloud Service.

    This is by far the most simple method to achieve continuous deployment of your websites to Azure.

    But, if your application is more complicated, or you need to run UI tests as part of your deployment, you should be using Octopus Deploy instead according to the Do you use the best deployment tool​ rule.​

    Figure: Setting up deployment from source control is simple from within the Azure portal
    TFS_Deployment.png
    Figure: Deployment is available from a number of different source control repositories

    Suggestion to Microsoft: We hope this functionality comes to on-premise TFS and IIS configurations in the next version.

  2. Do you use the best deployment tool?

    Often, deployment is either done manually or as part of the build process. But deployment is a completely different step in your lifecycle. It's important that deployment is automated, but done separately from the build process.

    There are two main reasons you should separate your deployment from your build process:

    1. You're not dependent on your servers for your build to succeed. Similarly, if you need to change deployment locations, or add or remove servers, you don't have to edit your build definition and risk breaking your build.
    2. You want to make sure you're deploying the *same* (tested) build of your software to each environment. If your deployment step is part of your build step, you may be rebuilding each time you deploy to a new environment.
    The best tool for deployments is Octopus Deploy.
    SugarLearningOctopus.png
    Figure: Good Example - SSW uses Octopus Deploy to deploy Sugar Learning

    Octopus Deploy allows you to package your projects in Nuget packages, publish them to the Octopus server, and deploy the package to your configured environments. Advanced users can also perform other tasks as part of a deployment like running integration and smoke tests, or notifying third-party services of a successful deployment.

    Version 2.6 of Octopus Deploy introduced the ability to create a new release and trigger a deployment when a new package is pushed to the Octopus server. Combined with Octopack, this makes continuous integration very easy from Team Foundation Server.

    What if you need to sync files manually?

    Then you should use an FTP client, which allows you to update files you have changed. FTP Sync and Beyond Compare are recommended as they compare all the files on the web server to a directory on a local machine, including date updated, file size and report which file is newer and what files will be overridden by uploading or downloading. you should only make changes on the local machine, so we can always upload files from the local machine to the web server. 

    This process allows you to keep a local copy of your live website on your machine - a great backup as a side effect. 

    Whenever you make changes on the website, as soon as they are approved they will be uploaded. You should tick the box that says "sync sub-folders", but when you click sync be careful to check any files that may be marked for a reverse sync. You should reverse the direction on these files. For most general editing tasks, changes should be uploaded as soon as they are done. Don't leave it until the end of the day. You won't be able to remember what pages you've changed. And when you upload a file, you should sync EVERY file in that directory. It's highly likely that un-synced files have been changed by someone, and forgotten to be uploaded. And make sure that deleted folders in the local server are deleted in the  remote server. 

    ticksubfolders.jpg

    If you are working on some files that you do not want to sync then put a _DoNotSyncFilesInThisFolder_XX.txt file in the folder. (Replace XX with your initials.) So if you see files that are to be synced (and you don't see this file) then find out who did it and tell them to sync. The reason you have this TXT file is so that people don't keep telling the web

    NOTE: Immediately before deployment of an ASP.NET application with FTP Sync, you should ensure that the application compiles - otherwise it will not work correctly on the destination server (even though it still works on the development server).

  3. Do you use the Lifecycles feature in Octopus Deploy?

    Octopus Deploy 2.6 introduced a new Lifecycles feature that makes Continuous Integration from TFS much easier. It's a must have for projects in TFS that use Octopus for deployment.

    As well as allowing continuous integration, the Lifecycles feature adds some good governance around when a project can be deployed to each environment.

    Lifecycles can be found in the Library section of Octopus Deploy. By default, a project will use the Default Lifecycle which allows any deployment at any time.

    Octopus_Lifecycles.png
    Figure: Lifecycles can be found in the Library

    You should create a new Lifecycle for each project you've configured with Octopus Deploy. You should set up a phase to continuously deploy to your first environment (e.g. test or staging), but make sure the final phase of the lifecycle is a manual step to production.

    SugarLearning_Lifecycle.png
    Figure: Good Example - This lifecycle has two phases: an automatic release to a Staging server, and a manual release to the Production server.

    In the Process tab of your project definition, there's a panel on the right-hand side that lets you configure the Lifecycle to use. You should also enable Automatic Release Creation. If you have a CI build which publishes a new package to the Octopus NuGet feed as part of your build using OctoPack, and your first Lifecycle phase is automatic, this will result in continuous deployment to your CI environment.

    Lifecycle_CI.png
    Figure: Good Example - This combination results in Continuous Deployment to the Staging server when a new package is pushed
  4. Do you avoid publishing from Visual Studio?

    ​Publishing from Visual Studio is a convenient way to deploy a web application, but it relies on a single developer’s machine which can lead to problems. Deploying to production should be easily repeatable, and able to be performed from different machines.

    A better way to deploy is by using a defined Build in TFS.

    Figure: Bad Example – Using Publish to deploy
    Figure: Good Example – Queuing a new build to deploy your application
    Figure: Best example – Use continuous integration to trigger your Continuous Deployment build
  5. Do you Configure the ExecuteBatchTemplate Build Process Template?

    Configure the ExecuteBatchTemplate Build Process Template.

    Figure: Enter the DeployOnBuild MsBuild argument, and then enter the name of the deployment batch file you wish to execute upon successful build of the project.
    Every time this build is executed successful (and all the unit tests pass), the specified batch file will run – deploying the site automatically.
  6. Do you Create a “.Deployment” Project alongside your Web Application for any additional deployment steps?

    ​Your source control repository should be the source of all truth. Everything, always, no-matter what should go into source control.

    This includes any deployment scripts and Web Deploy parameter files if you need them.

    This includes your deployment scripts and Web Deploy parameter files.

    Figure: Good Example - Create a Deployment project alongside your web project.
    In the image aboce,​ Vm-SynWeb.Deploy.Bat is a batch file that will deploy your web site to Vm-SynWeb
    Vm-SynWeb.SetParameters.xml is a Web Deploy SetParameters file that specifies environment specific settings.
    _Deploy.Bat is the base batch file that your environment specific deployment batch files will call.
    Figure: It is important that each of the batch and parameters files has it ‘Copy to Output Directory’ setting set to ‘Copy Always’
  7. Do you create a Continuous Integration Build for the Solution?

    ​​(Before you configure continuous deployment) You need to ensure that the code that you have on the server compiles. A successful CI build without deployment lets you know the solution will compile.

    Figure: The Build definition name should include the project name. The reason for this is that builds for all solutions are placed in the same folder, and including the build name makes the Build Drop folder organised
    Figure: On the Trigger tab choose Continuous Integration. This ensures that each check-in results in a build
    Figure: On the Workspace tab you need to include all source control folders that are required for the build
    Figure: Enter the path to your Drop Folder (where you drop your builds)
    Figure: Choose the Default Build template and enter the DeployOnBuild argument to the MSBuild Arguments parameter of the build template
    Figure: Queue a build, to ensure our CI build is working correctly
    Figure: Before we setup continuous deployment it is important to get a successful basic CI build
  8. Do you Create a Deployment Batch file and SetParameters file for each Environment?

    You should create a Deployment Batch file and SetParameters file for each Environment.

    Figure: Good Example - The batch file specifies the target Server, the ProjectName name to deploy, and the configuration file to use. You can also optionally supply additional parameters. Download a sample _Deploy.bat file here as a .txt file.
    Figure: Good Example - The SetParameters file specifies MS Deploy parameterisation values. Most important is the target “IIS Web Application Name” on the target server
    See Vishal’s blog for more details.
  9. Do you Deploy to other Environments?

    Now that you have configured “Build Once, Deploy Many” you can open the folder for any build on the build server and deploy any build, to any environment.

    This means that if you deploy version 37, and then want to roll back to version 36 simply open the folder for 36 and re-run that batch file (assuming there has been no breaking DB schema changes).

    TODO: AdamS – Write a rule on non-breaking Schema changes

    Figure: To deploy to staging and production, open the appropriate drops folder and execute the correct batch file from the drops folder
  10. Do you know the easiest way to continuously deploy is to use VisualStudio.com and Azure?

    TODO: AdamS – Include Steps for Continuous Delivery with Azure and VisualStudio.com

    If you use Azure Web Sites and VisualStudio.com you can set up continuously deployment in 5 minutes.

    If you are using TFS 2012 on premise, or are not using Windows Azure web sites, follow the steps below to configure continuous deployment.

    As you can see, there are a lot of steps and you will need at least a day to get it all right.

  11. Do you know to Create the Website in IIS if using Web Deploy?

    ​In theory WebDeploy can create a site for you when you deploy. The issue with this is that many settings are assumed.

    Always create the site before deploying to it, so that you can specify the exactly the settings that you desire. E.g. the directory where you want the files for the site to be saved, the app pool to use and the version of .Net.


    Figure: Create the website in IIS

  12. Do you not install Web Deploy from the Web Platform Installer?

    ​​​You should not Install Web Deploy from the Web Platform Installer, but instead download the installation from the IIS web site (http://www.iis.net/downloads/microsoft/web-deploy).

    The reason for this is that the Web Platform Installer does not install all of the components required for continuous deployment, but the downloaded package does.

    More information on this issue here: Don't Install Web Deployment Tool using the Web Platform Installer

    Figure: Bad Example - Installing Web Deploy from the Web Platform Installer does not install all the components required for continuous deployment​
    Figure: Good Example - Install Web Deploy 3.0 by downloading the package from http://www.iis.net/downloads/microsoft/web-deploy
  13. Do you Update your Build to use the ExecuteBatchTemplate Build Process Template?

    ​Update your Build to use the ExecuteBatchTemplate Build Process Template. A sample ExecuteBatchTemplate can be found here.

    Figure: If the ExecuteBatchTemplate is available in the dropdownlist on the Process tab, select it and continue in the next section
    Figure: If the ExecuteBatchTemplate is not available in the dropdown list, click the New button
    Figure: Select the Browse button to browse source control for the correct build process template
    Figure: Navigate to the \BuildProcessTemplates\ folder and then select the ExecuteBatchUpdate template. Click "OK"
  14. Do you know the reasons why calling a Batch File from the Build Process Template is better than Deploying Directly from the Build?

    Ideally, Builds are created once, and can then be deployed to any environment, at any point in time (Build Once, Deploy Many).
    We do this by including deployment batch files in the solution, and specifying them to be called in the Build Process Template.

    Deployment scripts
    Figure: Good Example - Include deployment scripts in the solution, and execute them from the Build Process Template
    Bad Example - Using Builds to DeployGood Example - Using Batch File
    Deployment Overview
    1. A separate build is created per target environment
    2. The MS Deploy parameters are put into the MSBuild parameters setting on the process template
    3. The build for the shared development server is set to be a CI build so it is executed on every check-in
    1. One batch file per target environment is created and checked into source control alongside the web project
    2. Each batch file is accompanied by a corresponding Web Deploy Parameterisation XML file with environment specific settings
    3. The build process template is modified to call the batch file to continuously deploy to the shared development server
    Deployment Process
    1. The build is automatically deployed to the shared dev server
    2. Lots of testing occurs and we decide to deploy to staging
    3. We can just kick off the staging build
    4. A whole lot of testing occurs and we want to deploy to production
    5. We can kick off a production build, but this will deploy the latest source code to production
    6. If we want to deploy the version of the software that we have deployed to staging we have to get that specific version from source control, and then do a production build of it
    1. The build is automatically deployed to the shared dev server
    2. Lots of testing occurs and we decide to deploy to staging
    3. The batch file for any build can be executed and the build deployed to staging
    4. A whole lot of testing occurs on staging and then we decide to deploy the same build to production
      We just call the batch file in the folder to do the deployment. No new build is required
    Benefits
    • No need to create batch files or modify the process template
    1. Builds are created once, and can then be deployed many times to any environment, at any point in time (Build Once, Deploy Many)
    2. When deploying to production, we use exactly the same build package as was used to deploy to staging
    3. The custom build process template only does the deployment if the build succeeds and all the unit tests pass
    4. Anyone with access to the batch file can deploy… including the product owner!
    5. You only need one build per project
    Cons
    • Without modifying the build process template, the build will deploy even if the unit tests fail
    • To deploy a specific build to a particular server, it is necessary to get the code from source control, and then do a build
    • Only developers can deploy
    • You need a build per environment for each project
    • Build Once, Deploy Once. (You can’t redeploy a build to a different environment)
    • You must customize the build process template to execute the specified batch file from the build folder
    • We have to create custom batch files

    TODO: AdamS - Include the steps to customize the build process template.

    The Web Platform Installer is great, but does not install all the Web Deploy 3.0 components required for continuous deployment.