Azure Resource Manager - Objects in variables

When you are working on more advanced deployment template scenarios for Azure Resource Manager, the number of variables in your templates can grow very quickly. It can be challenging to keep track of all variables, what their purpose is and it is becomes even more complex when you are passing variables between linked templates in a nested deployment scenario.

In this blog we will look at ways to group your variables in objects. These objects will form the basis of the next blog on sharing state between nested templates.

Objects in variables

You can group variables into objects. A variable object can also contain references to parameters.

"variables": {
  "myNestedVariables": {
    "fqdn": "[parameters('domainFqdn')]",
    "storageAccountName": "storage123unique"
  }
}

A object in variables can be created multiple level deep.

"variables": {
  "myNestedVariables": {
    "fqdn": "[parameters('domainFqdn')]",
    "storageAccountName": "storage123unique"
	  "storageAccountType" {
		  "localRedundant": "Standard_LRS",
		  "geoRedundant": Standard_GRS"
	  }
  }
}

You can reference a value from a variable object in resources and output using the format variable.subentry (e.g. “[variables(‘myNestedVariables’).storageAccountName]” ).

"resources": [
  {
    "type": "Microsoft.Storage/storageAccounts",
    "name": "[variables('myNestedVariables').storageaccountName]",
    "apiVersion": "2015-06-15",
    "location": "[resourceGroup().location]",
    "properties": {
      "accountType": "standard_LRS"
    }
  }
]

You can also reference a value from a variable object in resources and output using the format variable[number] or variable.subvalue[0] (e.g. “[variables(‘myNestedVariables’).storageAccountType[0]]” ).

"resources": [
  {
    "type": "Microsoft.Storage/storageAccounts",
    "name": "[variables('myNestedVariables').storageaccountName]",
    "apiVersion": "2015-06-15",
    "location": "[resourceGroup().location]",
    "properties": {
      "accountType": "[variables('myNestedVariables').storageAccountType[0]]"
    }
  }
]

It is possible to reference a parameter and/or a variable with a function within a variable object.

"parameters": {
	"storageAccountPrefix": {
		"type": "string"
	}
},
"variables": {
    "myNestedVariables": {
      "username": "[parameters('adminUsername')]",
      "password": "[parameters('adminPassword')]",
      "fqdn": "[parameters('domainFqdn')]",
      "vmPrefix": "myVm",
      "thisFunctionWorks": "[concat('you CAN use a function with', parameters('storageAccountPrefix'), 'and', variables('storageAccountName'))]"
	  },
	  "storageAccountName": "storage123unique"
}

A object cannot contain an expression that references a value from the same or another variables object.

"variables": {
  "myNestedVariables": {
    "username": "[parameters('adminUsername')]",
    "password": "[parameters('adminPassword')]",
    "fqdn": "[parameters('domainFqdn')]",
    "vmPrefix": "myVm",
    "storageAccountName": "storage456unique"
    "thisFunctionFails": "[concat('you CAN NOT use a function with', variables('myNestedVariables').storageAccountName )]"
  }
}

Create variable (that is not part of an variable object) for a function within an object that references another variable (e.g. the "storageAccountName": "storage123unique" variable in the previous example)

Nested templates

In the next blog we will look at how we can use the object in variables to improve the experience when working with nested templates.