InCycle Software's Application Modernization and DevOps Blog

Continuous Deployment to Azure Web Sites with Release Management

Written by Harris Boyce | Mar 13, 2015 12:00:08 PM

In my previous post, we looked at the various options available for enabling continuous deployment to Azure Platform-as-a-Service (PaaS) environments. We'll now take a look at a brief comparison between two PaaS offerings in Microsoft Azure, Cloud Services and Azure Web Sites, and then dig into a basic continuous deployment implementation for Azure Web Sites.

PaaS computing environments allow development teams and organizations to delegate typical operational and management responsibilities to the cloud service provider and concern themselves with developing their solution. In Azure, Cloud Services allows customers to specify the target Operating System and virtual machine sizing requirements for their solution and Microsoft takes on the responsibilities of management and maintenance of Operating System images. While the solution runs on virtual machines, it is important to understand that these virtual machine instances are inherently stateless and the entire machine is reset on every reboot. Cloud Services also provide two role types: web roles and worker roles, where worker roles are intended for background processing activities and do not have the IIS Windows Server role enabled by default. Another option is Azure Web Sites, which abstracts away the most amount of the platform. With Azure Web Sites, customers are provisioned individual IIS Worker Process instances and only have control over that which can be configured using a web.config file, though there are some exceptions. On this platform, Microsoft maintains and operates all aspects of the Windows Servers and IIS instances. Although this platform sounds limiting at first blush, it is extremely powerful, offering the most agility to development teams.

Today, the tooling support for release automation to PaaS environments currently favors Azure Web Sites; countless Azure Resource Manager templates exist to support Azure Web Sites and the Azure PowerShell library offers a significant set of automation commands for Azure Web Sites and other Azure Resources. This post will cover the basics with deploying a simple, empty ASP.NET MVC web application to Azure Web Sites using Release Management in Visual Studio Online. Over the next posts, we will gradually add additional functionality such as deploying databases, running web performance and load tests for verification, and combining testing in production (TIP) deployments with Application Insights to measure the effectiveness of an application change. So let's get started…

Getting Started with Cloud Deployment Projects

The first thing we need to do is create a new Cloud Deployment Project. The project template prompts you to select an Azure Template to leverage for deploying your application; for this, we will select Website:

Once the wizard completes, our solution contains two projects: the web application and the deployment project. Let's take a look at the deployment project:

The deployment project contains two JSON files and a PowerShell script. The WebSiteDeploy.JSON file contains the Azure Resource Manager template which is responsible for describing all of the Azure resources (i.e. services) our application will require and leverage. Inspecting this file, you'll see the following resources defined:

  • Web Site (type: "Microsoft.Web/sites")
  • Web Hosting Plan (type: "Microsoft.Web/serverfarms")
  • Auto-Scaling Rules (type: "Microsoft.insights/autoscalesettings")
    • Scale Up when CPU is over 80%
    • Scale Down when CPU is under 60%
  • Alert Rules (type: "Microsoft.insights/alertrules"):
    • High CPU (CPU > 90%)
    • Long HTTP Request Queue (> 100)
    • HTTP 500 Errors (> 0)
    • HTTP 403 Errors (> 0)
  • Application Insights Component (type: "Microsoft.insights/components")

Many of the resources defined in the template file contain parameterized settings, such as the name of the web site, which data center the site is deployed, and other aspects; this provides control over the provision and configuration of the deployments as you promote application changes across environments. The other JSON file (WebSiteDeploy.param.dev.json) allows you to specify settings for parameters for a development environment; the PowerShell script utilizes both of these files to initiate the deployment of the web application to the Microsoft Azure Web Site, leveraging the WebSiteDeploy.json file to provision the resources with the settings specified in the WebSiteDeploy.param.dev.json file. By default, the Cloud Deployment Projects also makes the assumption that we will leverage MSDeploy from Visual Studio using the Web Application Publishing capabilities to upload a Package ZIP file to Azure Blob Storage for deployment, so, while the default PowerShell script provides us the basics for provisioning our environment, modifications are necessary to ensure we can leverage the workflow, approval process and configuration management capabilities within Release Management. Let's get started by configuring a Release using Visual Studio Online's Release Management service.

Creating the Release Management Template for Azure Web Sites

Microsoft has existing documentation for creating a release using Visual Studio Online that targets virtual machines running in Azure. We will use this as a starting point because the virtual machine will act as our "jump-box" to the Azure platform, so if you haven't done so already, link your Azure account to the build definition in your project on Visual Studio Online by creating a release. Behind the scenes, Visual Studio Online creates multiple release artifacts for you, namely a Release Template, a Release Path and a Component. Components allow you to define deployable units based upon the output of your build. Release Paths represent the approval workflows that take place as the release is promoted through your environments. Finally the Release Templates define the set of actions required to deploy your application's Components – for each environment. So, for example, if your Release Path targets 3 environments and in Production you must do 5 extra actions that do not apply in the two lower environments, that is not a problem.

The most interesting pieces for releases exist in the components and Release Templates. To deploy our application to Azure Web Sites, even for an empty ASP.NET MVC application, we'll need to provide our deployment script several configuration settings for each environment so that our deployment is successful. For example, your production environment may be part of an Azure subscription that only a few people have access to whereas more team members may be able to provision services for development purposes using a different subscription; for reasons like these, we can set up configuration variables at the Component Level so that when our scripts run they are defined and available to use in the script. Other settings that would typically be defined this way would include database connection strings, web service URLs, Blob Storage accounts, etc. In our example, because we're using an Azure Resource Manager template file, we need to provide the path to that file plus values for all the parameters it requires as well:

As the screen shot above indicates, you can specify which variables contain sensitive information which are then encrypted when saved to Release Management, helping to keep configuration information secure. With the configuration variables defined on the component, we utilize the component in the Release Template and simply vary the settings by target stage/environment:

The deployment sequence targets a virtual machine running in Azure (though if we were using Release Management on premise, it could be a "local" virtual machine) and the actions used start the virtual machine, runs the PowerShell script on the targeted machine passing the specified configuration settings to the script, and then stops the virtual machine (because the machine costs us money in Azure, the machine does not need to continue running since the application does not live on this virtual machine). The PowerShell script that is executed is responsible for deploying the resources defined in the Azure Resources Manager template and deploying the web application to the Azure Web Site that is created using the Resource Manager template for each environment. Approval workflow for promotion of a release from environment to environment is configured using the Release Path:

Here, I have four environments defined and, when a release starts, in this scenario, the release is automatically promoted up to the test environment before manual/human approval is required for deployment to the staging environment. To reiterate, because the "Automated" check box next to "Acceptance Step" under the Staging stage is not checked, a person (in this case the "Release Management Service") must approve the deployment before the actions defined in our Release Template are executed. And, because we created our release from a build definition, when our build is successful the release is automatically started – so our application is ready in both the development and test environments and waits for approval before continuing to deploy the release to staging and production:

With the deployment of my application to the development and test environments completed, I can leverage the Azure portal to monitor the health of my application's resource across all environments and have greater insight as to whether or not the application is ready to be promoted to the next environment:

Wrapping Up

The addition of Release Management capabilities to Visual Studio Online offers customers an immense amount of capabilities for enabling continuous deployment to their development process and, for customers leveraging the PaaS offerings in Azure, this hold true for them as well. I hope that this has been beneficial as we're only scratching the surface as to the benefits Azure and Visual Studio Online can provide development organizations as they adopt "DevOps" practices. Next time, we'll look to apply these concepts to a real application and not a simple, out-of-box template application.