Deploying Multiple Resources Using an Azure JSON File

Aidan Finn profile picture
Aidan Finn Petri Contributor

Follow

Aidan Finn, Microsoft Most Valuable Professional (MVP), has been working in IT since 1996. He has worked as a consultant and administrator for the likes of Innofactor Norway, Amdahl DMR, Fujitsu, Barclays and Hypo Real Estate Bank International where...

 
JSON Hero scaled This post will show you how to deploy multiple resources in a fairly simple example of an Azure Resource Manager JSON file, which was created in the following posts:


 

The Starting Point

We will start with a pretty simple JSON that deploys a storage account into a resource group. The template asks, using parameters, the administrator to name the storage account and select a resiliency level for the Standard Storage (HDD) account. A variable (RGLocation) retrieves the Azure region of the desired resource group and is used to automatically place the new storage account into the same Azure region.

{
    "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
    "contentVersion": "1.0.0.0",
    "parameters": {
        "Storage Account Name": {
            "defaultValue": null,
            "type": "string"
        },
        "Storage Account Resiliency":
            {
            "type": "string",
            "defaultValue": "Standard_LRS",
            "allowedValues":
                [
                "Standard_LRS",
                "Standard_GRS"
                ]
        }    
    },
    "variables": {
        "RGLocation": "[resourceGroup().location]"
    },
    "resources": [
        {
            "comments": "Will be used to store virtual machines in this resource group",
            "type": "Microsoft.Storage/storageAccounts",
            "sku": {
                "name": "[parameters('Storage Account Resiliency')]",
                "tier": "Standard"
            },
            "kind": "Storage",
            "name": "[parameters('Storage Account Name')]",
            "apiVersion": "2016-01-01",
            "location": "[variables('RGLocation')]",
            "tags": {},
            "properties": {},
            "resources": [],
            "dependsOn": []
        }
    ]
}

Expanding the JSON Template

I want to add some resources to this JSON:

  • A virtual network
  • An availability set

I could learn how to build out the syntax of these resources, but the snippets functionality of VS Code allows me to quickly add arm-vn (VNet) and arm-avail (availability set) resources to the template.

The Virtual Network

I added a comma to the brace that marks the end of the storage account resource, and then the following code is automatically added when I added an arm-vn snippet:

The default new virtual network snippet [Image Credit: Aidan Finn]
The default new virtual network snippet [Image Credit: Aidan Finn]
I want to make a few changes. I will change the location setting so that it uses my RGLocation variable instead of running the resourceGroup() function again.

I am also going to convert the following settings into parameters with default values:

  • name: The desired name of the virtual network.
  • displayName: This will have the same value as name.
  • addressSpaceaddressPrefixes: The network address of the new VNet.
  • subnetsname: The name of each of the 2 default subnets.
  • subnetsaddressPrefix: The subnet address of each subnet, within the address space of the VNet.

I will have the following new parameters to customize the new network at the time of deployment:

The new JSON parameters for the virtual network [Image Credit: Aidan Finn]
The new JSON parameters for the virtual network [Image Credit: Aidan Finn]
And the new resource description that uses those parameters and the RGLocation variable will look as follows:
The customized VNet in the Azure JSON [Image Credit: Aidan Finn]
The customized VNet in the Azure JSON [Image Credit: Aidan Finn]

The Availability Set

I added a comma after the brace that ends the VNet definition and then typed arm-availability to add an availability set, as shown below.

The default Azure availability set JSON snippet [Image Credit: Aidan Finn]
The default Azure availability set JSON snippet [Image Credit: Aidan Finn]
I want to make two changes to this availability set:

  • name: Change this to a parameter.
  • displayName: Use the same value as name.
  • location: Use the RGLocation variable.

I will add a single parameter to the JSON file for the availability set:

The added variable for the ARM availability set JSON definition [Image Credit: Aidan Finn]
The added variable for the ARM availability set JSON definition [Image Credit: Aidan Finn]
The customized resource definition for the availability set is next:
The customized availability set in the Azure JSON [Image Credit: Aidan Finn]
The customized availability set in the Azure JSON [Image Credit: Aidan Finn]

The Complete JSON Template

Copying snippets from a website is a nightmare, so here is the complete JSON file:

{
    "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
    "contentVersion": "1.0.0.0",
    "parameters": {
        "Storage Account Name": {
            "defaultValue": null,
            "type": "string"
        },
        "Storage Account Resiliency": {
            "type": "string",
            "defaultValue": "Standard_LRS",
            "allowedValues": [
                "Standard_LRS",
                "Standard_GRS"
            ]
        },
        "Network Name": {
            "defaultValue": "nw-petri",
            "type": "string"
        },
        "Network Address": {
            "defaultValue": "10.0.0.0/16",
            "type": "string"
        },
        "Subnet-1 Name": {
            "defaultValue": "sn-petri-01",
            "type": "string"
        },
        "Subnet-1 Address": {
            "defaultValue": "10.0.0.0/24",
            "type": "string"
        },
        "Subnet-2 Name": {
            "defaultValue": "sn-petri-02",
            "type": "string"
        },
        "Subnet-2 Address": {
            "defaultValue": "10.0.1.0/24",
            "type": "string"
        },
        "Availability Set Name": {
            "defaultValue": "as-petri-01",
            "type": "string"
        }
    },
    "variables": {
        "RGLocation": "[resourceGroup().location]"
    },
    "resources": [
        {
            "comments": "Will be used to store virtual machines in this resource group",
            "type": "Microsoft.Storage/storageAccounts",
            "sku": {
                "name": "[parameters('Storage Account Resiliency')]",
                "tier": "Standard"
            },
            "kind": "Storage",
            "name": "[parameters('Storage Account Name')]",
            "apiVersion": "2016-01-01",
            "location": "[variables('RGLocation')]",
            "tags": {},
            "properties": {},
            "resources": [],
            "dependsOn": []
        },
        {
            "apiVersion": "2015-06-15",
            "type": "Microsoft.Network/virtualNetworks",
            "name": "[parameters('Network Name')]",
            "location": "[variables('RGLocation')]",
            "tags": {
                "displayName": "[parameters('Network Name')]"
            },
            "properties": {
                "addressSpace": {
                    "addressPrefixes": [
                        "[parameters('Network Address')]"
                    ]
                },
                "subnets": [
                    {
                        "name": "[parameters('Subnet-1 Name')]",
                        "properties": {
                            "addressPrefix": "[parameters('Subnet-1 Address')]",
                        }
                    },
                    {
                        "name": "[parameters('Subnet-2 Name')]",
                        "properties": {
                            "addressPrefix": "[parameters('Subnet-2 Address')]",
                        }
                    }
                ]
            }
        },
        {
            "type": "Microsoft.Compute/availabilitySets",
            "name": "[parameters('Availability Set Name')]",
            "apiVersion": "2015-06-15",
            "location": "[variables('RGLocation')]",
            "tags": {
                "displayName": "[parameters('Availability Set Name')]"
            },
            "properties": {}
        }
    ]
}


You can deploy this template in several ways to quickly deploy a storage account, a virtual network (with two subnets), and an availability set with a minimal amount of effort, and you’ll get a consistent result every time.