Understanding ARM templates – Scripted Deployments and DevOps Automation-1

Just as other tools are simply wrappers for the Azure REST APIs, everything that is built in Azure is defined as an ARM template. Whether you create a service through the Azure portal, PowerShell, REST APIs, or the CLI, ultimately that service is described within an ARM template.

An ARM template is a JSON-based text file and is broken down into the following sections:

  • A header containing $schema, contentVersion, and metadata: As an evolving platform, Microsoft is continually adding new components and adding new capabilities to existing components. For this reason, an ARM template contains information that states the schema and version.
  • parameters: ARM templates can be built to be re-usable by allowing you to define and pass in parameters. These are then added either as a separate parameters file, as command-line arguments, or, when deploying a template within the Azure portal, a parameters form.
  • variables: The variables section enables you to define expressions that can be used throughout the rest of the template. For example, they can be used to generate names or other values.
  • functions: There are a number of different built-in functions that can be used, or you can define your own in the functions section. This is useful for building complex logic that needs to be re-used elsewhere.
  • resources: The resources section contains the details of the component you wish to deploy and allows you to set the different configuration elements. Each configuration setting can either be hardcoded, used as a supplied parameter, or a computed variable.
  • outputs: This is useful for chaining multiple templates together. For example, you can capture the Id value of the component you have created in one template and pass that to another.

Microsoft also provides a catalog of quickstart templates on GitHub at https://github.com/Azure/azure-quickstart-templates.

An example template that creates a storage account can be found in the preceding repository under 101-storage-account-create:

{
“$schema”: “https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#”,
“contentVersion”: “1.0.0.0”,
“parameters”: {
“storageAccountType”: {
“type”: “string”,
“defaultValue”: “Standard_LRS”,
“allowedValues”: [
“Standard_LRS”,
“Standard_GRS”,
“Standard_ZRS”,
“Premium_LRS”
],
“metadata”: {
“description”: “Storage Account type”
}
},
“location”: {
“type”: “string”,
“defaultValue”: “[resourceGroup().location]”,
“metadata”: {
“description”: “Location for all resources.”
}
}
},
“variables”: {
“storageAccountName”: “[concat(‘store’, uniquestring(resourceGroup().id))]”
},
“resources”: [
{
“type”: “Microsoft.Storage/storageAccounts”,
“apiVersion”: “2019-06-01”,
“name”: “[variables(‘storageAccountName’)]”,
“location”: “[parameters(‘location’)]”,
“sku”: {
“name”: “[parameters(‘storageAccountType’)]”
},
“kind”: “StorageV2”,
“properties”: {}
}
],
“outputs”: {
“storageAccountName”: {
“type”: “string”,
“value”: “[variables(‘storageAccountName’)]”
}
}
}

Templates can contain individual components, as in the preceding example, or they can contain multiple components. ARM templates for defining VMs, for example, contain resource definitions for the VM itself, network interfaces, storage accounts, and virtual networks.

In complex templates such as a VM, resources can state whether they have a dependency on others within the template. Again, in the VM example, there is a requirement for an Azure Virtual Network (VNET) to exist. By stating the VNET as a dependency, the platform will ensure this is created before the VM.

You can also link templates, calling one template from within another. This is known as nested templates and allows you to decompose your deployments into individual components but still maintain a cohesive deployment.

Using functions, you can create logic within your templates to automatically generate values based on provided inputs. A common example is the concat function, which is used to combine two strings.

Leave a Reply

Your email address will not be published. Required fields are marked *