Twitter RSS

Blog Search

Latest Articles

Latest Comments

Popular Tags

Recent Months

Reading List

C# in Depth (2nd Edition)

Head First Design Patterns

Programming Entity Framework

Azure in Action

Dependency Injection in .NET


Azure Web Sites Git Deploy For Multiple Project Solutions

Created on April 27, 2013 at 02:00 by Paul Hiles | Permalink | 1 comment

If you are trying to Git deploy a solution with multiple web projects to multiple Windows Azure websites, you will find that it does not work out of the box. This post describes a simple way to workaround this omission by creating a custom deployment script. Don't worry though - it is dead simple.

With the introduction of ASP.NET Web API, it is now a very common requirement to want to add an API to your website. Most examples add Web API code into the same Visual Studio Project as your main website but if you are creating an API for public consumption, you probably do not want to take this approach. Instead, you might want a solution containing at least three projects: The Website, the Web API and a common library that is used by the other two projects. This is all very simple to set up within Visual Studio but if you want to Git deploy your projects to Windows Azure Websites (WAWS), things get a little bit more complicated.

Git deployment to Azure is fantastic, particularly if you are integrating your source control repo into the mix. Commit your code to GitHub, Bitbucket (or many others) and have azure automatically deploy the latest version. All very nice and with a single web application in your solution, this works seamlessly. Once we add a second web project to the solution for the API, things get interesting. To put it simply, out of the box, you will not be able to deploy both projects to Azure successfully. The root of the problem is that is is not possible (via the Azure portal) to tell an Azure website which project within the solution to deploy. Attempting to configure multiple websites to the same Git repository will deploy the first web project in the solution to both websites.

Fortunately, as is often the case, it is relatively easy to workaround these limitations.

One simple approach is to utilise the fact that you can tell azure which project to use via a .deployment file in the root of your repo.

    project = MyProject.Api/MyProject.Api.csproj

If you use different branches for each website, you can change this file in each branch to specify which project to use.

Whilst this works, it is not an ideal solution and I do not want to create separate branches for something as simple as this. Therefore, we are going to take another approach which involves using a custom deployment script.

You can get a lot more information from a great blog series by Amit Apple but for the sake of clarity, we will shortcut the process and just detail the files necessary to get it working.

In essence, we are just extending the above approach using the .deployment file. This time, instead of just specifying a project to use, we change the .deployment file to indicate that we want to customise the deploy process and use our own deployment script:

    command = deploy.cmd

The batch file that gets called needs to contain conditional logic to use the correct project for each azure website. In order to do this, we can utlise the fact that any app settings created via the azure portal will be available as environment variables within our script. So, let's go into the Azure portal and create a new key:

Windows Azure Web Sites App Settings

Figure 1: Windows Azure Web Sites App Settings

Now, it would be nice if we could just pass the appropriate project name to the default deployment script but I haven't found any way of dynamically doing this. Instead we are providing our own deployment script in place of the default:

@echo off
 :: ----------------------
:: KUDU Deployment Script
:: ----------------------

:: Prerequisites
:: -------------

:: Verify node.js installed
where node 2>nul >nul
  echo Missing node.js executable, please install node.js, if already installed make sure it can be reached from current environment.
  goto error

:: Setup
:: -----

setlocal enabledelayedexpansion

SET ARTIFACTS=%~dp0%artifacts





  :: Install kudu sync
  echo Installing Kudu Sync
  call npm install kudusync -g --silent
  IF !ERRORLEVEL! NEQ 0 goto error

  :: Locally just running "kuduSync" would also work
  SET KUDU_SYNC_COMMAND=node "%appdata%\npm\node_modules\kuduSync\bin\kuduSync"
  SET DEPLOYMENT_TEMP=%temp%\___deployTemp%random%


  SET MSBUILD_PATH=%WINDIR%\Microsoft.NET\Framework\v4.0.30319\msbuild.exe

  echo Missing PROJECT_PATH app setting. Please configure in Azure portal and redeploy.
  goto error

:: Deployment
:: ----------

echo Handling .NET Web Application deployment.

:: 1. Build to the temporary path
%MSBUILD_PATH% "%DEPLOYMENT_SOURCE%\%PROJECT_PATH%" /nologo /verbosity:m /t:pipelinePreDeployCopyAllFilesToOneFolder /p:_PackageTempDir="%DEPLOYMENT_TEMP%";AutoParameterizationWebConfigConnectionStrings=false;Configuration=Release
IF !ERRORLEVEL! NEQ 0 goto error

:: 2. KuduSync
echo Kudu Sync from "%DEPLOYMENT_TEMP%" to "%DEPLOYMENT_TARGET%"
call %KUDU_SYNC_COMMAND% -q -f "%DEPLOYMENT_TEMP%" -t "%DEPLOYMENT_TARGET%" -n "%NEXT_MANIFEST_PATH%" -p "%PREVIOUS_MANIFEST_PATH%" -i ".git;.deployment;deploy.cmd" 2>nul
IF !ERRORLEVEL! NEQ 0 goto error


goto end

echo An error has occured during web site deployment.
exit /b 1

echo Finished successfully.

Yes, this is quite a lot of code but rest assured that I did not just make it up. This is the default deployment script with a couple of tweaks. If you want to confirm this, you can generate it yourself using the Deployment Script Generator that is part of azure-cli (NB Node.js must be installed to use this tool). You can find out more about this tool and the deployment process in general on the Project Kudu GitHub Wiki.

In terms of changes to the default script, all we are doing is making sure that the environment variable is available and if so, using it in the MSBuild call. It would be nice to allow just the folder name to work rather than the full relative path of the csproj file but I do not know enough about MSBuild and deployments in general to be able to do this. It might also be useful to revert to the default deploy behaviour (picking the first web project in the solution) if the environment variable is not found but again, do not know how to do this.

Once you have created these two files (.deployment and deploy.cmd) and checked them in to your repo (at the root), provided that you have added the correct appsettings, you should find that both your websites are updated correctly. All subsequent commits will deploy both sites.


If you found this article useful then we would be very grateful if you could help spread the word. Linking to it from your own sites and blogs is ideal. Alternatively, you can use one of the buttons below to submit to various social networking sites.

Twitter Facebook Digg Delicious Reddit StumbleUpon MySpace LinkedIn FriendFeed



Added on May 01, 2013 at 02:18 by Dave | Permalink

Nice post. You can also integrate unit tests into deploy script. see

This article has been locked and further comments are not permitted.