Introduction To Azure ARM Template

Introduction

 
ARM stands for Azure Resource Manager. We use ARM templates to deploy resources to Azure. We can automate deployments and use the infrastructure as code. In code, we define the infrastructure that needs to be deployed. The infrastructure code becomes part of our project. Just like the application code, we store the infrastructure code in a repository and version it. We go with this approach because anyone on the team can run the code and deploy similar environments.
 
To implement infrastructure as code for Azure solutions, we use Azure Resource Manager (ARM) templates. The template is a JSON file that defines the infrastructure and configuration. The template uses declarative syntax, which lets you deploy without having to write the sequence of programming commands to create it. In the template, we specify the resources to deploy and the properties for those resources.
 

Template file


The template has the following sections:

Parameters - We can provide values during deployment that allow the same template which can be used for different environments.

Variables - These are values that can be reused in templates and can be formed from parameter values.

User-defined functions - Create functions that simplify our template.

Resources - Resources that are to be deployed

Outputs - Return values from the deployed resources.
 
Below is a sample template file which creates a Storage Account, Azure App Service Plan & Web App 
  1. {    
  2.   "$schema""https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",    
  3.   "contentVersion""1.0.0.0",    
  4.   "parameters":{    
  5.     "storagePrefixForArm":{    
  6.         "type""string",    
  7.         "minLength": 3,    
  8.         "maxLength": 24    
  9.     },    
  10.       "appServicePlanName": {    
  11.           "type""string",    
  12.           "defaultValue""exampleplan1"    
  13.       },    
  14.       "location":{    
  15.         "type""string",    
  16.         "defaultValue""[resourceGroup().location]"    
  17.       },    
  18.        "webAppName": {    
  19.            "type""string",    
  20.            "metadata": {    
  21.                "description""web app name and app service plan "    
  22.            },    
  23.            "minLength": 2    
  24.        },    
  25.        "linuxFxVersion": {    
  26.            "type""string",    
  27.            "defaultValue""php|7.0",    
  28.            "metadata": {    
  29.                "description""Current Web App"    
  30.            }    
  31.        },    
  32.     "storageSKU":{    
  33.         "type":"string",    
  34.         "defaultValue""Standard_LRS",    
  35.         "allowedValues": [    
  36.               "Standard_LRS",    
  37.               "Standard_GRS",    
  38.               "Standard_RAGRS",    
  39.               "Standard_ZRS",    
  40.               "Premium_LRS",    
  41.               "Premium_ZRS",    
  42.               "Standard_GZRS",    
  43.               "Standard_RAGZRS"    
  44.         ]    
  45.     },    
  46.     "resourceTags": {    
  47.         "type""object",    
  48.         "defaultValue": {    
  49.             "Environment""Dev",    
  50.             "Project""ARMTemp"    
  51.         }    
  52.     }        
  53.   },    
  54.   "variables":{    
  55.       "uniqueStorageName":"[concat(parameters('storagePrefixForArm'),uniqueString(resourceGroup().id))]",    
  56.        "webAppPortalName""[concat(parameters('webAppName'), uniqueString(resourceGroup().id))]"    
  57.     
  58.   },    
  59.   "resources": [{    
  60.       "type""Microsoft.Storage/storageAccounts",    
  61.       "apiVersion""2019-04-01",    
  62.       "name""[variables('uniqueStorageName')]",    
  63.       "location""[parameters('location')]",    
  64.       "tags""[parameters('resourceTags')]",    
  65.       "sku": {    
  66.           "name""[parameters('storageSKU')]"    
  67.       },    
  68.       "kind""StorageV2",    
  69.       "properties": {    
  70.           "supportsHttpsTrafficOnly"true    
  71.       }    
  72.   }, {    
  73.       "type""Microsoft.Web/serverfarms",    
  74.       "apiVersion""2016-09-01",    
  75.       "name""[parameters('appServicePlanName')]",    
  76.       "location""[parameters('location')]",    
  77.       "sku": {    
  78.           "name""B1",    
  79.           "tier""Basic",    
  80.           "size""B1",    
  81.           "family""B",    
  82.           "capacity": 1    
  83.       },    
  84.       "kind""linux",    
  85.       "properties": {    
  86.           "perSiteScaling"false,    
  87.           "reserved"true,    
  88.           "targetWorkerCount": 0,    
  89.           "targetWorkerSizeId": 0    
  90.       }    
  91.   }, {    
  92.       "type""Microsoft.Web/sites",    
  93.       "apiVersion""2018-11-01",    
  94.       "name""[variables('webAppPortalName')]",    
  95.       "location""[parameters('location')]",    
  96.       "dependsOn": [    
  97.           "[resourceId('Microsoft.Web/serverfarms', parameters('appServicePlanName'))]"    
  98.       ],    
  99.       "kind""app",    
  100.       "properties": {    
  101.           "serverFarmId""[resourceId('Microsoft.Web/serverfarms', parameters('appServicePlanName'))]",    
  102.           "siteConfig": {    
  103.               "linuxFxVersion""[parameters('linuxFxVersion')]"    
  104.           }    
  105.       }    
  106.   }],    
  107.   "outputs": {    
  108.       "storageEndpoint": {    
  109.           "type""object",    
  110.           "value""[reference(variables('uniqueStorageName')).primaryEndpoints]"    
  111.       }    
  112.   }    
  113. }  
Let's take a deep dive into the template file on each section.  
 

Schema and ContentVersion

 
$schema
 
Specifies the location of the JSON schema file. The schema file describes the properties that are available within a template.

contentVersion
 
Specifies the version of the template you are creating and value is used for versioning for the significant changes of your template.
  1. "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
  2. "contentVersion": "1.0.0.0",

Resources

 
This section specifies the resources which you are deploying. In the below example we are creating an Azure Storage account using ARM Template.
 
type refers to the Azure Resource which we are creating, which in the below example is "Microsoft.Storage/storageAccounts"
 
apiVersion refers to the REST API version which we are using to create the Azure resource using the ARM Template and apiVersion is specific to the azure resource we are creating.
 
location
 
location refers to the location we want to create the Azure resource.(Central US or Central India)
 
The other properties are specific to the resource which we are creating. If we consider Azure Storage Account we have kind and properties:
  1. "resources": [{      
  2.       "type""Microsoft.Storage/storageAccounts",      
  3.       "apiVersion""2019-04-01",      
  4.       "name""[variables('uniqueStorageName')]",      
  5.       "location""[parameters('location')]",      
  6.       "tags""[parameters('resourceTags')]",      
  7.       "sku": {      
  8.           "name""[parameters('storageSKU')]"      
  9.       },      
  10.       "kind""StorageV2",      
  11.       "properties": {      
  12.           "supportsHttpsTrafficOnly"true      
  13.       }      
  14.   }]  

Parameters

 
These are the i/p values that can be provided while executing the arm template. Parameters help us to provide values at runtime and help us in reusing the arm template for many purposes.
 
Below are the parameters which are defined in the arm template. If we consider storagePrefix it has type(dataType), minLength and maxLength properties. Similarly, we can use defaultValue property for assigning the default value when no value is not supplied at run time.
 
We can also use some predefined template functions in the parameters. For example if we consider location parameter it has defaultValue which is [resourceGroup().location], which means we have to create the storage account in the same location as the azure resource group. We call these functions as template functions.
 
We also have allowedValues property which is used to provide only the values from the set of values. At runtime, if a value is provided which is not from allowedValues, an exception will raise.
  1. "parameters":{      
  2.     "storagePrefixForArm":{      
  3.         "type""string",      
  4.         "minLength": 3,      
  5.         "maxLength": 24      
  6.     },      
  7.       "appServicePlanName": {      
  8.           "type""string",      
  9.           "defaultValue""exampleplan1"      
  10.       },      
  11.       "location":{      
  12.         "type""string",      
  13.         "defaultValue""[resourceGroup().location]"      
  14.       },                          
  15.     "storageSKU":{      
  16.         "type":"string",      
  17.         "defaultValue""Standard_LRS",      
  18.         "allowedValues": [      
  19.               "Standard_LRS",      
  20.               "Standard_GRS",      
  21.               "Standard_RAGRS",      
  22.               "Standard_ZRS",      
  23.               "Premium_LRS",      
  24.               "Premium_ZRS",      
  25.               "Standard_GZRS",      
  26.               "Standard_RAGZRS"      
  27.         ]      
  28.     }  
  29. }  
Now let's see how to retrieve values from the parameters and use them in the resources objects. We can use the parameters function by sending the parameter name to access the parameter value.
  1. "location": "[parameters('location')]",

Variables

 
We can use variables to reuse the values within the ARM Template. We define the Variables section below. We add the variables section by defining the variable and value. If we consider the below example we are creating a uniqueStorageName by accessing the parameter storagePrefix value and uniqueString function which generates a 13 character unique string from the resource group id we are using.
  1. "variables":{
  2. "uniqueStorageName":"[concat(parameters('storagePrefix'),uniqueString(resourceGroup().id))]",
  3. "webAppPortalName": "[concat(parameters('webAppName'), uniqueString(resourceGroup().id))]"
  4. }
We can access the variables similarly as the parameters.
  1. "name": "[variables('uniqueStorageName')]"
Outputs
 
Outputs are the values of the deployed resource. We use outputs when you need a value from a deployed resource.
 
In the below example, the return type is an object and we are using template function reference to get the runtime state of the deployed Azure resource by passing the name of the deployed resource. In the below example we are getting primaryEndpoints of the storage account.
  1. "outputs": {
  2.    "storageEndpoint": {
  3.          "type": "object",
  4.          "value": "[reference(variables('uniqueStorageName')).primaryEndpoints]"
  5.       }
  6. }
Tags
 
We can add the tags to the Azure resource. We are creating by defining the tags in the parameters section and then using the value of the parameter in the resource template.
  1. "resourceTags": {
  2.    "type": "object",
  3.    "defaultValue": {
  4.       "Environment": "Dev",
  5.       "Project": "Tutorial"
  6.    }
  7. }
Defining tags property for the resource:
  1. "tags": "[parameters('resourceTags')]",
We can deploy the arm template from azure CLI cmd prompt. Upload the arm.json file to azure cloud shell and execute the below command for execution.
 
 
If we check the Azure resource group and deployment tab we can see the arm template with template name.
 
 
That's it from this article, please provide your feedback.