DEV Community

Cover image for Demystifying ARM Templates (Azure Resource Manager)
Emily Freeman for Microsoft Azure

Posted on

Demystifying ARM Templates (Azure Resource Manager)

We've selected our favorite tips and tricks created by Michael Crump and are delivering fresh technical content on Azure all April! Miss a day (or more)? Catch up with the series.

Don't have Azure? Grab a free subscription.


If you've been in tech long enough, you might associate ARM with CPU architecture. In this case, ARM stands for Azure Resource Manager. 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

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 do!

Want more ARM Templates? Check out our overview!

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, in VSCode, or in the Azure portal.

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

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

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

automation options

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

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

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

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

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

And after deployment, go and check your App Settings.

check settings

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!


We'll be posting articles every day in April, so stay tuned or jump ahead and check out more tips and tricks now.

Top comments (0)