Build ARM Templates to Simplify Deployments

March 07, 2018

One of the first Azure-specific projects I worked on was a script to create all of the resources needed to run our application. It used the Azure Powershell module to build those resources and then deploy the application. That script saved a lot of time but it was error prone and a headache to modify. Just a few months later Azure Resource Manager (or ARM) templates were introduced. They’re a lot simpler to build and use than writing a script from scratch. Because they’re such a vital resource, I wanted to write a very high level overview of how to build ARM templates and ways to deploy them.

What are ARM templates?

ARM templates are just JSON files that declare a group of Azure resources. For example, a template for a basic web app might include an Azure Web App, an SQL database, and a blob storage account. A more complex template might have tons of VMs separated into different subnets including very fine-grained network security group rules. Both are possible. Using templates makes it so those resources can be spun up over and over again across resource groups or even subscriptions. In fact, if you’ve ever deployed something from the Azure Marketplace you’ve already deployed an ARM template. Every item in the marketplace is just an ARM template that some 3rd party has published.

Templates can also help you parameterize deployments. They let you define parameters that must be provided at deploy time that are then used in the template to configure resources. A simple use for this would be naming resources. A “name” parameter would tack on a prefix to every resource. Another common one is letting the user select which SKU (pricing tier) of a particular service to use at deployment.

Here’s an example of a ARM template for a web app. If I was to run this deployment I would have to specify a name and the App Service tier in order for it to work.

{
"$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"SiteName": {
"type": "string"
},
"AppServicePlanSku": {
"type": "string",
"allowedValues": [
"F1",
"S1",
"P1"
]
}
},
"variables": {
"appServicePlanName": "[concat(parameters('SiteName'), '-AppServicePlan')]",
"siteName": "[parameters('SiteName')]"
},
"resources": [
{
"type": "Microsoft.Web/serverfarms",
"sku": {
"name": "[parameters('AppServicePlanSku')]"
},
"kind": "app",
"name": "[variables('appServicePlanName')]",
"apiVersion": "2016-09-01",
"location": "[resourceGroup().location]",
"scale": null,
"properties": { },
"dependsOn": []
},
{
"type": "Microsoft.Web/sites",
"kind": "app",
"name": "[variables('siteName')]",
"apiVersion": "2016-08-01",
"location": "[resourceGroup().location]",
"scale": null,
"properties": {
"serverFarmId": "[resourceId('Microsoft.Web/serverfarms', variables('appServicePlanName'))]"
},
"dependsOn": [
"[resourceId('Microsoft.Web/serverfarms', variables('appServicePlanName'))]"
]
}
]
}
view raw template.json hosted with ❤ by GitHub

How do I build ARM templates?

Since templates are just JSON files you can build them from scratch using any text editor. There are extensions for Visual Studio and VS Code that include some nice tools for building them. Also, there are tons of quickstarts on Github to help get you started.

Another option is to create the resources you need and then export a template through the portal. This is a great starting point but in my experience you’ll almost certainly have to edit the template before it will work. I’ve had times where a straight exported template includes circular references between resources or unnecessary parameters that cause it to fail at deploy time.

If you’re a visual person another great resource is ARMVIZ. It lets you load in a template and view a diagram of all the different resources.

How do I deploy an ARM template?

There are several options for deploying templates too. Visual Studio has right-click->Publish support on it’s Resource Group project type. Another option (and what I do) is to upload them to your Cloud Shell storage or any publicly accessible URL (such as Github). Then you can use the Azure CLI to deploy.

To deploy using the CLI you just need to create a resource group and then you can create a deployment. There are command line arguments for the template path and parameters file. If you don’t specify a parameters file it will prompt you for the values before deploying.

az group create -n my-deployment-test -l westus2
az group deployment create -g my-deployment-test \
--template-uri https://raw.githubusercontent.com/jessebarocio/soa-arm-templates/master/basic-webapp/template.json
view raw cli.sh hosted with ❤ by GitHub

Building declarative ARM templates is much better than writing a procedural deployment script. How are you using ARM templates? Let me know in the comments.


© 2020 Jesse Barocio. Built with Gatsby