A successful Azure Web App deployment process

Deploying your application automatically on an Azure Web App isn't really challenging. You have several options to do it (including Web Deploy, Git, FTP...); and several release management services (like Visual Studio Team Services) provide automated tasks for this. But you might run into some issues if you just follow the easy way.

The shortest way is still not the best way

You can deploy your application straight to your Azure Web App, but here are the problems you might run into:

  • Your deployment package might be large, so the deployment process would be long enough to introduce significant downtime to your application.
  • After the deployment, the Web App might need to restart. This results in a cold start: the first request will be slower to process and multiple requests may stack up waiting for the Web App to be ready to process them.
  • Your deployment may fail due to files being used by the server processes.
  • If your last deployment introduces critical issues, you have no way to quickly rollback to the previous version.

All of these are worth considering if you are alone in your team, and deploy your application to your own private test Web App. But it isn't exactly the purpose of cloud computing, is it?
I mean, even if you are targeting an integration environment, only used by your kind frontend colleague, you don't want him to hit a brick wall, waiting for you to fix your API if something got wrong.
And if you are targeting a validation environment, would you like to have your QA open a non-reproductible issue due only to the deployment downtime?
And if you are deploying to your producti... OK, I think you got my point here, let's fix it!

Blue-Green deployment

Blue-Green deployment is a release approach to reduce downtime by ensuring you have two identical production environments: Blue and Green. At any time one of them is live, serving all production traffic, while the other is just idle.

Let's say that Blue is currently live.

You can deploy your new release in the environment that is not live, Green in our example. Once your deployment is finished, and your application is ready to serve requests, you can just switch the router so all incoming requests now go to Green instead of Blue.

Green is now live, and Blue is idle.

Credits: BlueGreenDeployment by Martin Fowler.

As well as reducing downtime, the Blue-Green deployment approach reduces risks: if your last release on Green produces unexpected behaviors, just roll back to the last version by switching back to Blue.

Deployment slots to the rescue!

The great news is that you have a nice way to implement the Blue-Green deployments for Azure Web Apps: deployment slots (available in the Standard or Premium App Service plan mode).

What are deployment slots?

By default, each Azure Web App has a single deployment slot called production which represents the Azure Web App itself.
You can then create more deployment slots. They are actually live Web App instances with their own hostnames, but they are tied to the main Web App.

In fact, if:

  • I have a Web App:
    • called geeklearning,
    • with default hostname geeklearning.azurewebsites.net,
  • and I create a slot:
    • named staging,
    • its hostname will be geeklearning-staging.azurewebsites.net.

You can easyly swap two slots, including the production one. Swapping is not about copying the content of the website but, as the Blue-Green approach recommends it, it is more about swapping DNS pointers.

When dealing with deployment slots, you should also be aware of how configuration works.
Indeed, some configuration elements will follow the content across a swap while others will stay on the same slot.

Particulary, the app settings and connection strings are swapped by default, but can be configured to stick to a slot.

Settings that are swapped:

  • General settings - such as framework version, 32/64-bit, Web sockets
  • App settings (can be configured to stick to a slot)
  • Connection strings (can be configured to stick to a slot)
  • Handler mappings
  • Monitoring and diagnostic settings
  • WebJobs content

Settings that are not swapped:

  • Publishing endpoints
  • Custom Domain Names
  • SSL certificates and bindings
  • Scale settings
  • WebJobs schedulers

Create a new slot

To create a new deployment slot, just open your Web App from the Azure Portal and click on Deployment slots, and then Add Slot.

You can choose to clone the configuration from an existing slot (including the production one), or to start with a fresh new configuration.

Once your slot has been created, you can configure it like a normal Web App, and eventually declare some settings as "Slot setting" to stick it to your new slot.

Successful deployment process

Now that you implement the Blue-Green deployments through Azure Web App Deployment Slots, you resolved almost all issues listed before.

The last one left is that your deployment may fail if a file is currently locked by a process on the Web App. To ensure that this will not happen, it seems safer to stop the Web server before deploying and start it again just after. As you are deploying on a staging slot, there is no drawback doing this!

So, the whole successful deployment process comes down to:

  1. Stop the staging slot
  2. Deploy to the staging slot
  3. Start the staging slot
  4. Swap the staging slot with the production one

You may leave the staging slot running after the deployment process, to let you swap it back in case of any issues.

Deploy from Visual Studio Team Services

Update: there is an easier way to deploy from VSTS now: learn how!

Implementing this deployment process in a VSTS Build or Release definition could be a little bit challenging: as you have a default build task to deploy your application to an Azure Web App, even to a specific slot, you can't stop, swap or start slots.

Fortunately, you can run PowerShell scripts, and even get them to use an Azure connection configured for your Team Project thanks to the Azure Powershell task.

You then just have to write three PowerShell scripts using the PowerShell Modules for Azure.

Stop Azure Web App Slot

Create a new PowerShell script named StopSlot.ps1, write the following content, and publish it to your source repository:

param (  
   [string] $WebAppName,
   [string] $SlotName
)

Stop-AzureWebsite -Name "$WebAppName" -Slot "$SlotName" -Force -Verbose  

Start Azure Web App Slot

Create a new PowerShell script named StartSlot.ps1, write the following content, and publish it to your source repository:

param (  
   [string] $WebAppName,
   [string] $SlotName
)

Start-AzureWebsite -Name "$WebAppName" -Slot "$SlotName" -Force -Verbose  

Swap Azure Web App Slots

Create a new PowerShell script named SwapSlots.ps1, write the following content, and publish it to your source repository:

param (  
   [string] $WebAppName,
   [string] $From,
   [string] $To
)

Switch-AzureWebsiteSlot -Name "$WebAppName" -Slot1 "$From" -Slot2 "$To" -Force -Verbose  

Add PowerShell scripts to your build definition

You are now ready to edit your Build or Release definition in VSTS to support your successful Azure Web App deployment process:

  1. Add the three Azure Powershell tasks, one before your Azure Web App Deployment task and two just after
  2. Configure your tasks
    1. Azure Connection Type: Azure Classic
    2. Azure Classic Subscription: Select your configured Azure Classic service (you should have this already configured if you deployed your application to Azure, otherwise learn how to configure it on the VSTS documentation)
    3. Script Path: Select the path to your script (from sources for a Build, or artifacts for a Release)
    4. Scripts Arguments: Should match the parameters declared in your scripts, like -WebAppName "slots-article" -SlotName "staging"

You have now a real successful Azure Web App deployment process, automated from Visual Studio Team Services, without downtime or cold start, strong and safe!

Updated: change screenshots to match VSTS and Azure new UIs, add a link to an easier successful Azure Web App deployment process from VSTS