Deploying Asp.Net MVC 2 Application to Remote WebServer using MSDeploy
Wednesday, February 3, 2010
Locally developed Asp.Net MVC 2 application which needs to be deployed to a remote web server. The web server, running IIS 7.5 is hosted by a 3rd party, but we have full administrative access (Virtual Machine). In order to meet our deployment needs, we will install and configure MSDeploy. MSDeploy is a new add-on for IIS 6 and above which enables the package and installation of web applications, and optionally remote deployment and administration. You can also use it to synchronize settings between web servers, for example in a Web Farm. It is the remote deployment that we are most interested in, which is built upon the packaging and installation piece. For this post I will be assuming a deployment source of Visual Studio 2010 Beta 2. MSDeploy ships with an API which can be used to do the deployment from say a build task on a Build Server (stay tuned for a follow-up post on that).
First you need to download MSDeploy to your remote web server and install it. Here is the direct link for the 64 bit version of MSDeploy. Other version can be downloaded from the MSDeploy website. Once downloaded, run the MSI installer and select the custom option. You need to select the IIS 6 Deployment Hanlder to get the remote deployment feature. I also select the UI Module and Management Service Delegation UI (See screen shot below). After selecting the desire components, hit next, then install.
If you had IIS Manager open during the installation, you will need to restart it. Once restarted, you can right click on the Default Web Site and you should see a deploy option listed.
Next we will be configuring some accounts and permissions for our remote deployment, following the instructions provided by Microsoft, which can be viewed in their entirety here. Following these rules we will be able to create a specific account for our application which limits our external exposure. I’m happy to see we can use the new IIS Users/Management feature instead of having to create a local or domain windows account. Here is an overview of the steps we will be doing:
- Create an IIS Manager user account for the customer.
- Give the WMSvc account access to the customer’s directory.
- Configure delegation for the customer.
- Add delegation rules for the customer.
- Restart the Web Management Service.
- Test the Web Deployment Handler.
Step 1 – Create an IIS Manager User
In IIS manager, select the root server level (this is usually named after the name of the computer IIS is running on, it’s the node just below Start Page). Once selected scroll down in the middle pane to the Management section and select IIS Manager Users.
- Double click on IIS Manger Users
- Click Add User from the actions list on the far right side
- Enter a username, and a strong password
- Click OK
I used the naming convention, [AppName]User, and a randomly generated password from KeePass. Once created you get additional options for managing the user, like Change Password, and Disable.
Step 2 – Grant the WMSvc account access to our directory
The Service name (as shown in the Services MMC) is Web Management Service, and is not started by default. Using the Services MMC, start the Web Management Service and set it’s start-up type to Automatic, or Automatic-Delayed.
Note the user account that the service is running under. By default it runs as Local Service. You will need to Grant the Local Service account full permissions to the targeted deployment directory. Since I’d like to look into running the Web Management Service as a lower privileged account in the future, I took the extra steps to create a local user group called MSDeplyUsers, added Local Service to it, and granted permissions to the group. This will allow me to more easily switch accounts in the future.
Before proceeding, you may need to make an additional change to your IIS server configuration. By default, the Management Service is not configured to accept remote connections. While the Web Management Service is stopped, in IIS Manager, click your top level server node on the left, and then select Management Service under Management in the center pane.
Check the box for Enable remote connections, and select a SSL certificate. I’m using a self signed SSL cert for now. I also added IP restrictions to restrict remote deployments from my office only. You can use www.whatismyip.com to determine you IP, but unless you have a static IP, you may have to come back and change this often. You will also need to add the port specified to your allow section in your firewall rules.
Step 3 – Configure Delegation
In order for our user account we created in Step 1 to have access to their folder, we need to grant permissions on the folder (or site). You can only set folder level permissions if the folder is setup as an Application.
Once you have selected the level (using the navigation tree on the left) at which to grant permissions, you can select the IIS Manger Permissions option in the central pane.
- Click on IIS Manger Permissions
- Click on Allow User on the far right pane
- Select IIS User and then select the user you created in Step 1
Step 4 – Add delegation rules
We now need to grant some specific rights to our user so they can deploy. This is done using the Management tools at the server level.
- Double click on Management Service Delegation
- Click on Add rule on the actions pane
- Select the Deploy Content Only Template (I, as an administrator will handle the configuration of the application directory and advanced configuration).
- Accept all default
- Providers: contentPath
- Actions: *
- Path Type: Path Prefix
- Run As: Current User
- When you click OK, you will be asked to provide the name of a user to add to the rule. This is where you specify your user you created in Step 1.
The steps for IIS 7.5 may differ from IIS 7.
Step 6 – Restart Web Management Service
Pretty self explanatory, using the Services restart, or start the Web Management Service.
Step 7 – Test
In visual study, you need to publish your web application to your newly configured remote server. Right click on your web project and choose Publish. In the screen that comes up, select MSDeploy Publish as your Publish Method and fill in the settings to match what we did in Steps 1 – 6.
Assuming everything is setup correctly, you should be able to publish you application to your remote server. Based on the rules we setup in Step 4, this will only publish content. It will not deploy database scripts, or create the application for you (mark the folder as an application). You can follow the more detailed instructions to set this up, but I wanted to keep this simple for now.
Nothing ever works right on the first time does it? It took me a couple of tries (by couple I mean hundreds) to get all the configuration setup on the client and server. Here are some of the errors I got and what I did to fix them:
Could not complete the request to remote agent URL ‘https://Server:8172/msdeploy.axd?site=
Unable to connect to the remote server
A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond
If you get connection timeouts, make sure you can browse to the Service URL entered above in the publish web screen. If you can’t, you hosting provider may be blocking port 8172. You should at least get prompted for credentials when using a Web Browser. If using a self signed cert, you will also get a certificate warning in the browser. Finally, you should see you attempt in the Log Files for the Management Service. The default path for the log files is: %SystemDrive%InetpublogsWMSvc
Error 400 Bad Request
Remote agent (URL https://Server:8172/MsDeploy.axd:8172/msdeploy.axd?site=
An unsupported response was received. The response header ‘MSDeploy.Response’ was ” but ‘v1’ was expected.
The remote server returned an error: (400) Bad Request.
This one was driving me nuts, and the fix/cause is absolutely ridiculous. Notice the two /MsDeploy.axd, one pascal cased, and the other all lower case. Now take a look at the following screen shot and compare have I have in the ServiceUrl and the example service URL provided in the same dialog.
Looks like it should work right? Nope, doesn’t work. What fixed it, changing it so that the /MsDeploy was all lower case as in https://Server:8172/msdeploy.axd. This got rid of the first MsDeploy.axd.
Remote agent (URL https://Server:8172/msdeploy.axd?site=Default Web Site) could not be contacted. Make sure the remote agent service is installed and started on the target computer.
An unsupported response was received. The response header ‘MSDeploy.Response’ was ” but ‘v1’ was expected.
The remote server returned an error: (401) Unauthorized.
The first question I had was, is the site “Default Web Site” correct? I was worried about the spaces in the name, but after reviewing the log files, the correct escape characters for a space where present. The full result code was a 401.2. I saw that my user account I created in Step 1 was being passed thru, and assumed that it had something to do with that.
I changed my credentials to an Windows Administrative account and gave that a go, and it worked. This means the service itself works, but either my authentication or authorization for the IIS user account is incorrect. If you are having problems with an administrative account, you need to make sure that you have the option enabled for Administrators to bypass rules. This is under Management Service Delegate, Edit Features. If you change this setting, you need to restart the Management Service.
When I had the Allow Administrators to bypass rules box unchecked, I got a different error message, one that said I was unauthorized to perform an action, not a 401. This led me to believe that my IIS User was suffering from an Authentication issue, not authorization.
Since the IIS Users are for management, I decided to try connecting to my Application using the IIS Management tool. Running this as a non-administrator you presented with a “empty” view. Right clicking on clicking on Start Page allows you to Connect to a Server, Web Site or Application. Selecting Application, and entering my credentials left me with a 401 Unauthorized error, confirming my belief that its a problem with the IIS User and not MSDeploy.
After playing around with the IIS settings, the IIS User account started working when connecting via IIS Manager, but not via VS. I do not believe I changed anything (without changing it back) to explain why it started working in IIS manager. The result codes when it was failing was the same 401.2 as I was getting when connecting via IIS.
For now I have to leave this as an open issue, and maybe try again on a local server.
I got it working more or less. Check out the comments for what I had to do.