Getting started with ARM templates. In most cases, if you are working exclusively with Azure and want to adopt Infrastructure as Code (IaC). Then using Azure Resource Manager (ARM) Templates and Azure DevOps is the natural choice. But getting started with ARM templates can take some time. With this in mind, we have created this series of articles to help you in getting started. Overall these articles will cover the basics of getting starting with ARM templates. Including what they are and how to use them. And finally, how to integrate them into a CI/CD pipeline in Azure DevOps.

Getting started with ARM templates – Before you get started

What is Azure Resource Manager?

Azure Resource Manager (ARM) is accessible via a REST API and is the central point for managing Azure resources. Consequently, it receives requests sent from the Azure Portal, Azure PowerShell, Azure CLI and Rest clients. Authenticates them then sends them to Azure Service to perform the requested action. ARM allows you to deploy several resources together as a single unit and make deployments idempotent. Importantly, the ARM architecture is resilient, continuously available and never taken down for maintenance.

azure resource manager

What are ARM Templates?

ARM Templates are JavaScript Object Notation (JSON) files that describe the resources that you want to create in Azure. Including their type, name and properties. The templates use a declarative syntax. Which means you simply state what you intend to deploy rather than having commands that create the resources. The ARM Templates are actually our IaC i.e. the artifacts that we store in source repository and version. In other words, the ARM Templates describe the infrastructure objects you want and the Azure Resource Manager creates the objects for you. Including handling any orchestration and deployment order of resources.

So what does an ARM Template look like?

In this section we will look at the structure and elements of an ARM template.

    1. $schema (required): location of the schema file that describes the version for the template language.
    2. contentVersion (required): version number that you assign to the template.
    3. apiProfile (not required): API version to use for resources in the template.
    4. parameters (not required): values to be used at deployment time to customise resources.
    5. variables (not required): values to be used as JSON fragments to simplify expressions.
    6. functions (not required): user-defined functions. In other words, these are functions that you create.
    7. resources (required): resources to be deployed or updated in Azure. Consequently, this is main part of an ARM template.
    8. outputs (not required): values to be returned after the deployment.

In addition, you can learn more about these elements here.

.

arm template structure

Getting started with ARM templates – What can you do with ARM templates

Use Parameters to Customise Resources

Provide parameters to customise your resources and configuration for different environments. After defining the parameters in your template file you can pass parameters as inline values. Or use a JSON file that contains the values to your parameters.

Generally, the template and parameter files use the following naming standards; azuredeploy.json and azuredeploy.parameters.json.

 

Use Different Deployment Modes

You can use different deployment modes. So when deploying templates you can specify either an incremental or complete update using the deployment mode setting. Incremental mode adds the resources in the template or modifies resources that are already deployed. Conversely, complete mode removes any resources that are not in the template.

The default mode is Incremental. Subscription level deployments do not support complete mode deployments.

 

Make Deployments Modular

You can use singular or modular deployments, through nested or linked templates. For instance, to make templates easier to understand and manage you can break them up into smaller pieces. By either using separate template files linked together with a main template file (linked templates) or by embedding templates into the main template file (nested templates).

In spite of it being easier to understand and maintain a single template file, linked templates give us the ability to reuse templates for different scenarios. Thus single templates are better suited to small to medium deployments.

 

Deploy Resource to Different Scopes

Resources within Azure are arranged in a hierarchical structure known as scopes i.e. Tenant, Management Group, Subscription and Resource Group. So you can use ARM templates to deploy your resources at different scopes.

 

Deploy Resources Based on Conditions

In addition ARM templates allow us to perform conditional deployment of resources. Because some resources may only need to be deployed under certain conditions. For example, you may want your template to be able to have the option of using an existing resource or creating a new resource. The condition element allows us to do this by specifying a true (create) or false (don’t create) value.

 

Set Resource Dependencies

By default Azure Resource Manager deploys resources in parallel. For this reason, ARM templates allow you to define dependencies between resources and change the order in which resources are deployed.
Consequently, we can use the dependsOn element to define any dependencies that our resources have. For example, if you are trying to deploy an Azure API Management instance and configure it to use Application Insights, we would first need to create our Application Insight resource first.

 

Deploy Multiple Instances of Resources

In addition, you can also use ARM templates to create multiple instances of resources. In this case, you can use the copy element to deploy multiple instances of resources and avoid duplicating the template syntax for that resource.

However, there are some limitations when it comes to using the copy element in nested templates. See Iteration for a child resource in this link.

 

Create User-Defined Functions

Also, ARM templates give you the ability to create your own user-defined functions with your templates. As a result, you have an easy way to repeatedly use complicated expressions in your templates. For example, you might want to use a function to create a naming standard for your resources.

ARM templates are for deploying Azure resources

ARM Templates are only designed to deploy Azure resources. For this reason, you will need to use an alternate technology like PowerShell (or PowerShell DSC) or to deploy your applications onto these resources.

Importantly, ARM Templates are only for deploying resources, not the code that runs on these resources.

What are some ARM Template Best Practices?

This section covers some of the best practices to keep in mind when we’re working with ARM Templates.

 

  • Keep template sizes to 4 MB and parameter files to 64KB
  • Use variables instead of parameters i.e. parameters should be used by variables and resources should use variables.
  • Provide default values (except username and password or secrets) and descriptions for parameters.
  • Always use parameters for username and passwords or secrets.
  • Use securestring (string) or secureObject (JSON) for all passwords or secrets.
  • Specify comments for each resource in the template to help others understand the purpose of the resource.
  • Use a parameter to specify the location for resources, and set the default value to resourceGroup().location.

To conclude

In this article you have learned some of the basics of ARM templates. Including,

  • What Azure Resource Manager and Azure Resource Manager templates are
  • How you can use ARM templates to deploy your resources in Azure
  • A few best practices to keep in mind when using ARM templates

Now that you have some of the basics covered. You are ready to look at how we can use ARM templates to deploy our resources in Azure.

Thank you for reading. We hope that this article has help you in getting started with ARM templates.

 

 

Keith Jenneke

Keith Jenneke

Managing Director | DevOps & Cloud Lead