Infrastructure as Code using Azure RM, PowerShell DSC, Chocolatey and Octopus Deploy

Everyone has been in a situation where your application is behaving differently on your production environment compared to how it behaves on your testing environment. Most of the time this is because these environments aren’t identical and even if they were at the beginning, it’s hard to keep them in sync with all the modifications and updates. Or think of the situation in which you need an extra server to test a new feature or need a new server because your current one cannot keep up with the load. In these situations, Infrastructure as Code is your answer (and to a lot of other problems). Infrastructure as Code is the process of managing and provisioning computing infrastructure and their configuration through code. It’s a very nice addition to the principles of Continuous Delivery as with these techniques one can manage ingrastructure during deployment of an application.

At a high level this blog will cover:

  • Using Azure Automation DSC to manage server configurations
  • Using Azure RM to create a new virtual machine
  • Using Chocolatey to create and maintain a package of a custom application
  • Using Octopus Deploy to release a web application

Azure Automation DSC

AzureAutomationIn this blog, I will be using a Windows Server on which I want to install multiple applications. Since I want to be able to delete and re-create this machine automatically we need something that manages this machines configuration. This is where Azure Automation DSC shines. It allows you to author and manage PowerShell Desired State Configurations. Desired state configuration enables you to declaratively say ‘Here is how I want this machine to be configured’ instead of writing scripts to do so. For example, you can say, “I want Chocolatey installed, I want IIS installed, I want port 80 opened”. These DSC items will be placed on the Azure Automation DSC pull server so that target nodes (such as physical and virtual machines) in the cloud or on-premises can pick them up, automatically conform to the desired state they specify, and report back on their compliance with the desired state to Azure Automation.

To create an Azure Automation account and setup a DSC pull server use the portal or run the following PowerShell script:

Next we need to create our first DSC configuration and add it to the pull server. The configuration contains a Configuration block.  You define it by using the Configuration keyword and providing a name. In this case, the name of the configuration is “ServerConfig”. Within this block there are one or more Node blocks. These define the VMs that you are configuring. In this example there is one Node “webserver”. Within this node there a multiple Resource blocks. This is where the configuration sets the properties for the resources that it is configuring. In this example there are blocks to install IIS, install IIS manager, install Chocolatey, install ASP.net 4.5, remove the default website from IIS and use Choclatey to install a self-made package to install the Octopus Tentacle. This last step uses a self-made package from a custom location using myget.org. More on creating this package later in this blog.  As you can see, steps can depend on each other to make sure they are executed in the right order. It’s important to know that the name of the configuration and the name of the node are used later on to specify which configuration should be applied to the new VM. In this example this becomes ‘ServerConfig.webserver’. As you can see there are two imports at the top of the file. These are needed because they are not in the default installed list of DSC Resources. To be able to use them we need to add them to our pull server. Open the Azure portal, navigate to your Automation account and click on Assets and the Modules. Click on browse Gallery and search for cChoco and xWebAdministration. Install both.

Once we are done with creating this configuration we need to add it to the pull server and compile it. Run the following script to do so.

Within the portal, you should know see one configuration that has been published.

AzureDsc

Azure Resource Manager

AzureRMRunning an application typically requires different components, for example virtual machines, databases, storage queues, etc.  You see them as related and interdependent parts of your infrastructure. Azure resource manager enables you to deploy, manage and monitor them as a group. This group is called a ‘Resource Group’ and this basically is a container holding your resources. A resource is a through Azure manageable item, for example a virtual machine. Resources and resource groups are managed using resource providers. Every resource provider offers operations for working with the resources that are deployed. A common resource provider is Microsft.Compute which supplies the virtual machine resource. Resources can be managed within the Azure portal, using PowerShell API’s or by using a resource template. Using a ‘Resource Manager template’ one can declaratively define one or more resources to deploy to a resource group. This template defines the relations between the resources and can be used to deploy the resources consistently and repeatedly. In this blog, I’ll be using a template.

A template contains the following elements:

Parameters are values that are provided during deployment to customize resource deployment. Variables are values that are used in the template to simplify reuse of values. Resources are the types that are deployed or updated in a resource group. Outputs are values that are returned after deployment. Here you can find more details on the templates. I will now discuss a few details.

While deploying this template it will ask you for a registration key. You can find this one in the Azure portal within your automation account. Go to all settings -> keys.

This template creates a Windows Server 2012 Virtual machine and all of its needed resources like storage and network interfaces. It creates a Network security group which opens ports 80 (http), 3389 (RDP) and 10933 (Octopus Tentacle). Most important for this demo is the installation of the PowerShell DSC Extension and the configuration of it. Here you’ll need to replace the RegistrationUrl with the url of your Automation account. You can find this url on the same page as the key. Another thing to point out is the NodeConfigurationName property. This is now set to ServerConfig.webserver and is used to tell this server which configuration it should read from the DSC pull server and apply. Below you will find my template.json and a script to deploy this template. Once this deployment completes you should see a new VM in the portal and have one DSC Node in your Automation account.

AzureDscNode

Chocolatey

ChocolateyFor Azure Automation DSC to be able to apply configuration it needs to know how to do so and for this it uses DSC Resources. These provide the building blocks for a DSC configuration and the expose properties and contains the PowerShell scripts to configure the resource. Within Azure DSC there a build in resources that you can use. For example, there is one to install IIS. You can also create these on your own to implement one for your own application. I decided to take in one step further and use Chocolatey instead. Chocolatey is a Windows package manager that allows you to install for example Google Chrome using one command line statement. Azure DSC has a resource that you can use to install Chocolatey packages. I will use a custom created Chocolatey package to install the Octopus Tentacle. I won’t go into too much details on Octopus here. For now, it is important to know that Octopus runs on its own server and that you install an Octopus Tentacle on every other server to which you want to deploy your application.

To create a Chocolatey package we first need to install Chocolatey from chocolatey.org. Once we’ve done that we create a nuspec file with the following contents:

Within the same directory as this nuspec file create a folder named tools. Within this folder create a powershell file named chocolateyInstall.ps1. A very simple installation would look like:

Installing the Octopus Tentacle is a bit harder. Mostly because I want to be able to pass in some variables to the process. Once you are done with the installation script, run cpack from within the package directory and your package will be created. I’ve used myget.org as a free package server. Create your own repository and upload your package. You are off course free to use mine.

Octopus Deploy

OctopusDeployOctopus Deploy is an automated software deployment and release management server. It is designed to simplify deployment of ASP.NET applications, Windows Services and databases. Since version 3.4 Octopus lets you trigger a deployment when it detects that a new tentacle has been installed. This means that when our server is installed using DSC, Octopus will detect it and automatically deploy the latest version of our application to it. If you don’t already own an Octopus server you can easily create one within Azure. Go to Virtual Machines, click add and search for Octopus Deploy.

Within Octopus go to Environments. If the deployment of the template succeeded and the DSC config has been applied to the VM, you should see an new deployment target. Now create a new project and configure it to deploy a package to an IIS server. Here you can find more details on how to do that if you are new to this. While you are on the project page go to Triggers and click Create trigger. Give it a nice name and select ‘New deployment target becomes available’ in the Event drop-down. For Environments choose the first environment in your deployment pipeline. For Roles choose the role that you have specified while installing the tentacle using Chocolatey.

octoTrigger

Now when Octopus detects the new tentacle it should deploy the latest version of your application to the new server.

octoDeploy

And there you are! Now you can issue one PowerShell statement and a completely new VM is automatically created en maintained using PowerShell DSC and Octopus Deploy!

You may also like...