Azure Resource Manager Templates 101

Azure has moved towards the resource manager (ARM) model for all new versions. Both the new portal and AzureRM PowerShell use ARM. The templates are based on JSON (JavaScript Object Notation) and allow for incremental and idempotent deployments, so when an error occurs, you can fix and re-deploy without affecting existing resources.

Using a simple JSON file, you can deploy any number of resources into a resource group. The simplest version of such a file is the following. Note that Microsoft Docs actually leaves out the contentVersion parameter, which is required:

title: Empty Azure Resource Manager Template
{
  "$schema": "http://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
  "contentVersion": "1.0.0.0",
  "parameters": {},
  "variables": {},
  "resources": [],
  "outputs": {}
}

There are five properties you can edit. Required properties are contentVersion, resources, and $schema.

  • contentVersion: Use to distinguish different versions of the template.
  • parameters: Contains questions the user has to answer when deploying the file.
  • variables: Are re-usable JSON fragments.
  • resources: Contains the collection of resources you want to deploy.
  • outputs: Passes data back to a parent file when executing a hierarchy of template files.

Deploying the File

ARM templates are deployed into a resource group. You may want to create one for testing purposes, which you can delete afterward:

New-AzureRmResourceGroup -Name Demo -Location "West Europe"

Deleting a resource group will delete all resources it contains, not only those you deploy via the script:

Remove-AzureRmResourceGroup -Name Demo

Next, you can validate the template file:

Test-AzureRmResourceGroupDeployment -ResourceGroupName Demo -TemplateFile demo.json

Then deploy the file to the specific Azure resource group:

New-AzureRmResourceGroupDeployment -Name DemoDeployment -ResourceGroupName Demo -TemplateFile demo.json

Instead of -TemplateFile, you can also use -TemplateUri and provide a URI to the file.

Visualizing the File

Microsoft is developing an online editor and visualizer for ARM templates at armviz.io. It’s still in its infancy at the time of writing.

Checking the Deployment Status

Depending on the size of your file, the deployment may take a while to complete. For any deployment, you can check the status for the resource group:

Get-AzureRmResourceGroupDeployment -ResourceGroupName Demo

Declaring Parameters

Templates may contain parameters. You can deploy a parameters file when deploying. The user must enter any missing parameters, or if you execute without a parameters file, all parameters. The basic format of parameters is as follows:

"parameters": {
  "<parameter-name>": {
    "type": "<type-of-parameter-value>"
  }
}
  • Types: Available types are string, int, bool, object, and array.

To hide sensitive values (e.g., passwords), use secure variants. The deployment mechanism uses these values and discards them afterward.

Declaring Variables

Variables can be simple strings or JSON fragments:

"variables": {
  "location": "West Europe",
  "customerSettings": {
    "default": {
      "instances": 1
    },
    "acme": {
      "instances": 4
    }
  }
}

Using Variables, Parameters, and Formulas

The deployment engine interprets values in square brackets. These can contain formulas. Examples:

  • Using a variable value:
"propertyX": "[variables('location')]"
  • Using parameters:
"propertyX": "[parameters('key')]"
  • Using functions:
"propertyX": "[substring(variables('location'), 0, 4)]"

Special methods like resourceGroup() return a JSON object:

"variables": {
  "location": "[resourceGroup().location]"
}

Creating Resources

In the resources section, you define the resources. Each resource depends on the resource type you’re targeting. Example:

"resources": [
  {
    "type": "Microsoft.Storage/storageAccounts",
    "apiVersion": "2015-06-15",
    "name": "demostorage",
    "location": "[resourceGroup().location]",
    "properties": {
      "accountType": "Standard_LRS"
    }
  }
]

Use properties like tags and comments for easier management:

"tags": {
  "environment": "test",
  "team": "Web"
},
"comments": "your deployment comment"

Define dependencies and relationships using dependsOn or child resources under resources:

"dependsOn": [
  "demostorage1",
  "website1"
]

Microsoft provides a GitHub repository of example resource templates.

Editing with Visual Studio

After installing the Azure SDK, you can create an “Azure Resource Group” project in Visual Studio. This provides the JSON Outline editor with a wizard for adding most resource types.

Naming Resources

Follow these guidelines for naming resources:

  1. Use a short (3-4 letters) prefix for the organization.
    ACME
    
  2. Distinguish between production and other resources.
    ACME-PROD and ACME-DEV
    
  3. Append the resource type for clarity.
    ACME-PROD-AS (AppService), ACME-PROD-VM (Virtual Machine)
    
  4. Add a short system name where applicable.
    ACME-PROD-AS-HMPG
    
  5. For international resources, add a data center suffix.
    ACME-PROD-AS-HMPG-EU, ACME-PROD-SQL1-EU