Simplified Azure Templating

Part 1 - Overview

The Problem

One of the defining concepts of the Azure Resource Management model is the template. Once a template has been defined it is possible to deploy that exact solution repeatability and reliably. This is the fundamental infrastructure-as-code building block in azure.

An ARM Templates is a json document that describes an Azure deployment. When a resource, or resource group are exported there is a one to one relationship between the resources in Azure and the resources defined in the template.

That one to one relationship can become difficult when you are creating templates that have multiple identical resources. In these scenarios you can put conditional logic inside the template to iterate sections of code and to add different external templates depending on passed parameters.

This mix of declarative language and conditional logic makes Azure templating very quickly become a hugely complex solution. One of Microsoft's solutions to this is to create building blocks out of template code. These are a collection of templates that define a specific component of Azure. A virtual machine for instance. a set of parameters can be passed into that block of template and it will go and build that resource, complete with its dependencies. These building blocks can then be stacked to create solutions.

The result of this is that what started off as a technically complex language, that was intimidating even to seasoned Ops people. Has now been used to create a behemoth of code that will confuse even those who are seasoned with the templating language. Trying to have this code managed by support staff who don't do ARM templating every day is going to be a near impossible. This is technical debt at its finest.

Towards a solution

Part of the problem here is that Azure expects everything in a deployment to be explicitly defined. If you look at a deployment of a virtual machine in Azure it will likely have the following components.

Virtual Machine Components
  • Virtual Network.
  • Storage
  • Network Interface
  • Public IP
  • Network Security Group

The first three of those components are mandatory for deploying a virtual machine. The last two are optional. If you could strip out the requirement to explicitly define those first three components then you would save a lot of information. If you specifically need to specify a parameter for one of them, for instance if you want to use premium storage, then you could define that single parameter for the storage solution. Everything else would take a default and auto create.

By stripping out a lot of the extraneous information in templates it would make them a lot easier to read and understand.

The most complicated aspect of ARM templates though is the conditional language that is used. It is clumsy and non-intuitive. Microsoft does have an extremely competent and complete conditional language though. PowerShell is much more widely understood, and is massively more powerful than the conditional processing in templates.

If you could strip out the conditional language from templates, and replace it with PowerShell, you would have a clear separation between the declarative template and the conditional processing.

For instance if you want to deploy four identical virtual machines, you could have a script call a template four times, with the required parameters. This would make future changes and debugging much simplier thereby reducing the technical debt that you leave to support staff.

The Concept

The basic idea for this solution is to provide a building block basis to deploying Azure resources. Similar in concept to Microsoft's solution but using smaller building blocks and instead of making it heavily reliant on ARM's conditional language we will use purely declarative templats and PowerShell as a conditional processor.