For the last few months we have automated the deployment of our Windows Azure web and worker roles – with a couple of clicks we can compile, package, deploy and run our latest bits in the Azure cloud!
We use Team Foundation Server 2010 (TFS) and one of the steps is to create the .CSPKG file – the windows azure package that needs to be uploaded to blob storage before you can use the Azure Management APIs to deploy and run your service.
Below I have some details on how to get that working with the latest Windows Azure SDK, version 1.3. Note that you could use a different source control system and something like Cruise Control .NET (http://cruisecontrol.sourceforge.net/) to automate the deployment of your web and worker roles – the principles are the same.
Update 2/25: Tom Hollander has a great post on his blog on how to achieve the same thing – check out the section “Supporting Multiple Sites per Role”, where he makes sure the azure project depends on the ASP.Net projects (the sites) and transforms the ServiceDefinition.csdef file to make sure the assemblies for the second site are included in the package -
Using MSBuild to deploy to multiple Windows Azure environments
As a side note, I hope Microsoft will provide some direction on how to properly automate the creation of an azure package in TFS 2010, without having to manually scan the target builds installed with the azure SDK.
How to create a Windows Azure package in Team Foundation Server (TFS)
(when you have multiple sites hosted in ‘Full IIS’ in one Azure web role)
To create the Azure package, with the Azure SDK 1.2 and below, I was using an invoke process workflow activity and calling CSPACK. Unfortunately, this stopped working after I installed the Azure SDK 1.3 and I started using the “Full IIS” feature to host multiple sites in one web role.
Here’s how you can create your Azure Package in TFS if you have a web role hosted in ‘Full IIS’ with multiple sites -
Step 1 – Edit your Azure project (.csproj) and change the build target
Open your windows azure project (the one that contains your web and/or worker roles) in Visual Studio and edit the project file (.csproj) in the XML editor.
Change the project’s ‘DefaultTargets’ from ‘Build’ to -
So your project XML will look something like this -
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" DefaultTargets="PrepareForPackaging;Build;CheckRoleInstanceCount;CopyServiceDefinitionAndConfiguration;
Step 2 – Create a pre-build event that compiles all of the sites included in your web role
The only way I found to make sure all of the sites deployed in my web role
included all of the needed assemblies was to have a pre-build event on my
azure project that compiled each site.
You can easily do that by right-clicking on your project > Properties >
Build Events > and editing the ‘Pre-build event command line’ -
You can also edit your project XML directly like we did in step 1-
echo PREBUILDSTEP for $(ProjectName)
if errorlevel 1 goto BuildEventFailed
if errorlevel 1 goto BuildEventFailed
REM Exit properly because the build will not fail
REM unless the final step exits with an error code
echo PREBUILDSTEP for $(ProjectName) FAILED
echo PREBUILDSTEP for $(ProjectName) COMPLETED OK
If I didn’t do this, I would find that after deploying, some assemblies were missing
from the azure package (even though I did set ‘copy local=true’ for the assemblies
in the project and my solution compiled in TFS did include the sites themselves) -
Note: once you make these changes, your compilation time in Visual Studio may increase, since you will be building the Azure package every time you compile.
We tend to run and debug our web sites in IIS in local development and we end up unloading the azure projects during development – so this is not an issue for us.
Step 3 – Edit your TFS Build XAML workflow and add a “MSBuild” activity
1) In your XAML workflow, after your project/solution has been compiled, add an activity of type “Microsoft.TeamFoundation.Build.Workflow.Activities.MSBuild” -
Make sure you choose your targets to be “CorePublish” (although since we edited the project directly, this matters less) -
That’s it! Now with one click you can compile, run your tests, and create the windows azure package to deploy your web role hosting multiple sites to the cloud!
Inside Baseball - How I got this working
After our automatic deployments to the Azure cloud stopped working, I had some talks with my co-worker M. and some discussions with @smarx and others in this thread -
One web role with two sites:
how do I package it in TFS or using msbuild tasks?
which got me digging into the MSBUILD tasks that are installed by the Azure SDK here:
C:\Program Files (x86)\MSBuild\Microsoft\Cloud Service\1.0\Visual Studio 10.0\Microsoft.CloudService.targets
Final note: Development, QA, and Production environments
Just a quick note on our software development process – we have three different branches in source control, corresponding to our three environments.
Our TFS build XAML workflow can handle all three environments/branches and deploys our services (the web and worker roles) differently depending on the arguments – here’s an example of our schedule:
Make sure your XAML workflow can handle different environments and different services – it will save you tons of time.