Step by Step ARM Templates - Building your first ARM Template

@20aman    Sep 04, 2016

Index of all blogs in this Step by Step ARM Templates series is located here: Step by Step Azure Resource Manager (ARM) Templates - Index

In this blog post, we will use the knowledge learned in previous blogs and will build a basic ARM template. If you haven't checked previous blog posts then have a quick read of your preferred topics here: Step by Step Azure Resource Manager (ARM) Templates - Index

To follow this blog, you can use any text editor which can provide JSON syntax highlighting. We will be looking at using Visual Studio to author ARM templates in a future blog post. Visual Studio can provide JSON outlining and is a very powerful tool for authoring ARM templates.

Let us assume that you want to deploy a storage account and build a virtual network in Azure. You want to automate the process and need to repeat the process in various environments. ARM templates fit the bill for the solution of this problem.

In the next few sections, we will build each section of the template and then at the end will check the complete template.

1. Template Header

This section is very basic and contains just the schema and the content version. You can use the content version to manage the development versions of the template as you make changes to your templates in the future.

"$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",

2. Parameters

Here we define all the inputs we need from the end users. We provide default values for those parameters for which we know what the most common values will be based on our environment. For the current template we define two parameters:

  • vhdStorageName - This is the name of the storage account in Azure which will be created by the deployment of this template.
  • virtualNetworkName - This is the name of the Virtual Network which will be created by the deployment of this template.

As a best practice, provide the metadata, describing what each parameter is for. Also, note that we have used pascal casing to name the parameters with very descriptive names.

"parameters": {
    "vhdStorageName": {
        "type": "string",
        "minLength": 1,
        "defaultValue": "mystorage101",
        "metadata": {
            "description": "Name of the Storage Account."
        }
    },
    "virtualNetworkName": {
        "type": "string",
        "metadata": {
            "description": "Name of the virtual network."
        }
    }
},

3. Variables

Next, we add some variables for the values which will be reused later in the template in the resources section. We create variables for all those reusable values for which we know what their value at deployment will be. We define 4 variables in this template:

  • addressPrefix - Address prefix for the Virtual Network
  • subnetName - Subnet name which will be created under the virtual network
  • subnetPrefix - Subnet prefix for the subnet, which will be created under the virtual network
  • vhdStorageType - Type of the storage account. Here we used Standard locally redundant storage (LRS)

Variables section look as below:

"variables": {
    "addressPrefix": "10.0.0.0/16",
    "subnetName": "Subnet",
    "subnetPrefix": "10.0.0.0/24",
    "vhdStorageType": "Standard_LRS"
},

4. Resources

Now comes the last and main section i.e. Resources. Here we define both the resources for our template:

  • Storage Account
  • Virtual Network

Let us look at each of these resources one by one.

A. Storage Account Resource

This resource has below properties (or key-value pairs):

  1. Type - Type of the resource is set to Microsoft.Storage/storageAccounts. This is what tells the Azure that the current resource is a Storage Account
  2. Name - This defines the name of the storage account to be deployed based on the parameter to the template
  3. API Version - this is the standard version for the REST API in Azure
  4. Location - This is the Azure location. The location is found dynamically based on the location of the resource group to which this template will be deployed.
  5. tags - only one tag is defined for the display name. You should have more tags in case of a production ready template
  6. properties - This is where you tell Azure what kind of storage account you need. Here the account type is set using the value of the variable vhdStorageType.

B. Virtual Network Resource

This resource has below properties (or key-value pairs):

  1. Type - Type of the resource is set to Microsoft.Network/virtualNetworks. This is what tells the Azure that the current resource is a Virtual Network
  2. Name - This defines the name of the virtual network to be deployed based on the parameter to the template
  3. API Version - this is the standard version for the REST API in Azure
  4. Location - This is the Azure location. The location is found dynamically based on the location of the resource group to which this template will be deployed.
  5. tags - only one tag is defined for the display name. You should have more tags in case of a production ready template
  6. properties - This is where you define the address space for the virtual network. You also define the subnet under the virtual network here.

The resources section look like below:

"resources": [
    {
        "type": "Microsoft.Storage/storageAccounts",
        "name": "[parameters('vhdStorageName')]",
        "apiVersion": "2015-06-15",
        "location": "[resourceGroup().location]",
        "tags": {
            "displayName": "StorageAccount"
        },
        "properties": {
            "accountType": "[variables('vhdStorageType')]"
        }
    },
    {
        "apiVersion": "2015-06-15",
        "type": "Microsoft.Network/virtualNetworks",
        "name": "[parameters('virtualNetworkName')]",
        "location": "[resourceGroup().location]",
        "tags": {
            "displayName": "VirtualNetwork"
        },
        "properties": {
            "addressSpace": {
                "addressPrefixes": [
                    "[variables('addressPrefix')]"
                ]
            },
            "subnets": [
                {
                    "name": "[variables('subnetName')]",
                    "properties": {
                        "addressPrefix": "[variables('subnetPrefix')]"
                    }
                }
            ]
        }
    }
]

Complete Template

Here is the complete template build from all the sections discussed above. You can copy and use this template for testing and working along with next deployment posts.

{
    "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
    "contentVersion": "1.0.0.0",
    "parameters": {
        "vhdStorageName": {
            "type": "string",
            "minLength": 1,
            "defaultValue": "mystorage101",
            "metadata": {
                "description": "Name of the Storage Account."
            }
        },
        "virtualNetworkName": {
            "type": "string",
            "metadata": {
                "description": "Name of the virtual network."
            }
        }
    },
    "variables": {
        "addressPrefix": "10.0.0.0/16",
        "subnetName": "Subnet",
        "subnetPrefix": "10.0.0.0/24",
        "vhdStorageType": "Standard_LRS"
    },
    "resources": [
        {
            "type": "Microsoft.Storage/storageAccounts",
            "name": "[parameters('vhdStorageName')]",
            "apiVersion": "2015-06-15",
            "location": "[resourceGroup().location]",
            "tags": {
                "displayName": "StorageAccount"
            },
            "properties": {
                "accountType": "[variables('vhdStorageType')]"
            }
        },
        {
            "apiVersion": "2015-06-15",
            "type": "Microsoft.Network/virtualNetworks",
            "name": "[parameters('virtualNetworkName')]",
            "location": "[resourceGroup().location]",
            "tags": {
                "displayName": "VirtualNetwork"
            },
            "properties": {
                "addressSpace": {
                    "addressPrefixes": [
                        "[variables('addressPrefix')]"
                    ]
                },
                "subnets": [
                    {
                        "name": "[variables('subnetName')]",
                        "properties": {
                            "addressPrefix": "[variables('subnetPrefix')]"
                        }
                    }
                ]
            }
        }
    ]
}

In the next blog, we will learn how to deploy this template.





Comments powered by Disqus