A typical Azure solution normally consists of many components (SQL Server, Active Directory, App Svc and so on) and involves provisioning these resources independently using Azure Service Management APIs or PowerShell scripts. By using ARM (Azure Resource Manager) templates you now have the ability to group all these resources together and use a declarative style template written in JSON to manage the deployment of your cloud services and any dependencies. Using the same template, provides the capability to deploy repeatedly into different environments throughout the application lifecycle with the same consistent results.
The benefits of using ARM templates are as follows:
Prebuilt templates are also community contributed and can form the basis to get you started by modifying an existing template that closely resembles your requirements. These templates are available from here: https://docs.microsoft.com/en-us/azure/azure-resource-manager/resource-group-overview.
The basic structure of an ARM template is made up of six elements and is similar to the code segment shown here:
{ "$schema": "http://schema.management.azure.com/schemas/2015-01- 01/deploymentTemplate.json#", "contentVersion": "", "parameters": { }, "variables": { }, "resources": [ ], "outputs": { } }
The following table describes the elements of the template in more detail:
Element name |
Description |
|
This is the location of the JSON schema file and is a mandatory value. The file sets the rules on how the template will be processed.
Typically, this value will be set to: https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json until MS publishes a later version.
|
|
The version of the template you are authoring and can be any value (for example, 1.0.0.0) and is a mandatory field. Use this to help you keep track of the template version between deployments. |
|
Provides the flexibility to collect user input for resource properties before starting the deployment. |
|
Variables are optional. They are used to simplify the template by reusing the same variable throughout the template. The value can be a simple data or a complex type such as another JSON object. Variables values can also be based on other values. |
|
This is a mandatory element, and it defines a collection of resources that you plan to deploy as a part of the template deployment. Note that at least one resource must be defined. |
|
This is used to return data or objects after a deployment. |
These elements are described in more detail in the following paragraphs.
The parameters elements specified in the ARM template are complex objects themselves. The structure of a parameter is as follows:
"parameters": { "<parameter-name>":{ "type" : "<type-of-parameter-value>", "defaultValue": "<default-value-of-parameter>", "allowedValues": [ "<array-of-allowed-values>" ], "minValue": <minimum-value-for-int>, "maxValue": <maximum-value-for-int>, "minLength": <minimum-length-for-string-or-array>, "maxLength": <maximum-length-for-string-or-array-parameters>, "metadata": { "description": "<description-of-the parameter>" } } }
Element name |
Required |
Description |
|
Yes |
The name of the parameter. |
|
Yes |
The data type of the parameter and can be any one of the following types:
|
|
No |
Default value of the input parameter if no value is provided. |
|
No |
An array list of allowed parameters to select from. |
|
No |
The minimum value for the "int" type parameters and this value is inclusive. |
|
No |
The maximum value for the "int" type parameters and this value is inclusive. |
|
No |
The minimum length for string, secureString, and array type parameters. This value is inclusive. |
|
No |
The maximum length for string, secureString, and array type parameters. This value is inclusive. |
|
No |
The description of the parameter which is displayed in the custom template interface on the portal. |
When you start to deploy the resources, you will be prompted for the input values of the parameters. You can also include the parameter values in another JSON file named templatename.params.json
. This will allow you to have multiple versions of the input values for different environments.
The variable elements are in the following form and are defined as a JSON key/value pair and must follow the standard JSON syntax:
"variables":{ "<variable-name>":"<variable-value>", "<variable-name>":{ <variable-complex-type-value> } }
The following is an example of two variables calling two different functions to obtain the resource group location and assigning a variable to a parameter. Functions are normally encapsulated in square brackets:
"location": "[resourceGroup().location]" "sbVersion": "[parameters('serviceBusApiVersion')]"
This defines the resource to be deployed or provisioned. The configuration information can either be defined directly in the resource definition or populated from variables and or parameter values:
"resources": [ { "apiVersion": "<api-version-of-resource>", "type": "<resource-provider-namespace/resource-type-name>", "name": "<name-of-the-resource>", "location": "<location-of-resource>", "tags": "<name-value-pairs-for-resource-tagging>", "comments": "<your-reference-notes>", "dependsOn": [ "<array-of-related-resource-names>" ], "properties": "<settings-for-the-resource>", "copy": { "name": "<name-of-copy-loop>", "count": "<number-of-iterations>" } "resources": [ "<array-of-child-resources>" ] } ]
The elements are described in more detail here:
Element name |
Required |
Description |
|
Yes |
The version of the REST API to use for creating the resource. |
|
Yes |
This a combination of the namespace and resource. |
|
Yes |
The name of the resource. The name must follow URI component restrictions defined in RFC3986. |
|
depends |
Supported geo-location for the resource. However, some types of resources do not require a location to be defined. |
|
No |
Tags that are associated with the resource. |
|
No |
User-defined notes. |
|
No |
ThedependsOnproperty is used to define dependencies among resources. |
|
No |
Specific configuration settings for the resource. It can be set directly or through variables or parameters. |
|
No |
The number of instances to create for a resource. |
|
No |
An array of child resources that depend on the resource being defined. |
The structure of the output element is defined as follows:
"outputs": { "<outputName>": { "type": "<datatype-of-output-value>", "value": "<output-value-expression>" } }
Element name |
Required |
Description |
|
yes |
The name of the output value. Must be a valid Javascript identifier. |
|
yes |
The datatype of the output value. Must be any one of the type listed here:
|
|
yes |
The expression that will be evaluated and returned, |
The output value can also be used to share state and data between nested template deployments.
Apart from the default elements described earlier, the template can also be extended using expressions and functions. When using functions, it should be enclosed in square brackets.
A full list of the available functions is available from here: https://docs.microsoft.com/en-in/azure/azure-resource-manager/resource-group-template-functions.
They are grouped in the following categories:
These are files used to populate the parameters specified in the ARM template, and they are useful when provisioning Azure resources for different environments or configuration settings:
{ "$schema": "https://schema.management.azure.com/schemas/2015-01- 01/deploymentParameters.json#", "contentVersion": "1.0.0.0", "parameters": { "<name-of-parameter>": { "value": "<value>" } } }
Element name |
Required |
Description |
|
yes |
The name of the parameters defined in the parameters section of the ARM template |
|
yes |
The value to be used for the parameter |
There are various options available when deploying these templates as listed here: