Skip to main content

Tips for working with Azure Resource Manager (templates)

· 6 min read

Azure Resource Manager (ARM) provides you with the means to describe the infrastructure for your Azure applications. This includes storage accounts, virtual machines, Azure SQL databases and a lot more. On a project I'm working on we're using it to describe the layout of an Azure Service Fabric cluster but we decided to start using it for all resource groups.

The main reason why is that this is the only way to guarantee consistency between environments in Azure. We have a develop, acceptance and production environment and you want these to be as similar as possible. Using a parameterized ARM template, you can guarantee this.

Azure Resource Manager provides a form of desired state configuration. You describe what your infrastructure should look like and Azure Resource Manager makes it so. If you apply a change, Azure Resource Manager makes sure your infrastructure matches this change.

And now for some tips if you want to get started with ARM.

Tip 1: Download the automation template from the portal

The Azure portal provides a download link at the resource group level for the ARM template for that resource group, parameterized and all. The following screenshot tells you where to find it.

Download automation template

You can use this template directly for deployment to the resource group you just downloaded it from.

Tip 2: No need to create resources

It is often useful to create a resource in the portal to see what it will look like in a resulting ARM template. However, there is no need to actually create the resource. When you have configured your new resource, a VM for example, you can download an ARM template representing your new resource without actually creating it. In the screenshot below I have configured a new VM and in the confirmation page you see a download link.

Download template new resource

Tip 3: Use Azure Resource Explorer to check existing resources

Azure Resource Explorer provides a view on all the resources in your subscription(s). Every resource and related resources are presented as JSON documents that you can inspect and even modify. Here's a screenshot showing an Azure Storage account:

Azure resource explorer

There's already a lot to see here so I marked a few parts:

  1. By default, you can't change anything in resource explorer. To make changes to resources, you must explicitly enable Read/Write mode.

  2. This is the absolute url of your resource in Azure Resource Manager. As you can see, it follows a certain hierarchy: subscription resource group resource type name. All operations you can run on this resource use this url.

  3. Here you find PowerShell or Azure CLI scripts for working with this resource.

  4. All actions you can perform on the resource are found here. The screenshot represents an Azure Storage account so you could, for example, perform a POST to the following url to retrieve the primary and secondary access keys: https://management.azure.com/subscriptions/4c70a177-b978-43f9-9fc0-1e50dd20271f/resourceGroups/horses-for-courses/providers/Microsoft.Storage/storageAccounts/rwwildenml/listKeys?api-version=2017-06-01.

  5. The JSON representation of the resource itself (this is different for each resource type of course). In this case, you could change the SKU or configure VNet protection (recently announced).

    There are some additional properties here you could try to change like the blob endpoint but I never tried that. I don't think that will work.

Tip 4: Getting API version information

Every resource type you want to address via ARM has a list of supported API versions. These are always in the following format: yyyy-MM-dd with an optional -preview. For example: 2017-10-01 or 2015-05-01-preview.

How do you know what the supported API versions for a specific resource type are? You can ask the relevant resource provider either through PowerShell or through Azure CLI. I'll describe them both. In both cases I'd like to know the supported API versions for managing virtual networks via ARM.

Using PowerShell, you can run the following commands:

Login-AzureRmAccount
$networkRP = Get-AzureRmResourceProvider -ProviderNamespace "Microsoft.Network"
$networkRP.ResourceTypes | where { $_.ResourceTypeName -eq "virtualNetworks" }

The result should look like this:

VNET API versions

As you can see, we have a list of supported API versions and also the locations that support a specific resource type.

If you want to use Azure CLI, you can run the following script:

$ az login
$ az provider list --query \
"[?namespace=='Microsoft.Network'].resourceTypes[] | [?resourceType=='virtualNetworks'].apiVersions[]"
[
"2017-11-01",
"2017-10-01",
"2017-09-01",
"2017-08-01",
"2017-06-01",
"2017-04-01",
"2017-03-01",
"2016-12-01",
"2016-11-01",
"2016-10-01",
"2016-09-01",
"2016-08-01",
"2016-07-01",
"2016-06-01",
"2016-03-30",
"2015-06-15",
"2015-05-01-preview",
"2014-12-01-preview"
]

The az provider list command lists the details for all Azure Resource Providers as JSON. You can use JMESPath queries to extract results from this JSON.

Tip 5: Azure Resource Explorer (raw)

For some resources you can not use Azure Resource Explorer. If you want to go really low-level you can visit https://resources.azure.com/raw/. For example, for a customer we have an OMS (Log Analytics) workspace. This workspace has a number of data sources that you can not inspect in Azure Resource Explorer:

Azure resource explorer

Apparently you have to apply a filter and Resource Explorer does not support that. So let's turn to the raw version and see what we can do there:

Azure resource explorer raw

We can now do a GET request with the required kind parameter and we see all data sources of the performanceCounter kind.

Besides GET requests, you can also perform all the other operations on your resources: PUT, POST, DELETE and PATCH.

Tip 6: Non-exportable resources

Sometimes when you download an automation template (tip 1) you get a warning message stating that: resource types cannot be exported yet and are not included in the template.

Non-exportable resources

In this case, one of the resource types that can not be exported is Microsoft.KeyVault/vaults/accessPolicies. In my case, I would actually like these access policies to be part of the ARM template but we don't know what this should look like because they weren't exported. So what can we do?

There are several options:

  1. Check Azure Resource Explorer (tips 3 and 5). In the case of Key Vault access policies, we can easily find them there.
  2. Check the ARM template documentation. Information for Azure Key Vault can be found here.
  3. If both previous options do not provide an answer, you can also try checking out the Azure REST API. The syntax that describes resources is the same. And in case of Key Vault access policies, you can find information here.

Further tips...

Well, actually, that was it. Hope it helped :)