Step by Step ARM Templates - What is in an ARM Template - Understanding Components 4 - Resources

@20aman    Aug 29, 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

If you haven't checked the previous blog on the overall structure of the ARM template, I suggest you give it a quick read before checking the component described in this post in detail.

  1. Understanding all components
  2. Parameters
  3. Variables
  4. Resources - This blog post
  5. Outputs

Resources

This is the major section of the whole ARM template. This is where you define what resources should be deployed in Azure. You also define dependencies between resources in this section.

The resources section consist of an array of JSON Objects as shown below:

"resources": [
        { },
        { },
]

Each object in the array (represented via curly braces) is an Azure resource. You can deploy multiple resources in a single ARM template. E.g. You can deploy a new Storage Account, new Virtual Network and three Virtual Machines in that virtual network within a single template. Within the object, various properties (and nested properties) are used to provide the configurations of each resource.

Elements

Different elements in a single resource object can be one of the following:

  1. apiVersion - Required - Version of the API. e.g. "2015-06-15"
  2. type - Required - Type of the resource. This value is a combination of the namespace of the resource provider and the resource type that the resource provider supports. e.g. Azure Storage Account will have type as "Microsoft.Storage/storageAccounts".
  3. name - Required - Name of the resource. The name must follow URI component restrictions and also the Azure naming restrictions if any. E.g. Storage account name can only be in small letters and has to be unique.
  4. location - Optional - Use supported geo-locations of the provided resource without any spaces. Or use the resource group's location dynamically.
  5. tags - Optional - Tags that are associated with the resource.
  6. dependsOn - Optional - Other resources in the same template, that the current resource being defined depends on. The dependencies between resources are evaluated and resources are deployed in their dependent order. When resources are not dependent on each other, they are attempted to be deployed in parallel. The value can be a comma-separated list of resource names or resource unique identifiers.
  7. properties - Optional - Resource specific configuration settings. E.g. Account type property for a storage account name.
  8. resources - Optional - Child resources that depend on the resource being defined. E.g. Extension resources for a Virtual Machine resource.

Examples

Let's look at two examples. First, we will take a simple resource example to deploy a storage account in Azure:

{
            "type": "Microsoft.Storage/storageAccounts",
            "name": "[variables('vhdStorageName')]",
            "apiVersion": "2015-06-15",
            "location": "[resourceGroup().location]",
            "tags": {
                "displayName": "StorageAccount",
                "department" : "Finance",
                "application" : "database"
            },
            "properties": {
                "accountType": "[variables('vhdStorageType')]"
            }
        }

Above example will deploy a storage account with the name from "vhdStorageName" variable. It will apply 3 tags to the resource after deployment. It will use the account type (i.e. standard or premium) based on the value of the "vhdStorageType" variable. If you want to deploy 2 or more similar storage accounts, then just copy and paste the json for the resource, separated by comma. It will become another object in the Resources array.

Now let's look at a complex and larger example of deploying a single virtual machine with one extension for Diagnostics.

    {
        "apiVersion": "2015-06-15",
        "type": "Microsoft.Compute/virtualMachines",
        "name": "[variables('vmName')]",
        "location": "[resourceGroup().location]",
        "tags": {
            "displayName": "VirtualMachine"
        },
        "dependsOn": [
            "[concat('Microsoft.Storage/storageAccounts/', variables('vhdStorageName'))]",
            "[concat('Microsoft.Network/networkInterfaces/', variables('nicName'))]"
        ],
        "properties": {
            "hardwareProfile": {
                "vmSize": "[variables('vmSize')]"
            },
            "osProfile": {
                "computerName": "[variables('vmName')]",
                "adminUsername": "[parameters('adminUsername')]",
                "adminPassword": "[parameters('adminPassword')]"
            },
            "storageProfile": {
                "imageReference": {
                    "publisher": "[variables('imagePublisher')]",
                    "offer": "[variables('imageOffer')]",
                    "sku": "[parameters('windowsOSVersion')]",
                    "version": "latest"
                },
                "osDisk": {
                    "name": "osdisk",
                    "vhd": {
                        "uri": "[concat('http://', variables('vhdStorageName'), '.blob.core.windows.net/', variables('vhdStorageContainerName'), '/', variables('OSDiskName'), '.vhd')]"
                    },
                    "caching": "ReadWrite",
                    "createOption": "FromImage"
                }
            },
            "networkProfile": {
                "networkInterfaces": [
                    {
                        "id": "[resourceId('Microsoft.Network/networkInterfaces', variables('nicName'))]"
                    }
                ]
            },
            "diagnosticsProfile": {
                "bootDiagnostics": {
                    "enabled": true,
                    "storageUri": "[concat('http://', variables('diagnosticsStorageAccountName'), '.blob.core.windows.net')]"
                }
            }
        },
        "resources": [
            {
                "type": "extensions",
                "name": "Microsoft.Insights.VMDiagnosticsSettings",
                "apiVersion": "2015-06-15",
                "location": "[resourceGroup().location]",
                "tags": {
                    "displayName": "AzureDiagnostics"
                },
                "dependsOn": [
                    "[concat('Microsoft.Compute/virtualMachines/', variables('vmName'))]"
                ],
                "properties": {
                    "publisher": "Microsoft.Azure.Diagnostics",
                    "type": "IaaSDiagnostics",
                    "typeHandlerVersion": "1.5",
                    "autoUpgradeMinorVersion": true,
                    "settings": {
                        "xmlCfg": "[base64(concat(variables('wadcfgxstart'), variables('wadmetricsresourceid'), variables('wadcfgxend')))]",
                        "storageAccount": "[variables('diagnosticsStorageAccountName')]"
                    },
                    "protectedSettings": {
                        "storageAccountName": "[variables('diagnosticsStorageAccountName')]",
                        "storageAccountKey": "[listkeys(variables('accountid'), '2015-06-15').key1]",
                        "storageAccountEndPoint": "https://core.windows.net"
                    }
                }
            }
        ]
    }

Note that the above code snippet defines a single virtual machine. Let us decode various sections of this complex resource:

  • It begins with simple properties like apiVersion, type, name, location and tags as discussed in the previous example. These are straightforward and thus values are provided to these attributes.
  • Next is the dependsOn section. This defines the dependency between resources. In the above example, the virtual machine resource is dependent on the storage account and a network interface, which are also defined in the template. These 2 resources will be created before the virtual machine creation/deployment. If these resources are not created in the template then it will check for the presence of these resources in the current subscription. If they are not present the template will not get deployed and will error out.
  • Next are various properties to configure the Virtual machine, like hardware profile, os profile, storage profile, os disk, network profile, diagnostics profile etc.
  • Next, we have additional sub-resources. These are Azure resources which will be created and linked to the current resource. Only one sub-resource is created in the above example which is an extension for VM diagnostics settings.

That's all there is to Resources in ARM Templates. If you have any doubts, please comment in the below section. Use the links at the Top to know all about other components in an ARM Template.





Comments powered by Disqus