Deploying to Azure using Azure Resource Manager templates and Octopus Deploy
Azure Resource Manager (ARM) is a set of APIs that enable interacting with Azure for creating and managing resources. ARM Templates create a simpler way of automating deployment to Azure, by allowing all the parts of your infrastructure to be declared in the template. Azure itself then handles how that infrastructure gets created including the order of execution and running things in parallel where possible.
Defining infrastructure in this way is known as Infrastructure as Code, which offers many benefits such as being able to keep your templates in a source code repository for versioning and change tracking.
Managing deployments across multiple environments, from development through to production, can be a complicated and challenging process. Octopus Deploy exists to make this process simpler, faster and more feature rich than tacking deployment on to an existing build server or hand rolling your own deployment process.
Octopus Deploy is a deployment automation server, installed on your own infrastructure. It's premise is that it does one thing and it does it well. Where a build server is great at compiling code and running tests, Octopus is great at taking the artefacts that build, configuring them and then distributing them to all the machines and environments that they need to run in. One of the key features that make an Octopus deploy superior to a build server for deployments is concurrency of tasks. Deploying the same package to many different locations concurrently is an area Octopus Deploy excels at.
In an Azure context, this could be useful for provisioning virtual machines that have already been deployed by an ARM Template. Even if you are purely deploying an ARM template full of Azure resources with no additional artefact deployment, there are plenty of other features that make Octopus worthwhile. To name but a few: configuration per environment, all deployments easily discoverable in one place, promotion between environments, and requirement of manual intervention and approval if necessary.
How can you use them together?
The Azure Resource Group Template step type was released with Octopus Deploy 3.3. This makes it really straight forward to set up a deployment process using the built-in step.
The Azure Resource Group Template step requires a Service Principal for authentication. To learn how to create a service principal using PowerShell, see a previous post on the endjin blog or a similar article in the Octopus documentation.
When adding a new Step to the deployment Process of a Project in Octopus, you'll see the Deploy an Azure Resource Group step type:
After choosing the step, you'll see a page where various properties need to be completed:
The account type has to be a service principal, which you should have already created.
It is possible to get the JSON template from "source code" which actually means you can paste the JSON directly into the deployment step in a multi-line text box. If this option is chosen the JSON is parsed and the parameters required by the template will appear directly in the step details form. The other alternative is to use a file inside a NuGet package, in which case you need to specify where to get the package, and what the template and template parameters paths are.
Taking things further
It is unlikely that you will have a single step in the deployment pipeline, for deploying an Azure Resource Group. In reality, multiple different types of step will be used for different purposes.
Creating the Azure Resource Group using a PowerShell step
The Azure Resource Group must exist before the deployment step can happen. When creating the deployment step you enter the name of the Resource Group to use. This could be achieved by using the "Run an Azure PowerShell Script" step. After adding the Step to the Deployment Process, the following PowerShell script could be added to the Script text field in the step:
New-AzureRmResourceGroup -Name $GroupName -Location $Location -Force
'$GroupName' and '$Location' are references to variables defined for the Project.
Creating a reusable Step Template
Creating a Resource Group using a PowerShell script is something that is going to be repeated. Octopus offers Step Templates that can be shared across your own projects, or shared with the community. There is also a library of community templates that can be reused.
Navigate to the 'Library' page from the top navigation bar. Then to the 'Step templates' page from the left navigation section. Then click the 'Add step template' button.
In the dialogue that appears, select the 'Run an Azure PowerShell Script' step type. Give the template a name and description. On the 'step' tab enter the PowerShell script from the previous section.
The script parameters could come from the variables of the project itself like previously. Parameters can also be set on the template. If this is done, they can be entered when adding the step to the deployment process. The section highlighted in red in the image below is a parameter defined on the template being entered when using the template:
Once all the template settings and parameters are to your liking, save the template to your library.
Now when you are adding a step to the deployment process for a project, the list of available steps will include the step template just added, for creating an Azure Resource Group.
Develop the ARM template using Visual Studio and use the NuGet package template source option
While it is possible create an ARM template directly in the Step definition by using the "source code" option, developing the template using Visual Studio has lots of benefits.
There is an Azure Resource Group project type that enables deployment of the template directly from Visual Studio. There is good JSON editing support. It's possible to add some common resources to the template using a wizard UI instead of manually.
Developing the template in your normal environment also means you can integrate with source control and build systems in the same way as you do with the rest of your code.
Use ARM Template parameters over Octopus variable substitution
Octopus variable substitution can be used in both the template and parameter files. It is recommended to use variable substitution with the parameters file only, and not in the template itself. The ARM template parameters should then be provided in the parameter file. This enables the template to be reused elsewhere, for example deploying from Visual Studio during development time or from another build or deployment solution.
Use ARM Template outputs
There is an "outputs" section in an ARM template that can be used to return values from the deployment. Octopus will capture those template outputs as output variables that can be used later in the deployment process.
For example, if a storage account resource is created by the template, values can be set in the outputs section for the name and access key for that storage account. The next step in the deployment process deploys a web app using the storage name and key variables to set a connection string in the web app configuration.