Automating Deployment with Microsoft Web Deploy IIS

http://weblogs.asp.net/scottgu/automating-deployment-with-microsoft-web-deploy

This blog post continues a series of posts I’m doing that cover the new improvements we made around web deployment.  In my first post in the deployment series I provided an overview of the new VS 2010 Web Deploymentfeatures.

In today’s post I’m going to be discussing Microsoft Web Deploy – which is a free server technology that enables a comprehensive publishing and deployment mechanism.  Web Deploy enables you to not only publish files – but also provision database schema/data, run database change scripts, set security ACLs, and more.  All of these deployment steps can be automated using Visual Studio.

This post will provide a step by step tutorial on how to install Web Deploy and enable it on a web-server.  I’ll then demonstrate how you can use Visual Studio 2010 to directly publish to servers using Web Deploy, as well as how you can use Visual Studio to create installation packages that you can use to automate the deployment of your applications.

Web Deploy – And Why Should You Care

Deploying a web application or site involves several steps. You typically need to:

  • Copy files and folders
  • Provision database schema and optionally populate database content
  • Set appropriate read/write and security ACLs on files and folders
  • Install and configure SSL certificates
  • Deploy other misc dependencies (Event logs, GAC libraries, COM objects, etc)

Performing all of these steps manually is tiresome, slow, and dangerous (since manual deployment steps are error prone).  Enabling an automated process that allows you to quickly provision and deploy applications on a server helps reduce the chances of things going wrong, and can dramatically improve the cycle time it takes for you to get a change you make in an application into production.

Microsoft Web Deploy

Web Deploy is a free technology built by my team that can improve web deployment. It is a deployment service that runs on a server, and enables you to either locally or remotely deploy applications onto it.  Web Deploy includes built-in support for creating virtual directories and applications within IIS, copying files and folders, provisioning databases (both SQL Server and MySQL), setting file-system ACLs and more (it even includes built-in providers for things like setting registry entries, registering COM components, etc).  In addition to having these built-in deployment features, it also supports a .NET based provider API that enables you to create and plug-in your own custom deployment actions – which allow you to customize it however you want.

The wire-protocol for Web Deploy is HTTPS – which means Web Deploy can be used through firewalls (enabling easy, secure, deployment to remote hosted servers).  Web Deploy also supports both admin and non-admin deployment scenarios.  The non-admin scenarios enable administrators to configure Web Deploy on a server, and then delegate a subset of deployment capabilities to developers who do not have admin accounts on the production server.  This enables a very secure and flexible deployment approach.  I’ll cover the configuration steps to enable delegated deployment scenarios in my next blog post in this series.

Installing Web Deploy on Windows Server 2008

Visual Studio 2010 (and Visual Web Developer 2010 Express) will by default install Web Deploy on your development machine as part of their setup.  This provides you with what you need to create Web Deployment setup packages within VS, as well as publish them to remote servers that have the Web Deploy service installed and enabled.

Below are the steps for how to install Web Deploy on a production server running IIS 7.x on Windows Server 2008 or Windows Server 2008 R2:

1) Download and run the Microsoft Web Platform Installer on your production server.

2) Click the “Web Platform” tab within the Web Platform Installer, then click the “Customize” link under the “Web Server” section.  Select the “Web Deployment Tool 1.1” feature as well as the “Management Service” feature:

image

3) Press the Install Button.  This will download and install the Web Deployment Package, and enable the IIS Management Service feature that is built-into Windows.

Enabling Deployments with Windows Server 2008

We now have Web Deploy installed – next we need to enable deployments with it.

Web Deploy supports deployments by administrators, as well as deployments by non-administrators (aka delegateddeployments). In this blog post, I’m going to cover how to enable deployments using an account that has administrator permissions on the server.  I will cover how to enable delegated deployments by developers that do not have an administrator account in my next blog post in this series.

1) The first step to enable Web Deploy is to start the IIS Admin Tool (Start -> Run -> inetmgr.exe).  Then double-click the “Management Service Delegation” icon on the home-screen:

image

When you double-click the “Management Service Delegation” icon it will bring you to a page that looks like below.  In the Actions pane, click the “Edit Feature Settings…” link.  This will bring up the “Edit Feature Settings” dialog – check the “Allow administrators to bypass rules” option within this dialog box.  This will allow those with Administrator accounts on the server to bypass the delegation capabilities of the Web Management Service and perform actions using their administrator capabilities:

image

Then return back to the IIS Admin Tool home-screen and double click the “Management Service” icon:

image

When you double-click the “Management Service” icon it will bring you to a page that looks like below.  Click the “Enable Remote Connections” checkbox to enable remote deployments.  You can optionally choose which IP address and port the management service runs on – as well as what client IP addresses are allowed to connect with it.  You can tweak these settings to lock down who can access the deployment service.

When you are done click the “Start” link within the “Actions” tab to start the Web Management Service on the server:

image

The server is now setup for deployments using an administrator account with Web Deploy.

Important Tip: One thing to watch for is whether you have a firewall enabled on your server, or within the cluster where your server is hosted.  By default the Management Service runs using the HTTPS protocol on port 8172.  This port might be locked down by default depending on your hosting configuration.  If so you should either unlock it with your firewall/hoster – or pick a different port number that is allowed.  You can test to see whether the management service is available simply by opening up a browser and accessing it using a URL like:https://yourservername:8172/MsDeploy.axd – if you are prompted for a username/password then you know it is working, and there is no firewall blocking access to it.  If it times out then it is likely that a firewall is blocking it.

Enabling Web Deploy on a non-Windows Server 2008 Operating System

The steps above demonstrate how to enable the Web Deploy service on a Windows Server 2008 or Windows Server 2008 R2 operating system.  The IIS 7 Management Service is built-into these operating systems, and Web Deploy takes advantage of it.

If you try and follow the above steps on Windows 7, Windows Vista, or Windows Server 2003, though, you’ll notice that the IIS Management Service (and its icon within the IIS admin tool) isn’t available.  Instead you need to follow a slightly different set of steps to enable the Web Deploy service.

Enabling Web Deploy on Windows 7, Windows Vista, and Windows Server 2003

You can enable the Web Deploy publishing service on Windows 7, Windows Vista, and Windows Server 2003 using the below steps:

1) Open an elevated command prompt (meaning you right-click and launch it using the “run as administrator” command)

2) Type “net start msdepsvc” to start the “Web Deploy Agent Service”:

image

3) To confirm that the publishing service is working, change directory to the “c:\Program Files\IIS\Microsoft Web Deploy”, and then type the command “msdeploy –verb:dump –source:appHostConfig,computername=localhost”:

image

This should cause the local msdeploy client to connect to the publishing service you just enabled and dump out the current status of your web-servers ApplicationHost.Config file:

image

If a bunch of spew comes out then you know that everything is working and you have just enabled Web Deploy for publishing.  Using this approach won’t allow you to enable “delegated access” (which allows non-admin accounts to deploy – and which I’ll cover in more depth in my next blog post) – but will allow those with an account with admin permissions to deploy to the machine.

Using the “Publish Web” Dialog within Visual Studio

Now that we have our web server enabled with Web Deploy, let’s try deploying something to it within the Visual Studio IDE.

VS 2010 includes a new “Publish Web” feature that you can use to quickly deploy a web application to a remote server.  You can activate it by right-clicking on any ASP.NET Web Application Project (both Web Forms and MVC varieties), and then select the “Publish” context menu item:

image

Selecting this will bring up a “Publish Web” dialog which allows you to configure publish settings.  You can use this dialog to publish an ASP.NET application to a remote user using FTP/FTPS, Web Deploy, or FrontPage Server Extensions.

We’ll select the “Web Deploy” option from the drop-down, and then enter the publishing information of our Web Deploy server:

image

Note that you only have to fill these settings out once – you can then save them as a “Publish Profile” using the “Save/Rename/Delete” buttons at the top.  Publish profiles allow you to save multiple deployment/publishing options and quickly flip between them depending on what server you want to use.

A few notes about the various options you can specify:

Service URL: This is the URL of the Web Deploy Management Service.  If you are using Windows Server 2008 the default format of the URL is https://mysite:8172/MsDeploy.axd Note the protocol is “https://” and the port should match whatever you specified when you enabled the IIS Management Service above.  

If you are publishing against a Windows Server 2003, Windows 7, or Windows Vista machine then the default format of the URL is http://server-name/ (not https – since the security credentials are sent using built-in Windows authentication which is encrypted). You also don’t need to specify a port number with Windows Server 2003, Windows 7 or Windows Vista.

Site/Application: This allows you to specify the site name (and optional application name) on the remote server that you want to install the application to.  You can publish your project as a site, in which case you might specify something like www.mysite.com as the sitename, or “Default Web Site” if you just want to publish at whatever the default root site name is.  

Important: The site name you specify needs to correspond to the same site-name that shows up in the IIS admin tool.  So if you’ve registered the www.scottgu.com site using the friendly name “ScottGu’s Site” or just “scottgu.com” when you created it in IIS you need to make sure the site name you specify as a publish setting corresponds to the friendly name (so you’d specify “ScottGu’s site” instead of www.scottgu.com if that is what shows up in the IIS admin tool as the site name).  If you specify this incorrectly you’ll get an error that says the the remote agent “could not be contacted”. 

Alternatively you can publish to a sub-application location using a value like “www.mysite.com/myapplication” or “ScottGu Site/myapplication”.  If the /myapplication vdir and application doesn’t already exist, then the Web Deploy service will create it for you and then publish your project to it.  

You can optionally indicate that you want this sub-path to be a virtual directory (the default) or an application by checking the “Mark as IIS Application on Destination” checkbox.

Credentials: If you are publishing to a remote server that is not part of your windows domain, then you can specify your username/password in the publish dialog.  This username/password combination can either map to a Windows account on the remote server – or alternatively map to IIS usernames (which enable more flexible locked-down delegation options – which I’ll cover in my next blog post). 

Important: Unless you’ve installed a signed SSL certificate on your remote server, make sure you check the “Allow untrusted certificate” checkbox.  By default Web Deploy will install a cert for you to use that is unique (and unsigned) – and if you don’t check this checkbox your login will fail because VS won’t trust an unsigned cert.

Other Notes: There is a checkbox provided that allows you to indicate whether you want to “Leave extra files on destination” or not.  If you uncheck this then the existing files in the site/application you are publishing to will be deleted if they don’t match what is currently in your VS project.

Once you have filled out the Publish settings, you can click the “Publish” button and it will connect to the remote Web Deploy service and deploy your application to the location you provided.  Your “Output” windows within Visual Studio will show output like below that explains how it was deployed and the actions that occurred with the publish step:

image

The above project is a basic web project with just a few files and directories within it.  Web Deploy will handle copying all of the file and setting appropriate ACLs on the remote server (for example: making the \app_data directory to be read/write).  In later blog posts in this series I’ll discuss how to enable database deployment as part of the Web Deploy process – as well as how to automatically switch web.config file settings (e.g. connection-strings) as part of it.

And with that we’ve published our site on a remote server.  To re-publish it again you can right-click on the project and once-again select the “Publish” command – which will bring up the publish dialog again (with the same settings as last time populated in it by default). Alternatively, you can enable the “Web One Click Publish” toolbar within VS 2010 – which enables you to quickly switch between saved publishing profiles (using a drop-down) and then click the “”Publish” button to the right of it to public the project to the target server (no dialog required):

image

Note that Web Deploy is smart enough to compare the remote server with your local project – and only copy the files it needs to.  So if you make a quick few changes to a large project, and then re-publish again – only those files that changed will be copied over.  The files that weren’t updated won’t need to be copied again.  This makes re-deploying/updating a site much faster – especially when there is a lot of static content and large images in the project.

Web Deploy also by default compresses files before it copies them to the Web Deploy service – which shrinks the wire-size and enables faster deployments.

Creating Deployment Packages from VS 2010

VS 2010 also supports a packaging option that enables you to package up your ASP.NET Web Application (together with its dependencies like web.config, databases, ACLs, etc) into a .zip based deployment package file that Web Deploy understands.  You can then hand-off the deployment package file to someone who can deploy it either via the IIS Admin Tool, or via a command-line/powershell script that installs it on a remote server using Web Deploy.

The deployment package you create can optionally expose application configuration settings that can be overridden (like directory locations, database connection-strings, etc).  When using the IIS7 Admin Tool, the install wizard will prompt the administrator for each setting to be customized – enabling you to provide a clean customization experience without having to write any custom code to-do so.  The settings can also be passed as arguments on the command-line when using a command-line or Powershell script to deploy the application via a remote Web Deploy service.

To create a web package within Visual Studio 2010, just right click on your ASP.NET Web Project in the solution explorer and select the “Build Deployment Package” menu item:

image

Selecting this option will cause VS 2010 to build a Web Deploy compatible deployment package.  You can configure where this package is created on disk within the project’s “Properties” dialog (select the Package/Publish Web tab).  Note that the disk location of the generated Web Deploy package is always displayed in the “Output” window build content (which makes it easier to find):

image

The generated package file is literally a .zip file that contains a Web Deploy manifest that enables you to easily deploy it on a remote server using either the IIS Admin Tool or a command-line.

Installing a Package Using the IIS Admin Tool

Once you have created the .zip deployment package file, you can use the IIS Admin Tool to install it.  Within the IIS Admin tool simply click the “Import Server or Site Package…” link on the “Actions” panel of the admin tool (these links are present if Web Deploy is installed):

image

This will launch a dialog that allows you to select the .zip package file.  When you do this the IIS Admin Tool will show the administrator the exact deployment steps that have been automated by the package:

image

If you continue through the wizard it will automate provisioning the application for you onto your server.

Deploying a Package from the Command-Line

Alternatively, you can use a command-shell to deploy the package onto a remote server.

To do this, open a command window, and navigate to the location of the deployment package .zip file on disk.  In addition to the .zip package file, you’ll find that VS also added a few additional files to the directory:

image

The ProjectName.deploy.cmd file provides a pre-built script that you can use to deploy the package onto a remote server.

The ProjectName.SetParameters.xml file contains some deployment parameters that you can set (like site-name, connection-string locations, etc).  You can use Visual Studio’s project properties pane to set the default values for the parameters that are generated into this file.  Admins can then optionally edit/change them later if they want (avoiding the need to explicitly specify them as command-line parameters). Make sure to open/view this file to see what the current defaults in it are.  In particular, check to make sure that the site name/application name is where you want the application deployed.

To install the package on a remote Web Deploy server, run the deployment script with the following parameters:

ProjectName.deploy.cmd /y /M:https://WebDeployUrl:8172/MsDeploy.axd /u:username /p:password –allowUntrusted /A:basic

A couple of quick notes on the various parameters above:

/y Indicates that Web Deploy should deploy the application onto the remote server.  

Alternatively instead of /y you can specify /t to perform a trial install that will simulate deployment and help you verify everything is ready (without actually provisioning it).

/M: parameter Specifies the Web Deploy publishing endpoint of the server you want to deploy the package onto.  It should match whatever publishing service URL you setup (and will be the same as the “Service URL” parameter in the Publish Web dialog). It should be an “https” based URL if you are publishing to a Windows Server 2008 or 2008 R2 server.
-allowUntrusted Required if the SSL certificate on the remote Web Deploy server is unsigned (which it isn’t by default)
/A:basic Required if the remote server is not using Windows Authentication to identify the user (it instead specifies that you will use http basic auth over SSL)

When you run the command it will deploy the package to the remote server, perform all of the deployment steps (including things like provisioning databases, setting file ACLs, etc), and output the status back to the command-prompt as it makes progress.

Automating Deployment from a Build Server or Continuous Integration Server

In addition to having a developer/administrator kick off deployment explicitly, you can alternatively automate it to happen as part of a continuous integration process or as part of a build server.  The commands necessary to automate creating a Web Deploy .zip package are available as MSBuild tasks.  You can use them to either create a deployment package as part of the build process – or optionally have an automated build also deploy the app as well.

I’ll be covering how to enable these automated build scenarios in a future blog post.

Deploying Across a Web Farm

Web Deploy can be used together with the Microsoft Web Farm Framework to enable automated deployment across a web-farm.  You can install and configure Web Deploy on a primary server in a Web Farm Framework cluster – and the secondary servers within the web farm cluster will then monitor and clone any applications you deploy with it.  This allows you to use the exact same steps as above to deploy sites and applications across any number of machines within a web farm in an automated way.

Read my previous blog post about the Microsoft Web Farm Framework to learn more about how to enable this.

Summary

Web Deploy provides a powerful and flexible way to automate the deployment of ASP.NET Web Applications to a remote server.  Web Deploy enables you to not only publish files – but also provision database schema/data, run database change scripts, set security ACLs, and more.

You can use Visual Studio 2010 to directly publish to web servers that have Web Deploy enabled, or create deployment package files that can be installed either via an admin tool or the command-line.  You can also integrate packaging and deployment as part of a build server or continuous integration process to better enable a continuous delivery model.

I’ll cover more about how to enable Web Deploy with delegated security scenarios in my next blog post.  I’ll then do blog posts that cover how to modify/customize web.config files as part of deployment, how to deploy databases as part of a Web Deploy process, and how to integrate all of this as part of an automated build process.

Hope this helps,

Scott

P.S. In addition to blogging, I am also now using Twitter for quick updates and to share links. Follow me at:twitter.com/scottgu