Tuesday, September 11, 2012 8:47 AM srkirkland

CI Deployment Of Azure Web Roles Using TeamCity

After recently migrating an important new website to use Windows Azure “Web Roles” I wanted an easier way to deploy new versions to the Azure Staging environment as well as a reliable process to rollback deployments to a certain “known good” source control commit checkpoint.  By configuring our JetBrains’ TeamCity CI server to utilize Windows Azure PowerShell cmdlets to create new automated deployments, I’ll show you how to take control of your Azure publish process.

Step 0: Configuring your Azure Project in Visual Studio

Before we can start looking at automating the deployment, we should make sure manual deployments from Visual Studio are working properly.  Detailed information for setting up deployments can be found at http://msdn.microsoft.com/en-us/library/windowsazure/ff683672.aspx#PublishAzure or by doing some quick Googling, but the basics are as follows:

  1. Install the prerequisite Windows Azure SDK
  2. Create an Azure project by right-clicking on your web project and choosing “Add Windows Azure Cloud Service Project” (or by manually adding that project type)
  3. Configure your Role and Service Configuration/Definition as desired
  4. Right-click on your azure project and choose “Publish,” create a publish profile, and push to your web role

You don’t actually have to do step #4 and create a publish profile, but it’s a good exercise to make sure everything is working properly.  Once your Windows Azure project is setup correctly, we are ready to move on to understanding the Azure Publish process.

Understanding the Azure Publish Process

The actual Windows Azure project is fairly simple at its core—it builds your dependent roles (in our case, a web role) against a specific service and build configuration, and outputs two files:

  • ServiceConfiguration.Cloud.cscfg: This is just the file containing your package configuration info, for example Instance Count, OsFamily, ConnectionString and other Setting information.
  • ProjectName.Azure.cspkg: This is the package file that contains the guts of your deployment, including all deployable files.

When you package your Azure project, these two files will be created within the directory ./[ProjectName].Azure/bin/[ConfigName]/app.publish/.  If you want to build your Azure Project from the command line, it’s as simple as calling MSBuild on the “Publish” target:

msbuild.exe /target:Publish

Windows Azure PowerShell Cmdlets

The last pieces of the puzzle that make CI automation possible are the Azure PowerShell Cmdlets (http://msdn.microsoft.com/en-us/library/windowsazure/jj156055.aspx).  These cmdlets are what will let us create deployments without Visual Studio or other user intervention.

Preparing TeamCity for Azure Deployments

Now we are ready to get our TeamCity server setup so it can build and deploy Windows Azure projects, which we now know requires the Azure SDK and the Windows Azure PowerShell Cmdlets.

Once this SDK is installed, I recommend running a test build to make sure your project is building correctly.  You’ll want to setup your build step using MSBuild with the “Publish” target against your solution file.  Mine looks like this:

image

Assuming the build was successful, you will now have the two *.cspkg and *cscfg files within your build directory.  If the build was red (failed), take a look at the build logs and keep an eye out for “unsupported project type” or other build errors, which will need to be addressed before the CI deployment can be completed.

With a successful build we are now ready to install and configure the Windows Azure PowerShell Cmdlets:

  • Follow the instructions at http://msdn.microsoft.com/en-us/library/windowsazure/jj554332 to install the Cmdlets and configure PowerShell
  • After installing the Cmdlets, you’ll need to get your Azure Subscription Info using the Get-AzurePublishSettingsFile command. Store the resulting *.publishsettings file somewhere you can get to easily, like C:\TeamCity, because you will need to reference it later from your deploy script.

Scripting the CI Deploy Process

Now that the cmdlets are installed on our TeamCity server, we are ready to script the actual deployment using a TeamCity “PowerShell” build runner.  Before we look at any code, here’s a breakdown of our deployment algorithm:

  1. Setup your variables, including the location of the *.cspkg and *cscfg files produced in the earlier MSBuild step (remember, the folder is something like [ProjectName].Azure/bin/[ConfigName]/app.publish/
  2. Import the Windows Azure PowerShell Cmdlets
  3. Import and set your Azure Subscription information (this is basically your authentication/authorization step, so protect your settings file
  4. Now look for a current deployment, and if you find one Upgrade it, else Create a new deployment

Pretty simple and straightforward.  Now let’s look at the code (also available as a gist here: https://gist.github.com/3694398):

$subscription = "[Your Subscription Name]"
$service = "[Your Azure Service Name]"
$slot = "staging" #staging or production
$package = "[ProjectName]\bin\[BuildConfigName]\app.publish\[ProjectName].cspkg"
$configuration = "[ProjectName]\bin\[BuildConfigName]\app.publish\ServiceConfiguration.Cloud.cscfg"
$timeStampFormat = "g"
$deploymentLabel = "ContinuousDeploy to $service v%build.number%"
 
Write-Output "Running Azure Imports"
Import-Module "C:\Program Files (x86)\Microsoft SDKs\Windows Azure\PowerShell\Azure\*.psd1"
Import-AzurePublishSettingsFile "C:\TeamCity\[PSFileName].publishsettings"
Set-AzureSubscription -CurrentStorageAccount $service -SubscriptionName $subscription
 
function Publish(){
 $deployment = Get-AzureDeployment -ServiceName $service -Slot $slot -ErrorVariable a -ErrorAction silentlycontinue 
 
 if ($a[0] -ne $null) {
    Write-Output "$(Get-Date -f $timeStampFormat) - No deployment is detected. Creating a new deployment. "
 }
 
 if ($deployment.Name -ne $null) {
    #Update deployment inplace (usually faster, cheaper, won't destroy VIP)
    Write-Output "$(Get-Date -f $timeStampFormat) - Deployment exists in $servicename.  Upgrading deployment."
    UpgradeDeployment
 } else {
    CreateNewDeployment
 }
}
 
function CreateNewDeployment()
{
    write-progress -id 3 -activity "Creating New Deployment" -Status "In progress"
    Write-Output "$(Get-Date -f $timeStampFormat) - Creating New Deployment: In progress"
 
    $opstat = New-AzureDeployment -Slot $slot -Package $package -Configuration $configuration -label $deploymentLabel -ServiceName $service
 
    $completeDeployment = Get-AzureDeployment -ServiceName $service -Slot $slot
    $completeDeploymentID = $completeDeployment.deploymentid
 
    write-progress -id 3 -activity "Creating New Deployment" -completed -Status "Complete"
    Write-Output "$(Get-Date -f $timeStampFormat) - Creating New Deployment: Complete, Deployment ID: $completeDeploymentID"
}
 
function UpgradeDeployment()
{
    write-progress -id 3 -activity "Upgrading Deployment" -Status "In progress"
    Write-Output "$(Get-Date -f $timeStampFormat) - Upgrading Deployment: In progress"
 
    # perform Update-Deployment
    $setdeployment = Set-AzureDeployment -Upgrade -Slot $slot -Package $package -Configuration $configuration -label $deploymentLabel -ServiceName $service -Force
 
    $completeDeployment = Get-AzureDeployment -ServiceName $service -Slot $slot
    $completeDeploymentID = $completeDeployment.deploymentid
 
    write-progress -id 3 -activity "Upgrading Deployment" -completed -Status "Complete"
    Write-Output "$(Get-Date -f $timeStampFormat) - Upgrading Deployment: Complete, Deployment ID: $completeDeploymentID"
}
 
Write-Output "Create Azure Deployment"
Publish

 

Creating the TeamCity Build Step

The only thing left is to create a second build step, after your MSBuild “Publish” step, with the build runner type “PowerShell”.  Then set your script to “Source Code,” the script execution mode to “Put script into PowerShell stdin with “-Command” arguments” and then copy/paste in the above script (replacing the placeholder sections with your values).  This should look like the following:

image

 

Wrap Up

After combining the MSBuild /target:Publish step (which creates the necessary Windows Azure *.cspkg and *.cscfg files) and a PowerShell script step which utilizes the Azure PowerShell Cmdlets, we have a fully deployable build configuration in TeamCity.  You can configure this step to run whenever you’d like using build triggers – for example, you could even deploy whenever a new master branch deploy comes in and passes all required tests.

In the script I’ve hardcoded that every deployment goes to the Staging environment on Azure, but you could deploy straight to Production if you want to, or even setup a deployment configuration variable and set it as desired.

After your TeamCity Build Configuration is complete, you’ll see something that looks like this:

image

Whenever you click the “Run” button, all of your code will be compiled, published, and deployed to Windows Azure!

One additional enormous benefit of automating the process this way is that you can easily deploy any specific source control changeset by clicking the little ellipsis button next to "Run.”  This will bring up a dialog like the one below, where you can select the last change to use for your deployment.  Since Azure Web Role deployments don’t have any rollback functionality, this is a critical feature.

image

 

Enjoy!

Filed under: , , , , , ,

Comments

# re: CI Deployment Of Azure Web Roles Using TeamCity

Tuesday, September 11, 2012 5:01 PM by brady gaster

Nice write-up! This is pretty cool stuff. Great job!

# re: CI Deployment Of Azure Web Roles Using TeamCity

Sunday, December 16, 2012 2:48 PM by code reduc la redoute

Around plethora our favorite relatives are familiar with our company; when it comes to hardship when they're older our favorite relatives.

# re: CI Deployment Of Azure Web Roles Using TeamCity

Tuesday, February 26, 2013 12:20 AM by Jenson

My programmer is trying to persuade me to move to .

net from PHP. I have always disliked the idea because of the

costs. But he's tryiong none the less. I've been using WordPress on numerous websites for about a

year and am concerned about switching to another platform.

I have heard great things about blogengine.net. Is there a way I can transfer all my wordpress

posts into it? Any kind of help would be greatly appreciated!

# re: CI Deployment Of Azure Web Roles Using TeamCity

Tuesday, February 26, 2013 2:30 PM by Dion

Wonderful article! That is the kind of information

that should be shared around the internet. Shame on Google for no longer positioning

this submit higher! Come on over and visit my web site .

Thanks =)

# re: CI Deployment Of Azure Web Roles Using TeamCity

Wednesday, February 27, 2013 2:00 PM by Orr

Hello! I'm at work browsing your blog from my new iphone 3gs! Just wanted to say I love reading through your blog and look forward to all your posts! Carry on the superb work!

# re: CI Deployment Of Azure Web Roles Using TeamCity

Wednesday, February 27, 2013 11:21 PM by Good

What's up, yes this post is truly good and I have learned lot of things from it about blogging. thanks.

# re: CI Deployment Of Azure Web Roles Using TeamCity

Tuesday, April 2, 2013 4:39 PM by coach factory outlet online

If you love any kind of marketing of a really, add up pals.

# re: CI Deployment Of Azure Web Roles Using TeamCity

Tuesday, April 16, 2013 2:24 PM by Mccollum

What's up to every single one, it's truly a nice for me to pay a visit

this web site, it includes priceless Information.

# re: CI Deployment Of Azure Web Roles Using TeamCity

Saturday, April 20, 2013 1:49 PM by www.b33.fr

It is possible Fin intends most of us to satisfy a few wrong folk earlier living up to the most appropriate one, making sure that after we then finally match the customer, we're going aren't able to often be happy.

# re: CI Deployment Of Azure Web Roles Using TeamCity

Monday, April 22, 2013 3:51 PM by archeage gold

Using a particular cold evening, archeage gold are perfect.

# re: CI Deployment Of Azure Web Roles Using TeamCity

Tuesday, April 23, 2013 10:15 AM by Garvin

When some one searches for his necessary thing, so he/she needs to be available that in detail, so that thing is maintained over here.

# re: CI Deployment Of Azure Web Roles Using TeamCity

Wednesday, April 24, 2013 6:17 AM by cheap neverwinter gold

I feel cheap neverwinter gold are adorable, fashion, and very great.

# re: CI Deployment Of Azure Web Roles Using TeamCity

Saturday, April 27, 2013 2:16 AM by diablo 3 gold

Decreased diablo 3 gold your bundle format and function.  I come with nearly always reckoned. diablo 3 gold were cute but yet my friends, siblings and also pals .  Presently, they both apparent footwear!Everyone is when it comes to Therefore ,. Fla. Coupled with diablo 3 gold abound

# re: CI Deployment Of Azure Web Roles Using TeamCity

Monday, May 6, 2013 4:15 AM by 2buu

asduhakjdhkjahdkjhaksdjlhasdjkdhahdkjhakhdkjahsjkdhjkssssssssssssssssssssssssssssssssssssssssss