Demystifying ARM Templates (Azure Resource Manager)
Tags: azureapril, azure, devops, tutorial
Published: 2019-04-07 18:37:33

---
title: Demystifying ARM Templates (Azure Resource Manager)
published: true
description: Dig into everything ARM Templates in Azure. Static or custom, we've got you covered. 
tags: azureapril, azure, devops, tutorial
series: Azure April
cover_image: https://thepracticaldev.s3.amazonaws.com/i/pblyvmtj4y8bdqisyzey.jpeg
---

*We've selected our favorite tips and tricks created by [Michael Crump](https://twitter.com/mbcrump) and are delivering fresh technical content on Azure all April! Miss a day (or more)? [Catch up with the series](https://dev.to/t/azureapril).*

**Don't have Azure?** [Grab a free subscription](https://azure.microsoft.com/en-us/free?&WT.mc_id=azureapril_devto-blog-cxa). 

----

If you've been in tech long enough, you might associate ARM with CPU architecture. In this case, ARM stands for [Azure Resource Manager](https://docs.microsoft.com/en-us/azure/azure-resource-manager/resource-group-overview?WT.mc_id=azureapril_devto-blog-cxa). ARM is how you organize all your stuff on Azure — virtual machines (VMs), databases, storage accounts, containers, web apps, bots and more. 

> In Azure, we call ALL your stuff resources.

![portal](https://microsoft.github.io/AzureTipsAndTricks/files/resources_page.PNG)

Most people tend to create multiple related items together in Azure. A web app and a database might be contained in a single resource group. But what if you had to do this all the time? Or for many different clients? 

Wouldn’t it be nice to have an easy way to keep track of all the repeatable groups of resources you are creating for people? Good news, this is exactly what [ARM templates](https://docs.microsoft.com/en-us/azure/azure-resource-manager/resource-group-overview?WT.mc_id=azureapril_devto-blog-cxa) do!

**Want more ARM Templates?** Check out our [overview](https://docs.microsoft.com/en-us/azure/azure-resource-manager/resource-group-overview?WT.mc_id=azureapril_devto-blog-cxa)!


# Real Scenarios for ARM Templates

When you need an easy way to repeat infrastructure deployments on Azure, ARM templates are going to save you a lot of time. 

If you ever need to share your infrastructure with other people — such as opensource projects or for blogs, tutorials and documentation — ARM templates will be a lifesaver and will let your readers and users replicate what you did. 

Finally, if you just need a way to keep track of what you deployed on Azure, ARM templates are a great way to help you remember.


# It's Just a JSON File

This is where ARM templates come in. ARM templates are JSON files that act like blueprints for the related resources you want to deploy together. You’ll also hear this called “infrastructure as code,” or IaC, which is geek-speak for being able to upload your infrastructure notes to GitHub if you want to. 

It’s a structured format for keeping track of your Azure infrastructure with some superpowers. The biggest ARM template superpower is that you can use templates to automate your infrastructure deployments because Azure knows how to read them. After all, it's really just a JSON file. 

In the example below, we are creating an ARM template that creates a Notification Hub. You'll see that it contains things that the deployment needs such as `Name`, `Location`, etc.


```
{
    "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json",
    "contentVersion": "1.0.0.0",
    "parameters": {
        "namespaceName": {
            "type": "string",
            "metadata": {
                "description": "The name of the Notification Hubs namespace."
            }
        },
        "location": {
            "type": "string",
            "defaultValue": "[resourceGroup().location]",
            "metadata": {
                "description": "The location in which the Notification Hubs resources should be deployed."
            }
        }
    },
    "variables": {
        "hubName": "MyHub"
    },
    "resources": [
        {
            "apiVersion": "2014-09-01",
            "name": "[parameters('namespaceName')]",
            "type": "Microsoft.NotificationHubs/namespaces",
            "location": "[parameters('location')]",
            "kind": "NotificationHub",
            "resources": [
                {
                    "name": "[concat(parameters('namespaceName'), '/', variables('hubName'))]",
                    "apiVersion": "2014-09-01",
                    "type": "Microsoft.NotificationHubs/namespaces/notificationHubs",
                    "location": "[parameters('location')]",
                    "dependsOn": [
                        "[parameters('namespaceName')]"
                    ]
                }
            ]
        }
    ]
}
```


# Getting Started

You can make an ARM template in [Visual Studio](https://docs.microsoft.com/en-us/azure/azure-resource-manager/vs-azure-tools-resource-groups-deployment-projects-create-deploy?&WT.mc_id=azureapril_devto-blog-cxa), in [VSCode](https://docs.microsoft.com/en-us/azure/azure-resource-manager/resource-manager-quickstart-create-templates-use-visual-studio-code?tabs=CLI?&WT.mc_id=azureapril_devto-blog-cxa), or in the [Azure portal](https://docs.microsoft.com/en-us/azure/azure-resource-manager/resource-manager-quickstart-create-templates-use-the-portal?&WT.mc_id=azureapril_devto-blog-cxa). 

The last way is probably the easiest since it walks you through the process. Start creating a resource through the portal the way you normally would, by clicking on `Create Resource` on your Azure Portal dashboard. 

Now select what you'd like to create. I'm going to create a Web App. Look at the bottom of this page and you'll see automation options.

![options](https://microsoft.github.io/AzureTipsAndTricks/files/new_webapp.png)

But what does that unassuming link labeled `Automation options` next to it do? You’ve probably never noticed it before or been afraid to mess with it, but if you click on that link, you will be on the road to creating an ARM template for your resource. 


# Taking It One Step Further

Go ahead and click `Create a resource` inside the Azure Portal and select `Web App`.

Enter a `Name` and a `Resource Group` for your web app and click `Automation options` at the bottom before you hit `Create` in order to start creating your ARM template.

![ARM template](https://microsoft.github.io/AzureTipsAndTricks/files/new_webapp.png)

After you click `Automation options`, you'll see something like this:

![automation options](https://microsoft.github.io/AzureTipsAndTricks/files/arm_template.png)

The template to create a web app (or any other Azure resource) is simply a JSON file with multiple values describing how your web app is going to be deployed. Once you overcome the fancy jargon, it's pretty simple. And we make it easy for you to get started without speaking fluent JSON. 


# Creating Static App Settings for your [Azure App Service](https://azure.microsoft.com/en-us/services/app-service/)

To make things as easy as possible, let’s assume for now that you want to add the exact same settings every time you deploy your web app template.

Go to `Deploy` then `Edit Template` and paste the following settings fragment to overwrite your template’s resource section. (You could, of course, add as many keys as your web app needs or make changes as you see fit.)

> We are adding three names and 3 values for `MyFirstName`, `MyLastName`, and `MySSN`.

```
  "resources": [
  {
    "apiVersion": "2016-03-01",
    "name": "[parameters('name')]",
    "type": "Microsoft.Web/sites",
    "properties": {
        "name": "[parameters('name')]",
        "siteConfig": {
            "appSettings": [
            {
              "name": "MyFirstName",
              "value": "Michael"
            },
            {
              "name": "MyLastName",
              "value": "Crump"
            },
            {
              "name": "MySSN",
              "value": "355-643-3356"
            }
          ]
        },
        "serverFarmId": "[concat('/subscriptions/', parameters('subscriptionId'),'/resourcegroups/', parameters('serverFarmResourceGroup'), '/providers/Microsoft.Web/serverfarms/', parameters('hostingPlanName'))]",
        "hostingEnvironment": "[parameters('hostingEnvironment')]"
    },
    "location": "[parameters('location')]"
  }],
```

Press `Save.` Ensure the settings are filled out. Agree to the terms and check the `Purchase` option.

![template settings](https://microsoft.github.io/AzureTipsAndTricks/files/customdeployment.png)

> If it says failure to deploy, then give it a shot again. Sometimes an asynchronous return is the only hiccup. 

Your settings (for `MyFirstName`, `MyLastName`, and `MySSN`) will now be deployed.

After deployment, navigate to your `App Service` and go to `Application Settings`. You'll see your site deployed along with the settings that we specified earlier.

![application settings](https://microsoft.github.io/AzureTipsAndTricks/files/create_resource1.png)

Now let's look at adding parameters. 

# Inputting Values Before Deployment

You’ve already seen that you can automate deploying static configuration information like app settings with your ARM template. But what about providing parameters that allow end-users to input values BEFORE deployment. 

Go ahead and search for `templates` inside the Azure Portal and click `Add` to create a new one.

Enter a name and a description on the ARM Template.

![enter name](https://microsoft.github.io/AzureTipsAndTricks/files/customdeploy5.png)

# Choose Your Own Adventure 

We want to have dynamic settings that are customizable every time you deploy your web app instead of having them be the same each time, you just need to add the parameter values for what you want to your ARM template.

Below is a sample of three values (`FirstNameValue`, `LastNameValue` and `SSNValue`) that we previously hardcoded before:

```
"FirstNameValue": {
    "type": "string"
},
"LastNameValue": {
    "type": "string"
},
"SSNValue": {
    "type": "string"
},
```

We'll add the same parameters called `FirstNameValue`, `LastNameValue` and `SSNValue` to the parameters collection of the template. From now on, every time you deploy this template, you will be prompted to enter a value for each one.

```
"siteConfig": {
    "appSettings": [
        {
            "name": "MyFirstName",
            "value": "[parameters('FirstNameValue')]"
        },
        {
            "name": "MyLastName",
            "value": "[parameters('LastNameValue')]"
        },
        {
            "name": "MySSN",
            "value": "[parameters('SSNValue')]"
        }
    ]
}
```


# Stringing Everything Together

Our full template file looks like the following:

```
{
    "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
    "contentVersion": "1.0.0.0",
    "parameters": {
        "appServiceName": {
            "type": "string",
            "minLength": 1,
            "maxLength": 10
        },
        "appServicePlanName": {
            "type": "string",
            "minLength": 1
        },
        "FirstNameValue": {
                "type": "string"
            },
            "LastNameValue": {
                "type": "string"
            },
            "SSNValue": {
                "type": "string"
            },
        "appServicePlanSkuName": {
            "type": "string",
            "defaultValue": "S1",
            "allowedValues": [
                "F1",
                "D1",
                "B1",
                "B2",
                "B3",
                "S1",
                "S2",
                "S3",
                "P1",
                "P2",
                "P3",
                "P4"
            ],
            "metadata": {
                "description": "Describes plan's pricing tier and capacity. Check details at https://azure.microsoft.com/en-us/pricing/details/app-service/"
            }
        }
    },
    "variables": {
        "appHostingPlanNameVar": "[concat(parameters('appServicePlanName'),'-apps')]"
    },
    "resources": [
        {
            "name": "[variables('appHostingPlanNameVar')]",
            "type": "Microsoft.Web/serverfarms",
            "location": "[resourceGroup().location]",
            "apiVersion": "2015-08-01",
            "sku": {
                "name": "[parameters('appServicePlanSkuName')]"
            },
            "dependsOn": [],
            "tags": {
                "displayName": "appServicePlan"
            },
            "properties": {
                "name": "[variables('appHostingPlanNameVar')]",
                "numberOfWorkers": 1
            }
        },
        {
            "name": "[parameters('appServiceName')]",
            "type": "Microsoft.Web/sites",
            "location": "[resourceGroup().location]",
            "apiVersion": "2015-08-01",
            "dependsOn": [
                "[resourceId('Microsoft.Web/serverfarms', variables('appHostingPlanNameVar'))]"
            ],
            "tags": {
                "[concat('hidden-related:', resourceId('Microsoft.Web/serverfarms', variables('appHostingPlanNameVar')))]": "Resource",
                "displayName": "webApp"
            },
            "properties": {
                "name": "[parameters('appServiceName')]",
                "serverFarmId": "[resourceId('Microsoft.Web/serverfarms', variables('appHostingPlanNameVar'))]",
                "siteConfig": {
                    "appSettings": [
                        {
                            "name": "MyFirstName",
                            "value": "[parameters('FirstNameValue')]"
                        },
                        {
                            "name": "MyLastName",
                            "value": "[parameters('LastNameValue')]"
                        },
                        {
                            "name": "MySSN",
                            "value": "[parameters('SSNValue')]"
                        }
                    ]
                }
            }
        }
    ],
    "outputs": {}
}
```

If you save the template, then the next time you deploy resources using this ARM template, you will be required to put in a new value for the first name, last name, and SSN that will be used in your application settings.

![customized template](https://microsoft.github.io/AzureTipsAndTricks/files/customdeploy3.png)

And after deployment, go and check your App Settings.

![check settings](https://microsoft.github.io/AzureTipsAndTricks/files/customdeploy4.png)

Pretty cool, huh? Once I overcame the confusion of what ARM templates are and why I need them, it's like my brain opened up. ARM templates make your life easier by automating resource management and customizing values as needed. 

**Want to learn more about ARM Templates?** Check out our [overview](https://docs.microsoft.com/en-us/azure/azure-resource-manager/resource-group-overview?WT.mc_id=azureapril_devto-blog-cxa)!

---
We'll be posting articles every day in April, so stay tuned or jump ahead and check out more tips and tricks [now](http://azuredev.tips).