I tend to find that I have to learn a new technology concept under a bit of time pressure. The requirement is suddenly presented to me and so is an imminent deadline. This was the case when I was asked to create an environment in Azure and ensure that it could be recreated easily. As I was aware of Azure Resource Manager (ARM) templates so I decide to head off it that direction. The first problem is that my awareness of something doesn’t equate to experience so I would be learning on the job. The rest of this post covers some of the things I learned on this journey.
What is an ARM Template?
An ARM template is a JSON file that describes all the resources in an Azure resource group. The syntax is JSON but extended with expressions and functions that allow it to describe resources. See Authoring Azure Resource Manager templates, for more details about the template syntax. Templates can have variables (which simply act as global variables across the template file) and parameters, which allows values to be plugged in from an external source. This makes your templates flexible, so they can be designed to provision an environment but the parameters can be used to vary server names or customise domain names or public IP addresses, etc. In many of the examples you find two JSON files, one being the template and another being values for parameters.
Talking of examples, the best place to find some is in this repository on GitHub. Microsoft has created templates for a huge number of situations so you should find something that is close to what you need. You are free to use them verbatim, plugging in your own parameter values or they can be use as the basis of your own templates. Whilst customising the template is as simple as hacking around the JSON with your favourite text editor, in practice it is not that obvious what you need to do. I found that a better approach was to use the template to setup its bits in Azure. I would then tailor the resource group that was created for my own needs manually via the Azure portal. Then it is possible to export the changes as a customised template using the automation script option. The download button gives you the template files that you can then start editing.
But why do you need to edit the files – they provide a complete (usually) description of the resource group. I have found that although the templates that are exported do represent the resource group, they do need to be whipped into shape if they are going to be reused. Firstly, the export process parameterizes everything. Most of these parameters are not normally things you’d want to change so it is better if they were converted to variables in the template. You might also want to derive the name of resources from other things, so the name of the resource group might be resources_rg and you want the public Ip to be named resources_ip and the network security group to be resources_nsg. Therefore, you’ll want one parameter and have the template construct the values for three variables. Secondly if your resource group contains 3 servers behind a load balancer the exported template will have three virtual machine configurations in it. If you want the number of servers in the template to be configurable then you’ll be back editing the template.
Once you start editing the file that is when your problems start. The only way to be sure that your template will work is by deploying it to Azure. The first type of problems you’ll encounter are syntactical errors in the form of malformed JSON. Incorporate a JSON validator into your workflow will minimise the amount of hair you’ll lose dealing with this type of problem. You can also upload the template into Azure via the Templates preview features. However, at the time of writing I didn’t feel that this offered much particularly as you have to copy and paste your template and/or edited it in place. Instead I choose to work on my templates in a richer text editor. Once I was happy with my changes I then test deployed it to an Azure subscription. Hold on, I have missed a step I have not explained how you deploy templates to Azure.
Luckily if you have exported the template from Azure you have already got everything you need to deploy the template using a number of languages. If you are using powershell you’ll find a deploy script called, deploy.ps1. it can be launched as follows:
.\Deploy.ps1 -subscriptionId <your_sub_id> -resourceGroupName <rg-to-be-created> -resourceGroupLocation <region> -deploymentName <name>
You can also deploy your efforts via the previously mentioned Templates Azure feature. You simply select the deploy option. However, this method doesn’t allow you to test whether your parameter file (if you have one), is applied correctly.
Finally, you could take a leaf out of Microsoft’s book by allowing any of your template you happen to have in GitHub to be invoke directly. If you add the following to your readme.md file you’ll get a nice little button that does just that.
<a href="https://portal.azure.com/#create/Microsoft.Template/uri/https%3A%2F%2Fraw.githubusercontent.com%2F<MyRepoUrl>%2Fazuredeploy.json" target="_blank"> <img src="http://azuredeploy.net/deploybutton.png"/> </a>
Again the downside is that it does not use a parameters file. I have also found that it is hard to get this method to target the correct subscription if you happen to have many.
What to do when things go wrong?
The Azure resource group model is pretty good at keeping you informed with ongoing deployments. If you click on the resource group that you are interested in within the portal, you’ll be able to see its deployment status on the summary screen. It will say whether there is a deployment in progress. It will also tell you if a deployment has failed. This is where to go to troubleshoot the inevitable problems you’ll have when designing and deploying your own templates.