Using Objects in Azure Resource Templates

Over the past few weeks I’ve been refactoring and improving the templates that I have been creating for Black Marble to deploy environments in Azure. This is the first post of a few talking about some of the more advanced stuff I’m now doing.

You will remember from my previous posts that within an Azure Resource Template you can define parameters and variables, then use those for the configuration values within your resources. I was finding after a while that the sheer number of parameters and variables I had made the templates hard to read and understand. This was particularly true when my colleagues started to work with thee templates.

The solution I decided on was to collect individual parameters and variables into objects. These allow structures of information to be passed into and within a template. Importantly for me, this approach significantly reduces the number of items listed within the variables and parameters sections of my template, making them easier to read and understand.

Creating objects within the JSON is easy. You can simply declare variables within a hierarchy in your JSON. This is similar to using arrays, but each property can be individually references. Below is a sample from the variables section of my current deployment template:

"VirtualNetwork": {    "Name": "[concat(parameters('envPrefix'), 'network')]",    "Location": "[parameters('envLocation')]",    "Prefix": "192.168.0.0/16",    "Subnet1Name": "Subnet-1",    "Subnet1Prefix": "192.168.1.0/24" },  When passing this into a nested deployment I can simply push the entire object via the parameters block of the nested deployment JSON:
"parameters": {     "VirtualNetwork": {         "value": "[variables('VirtualNetwork')]"     },     "StorageAccount": {         "value": "[variables('StorageAccount')]"     } }

Within the target template I declare the parameter to be of type Object:

"VirtualNetwork": {   "type": "object",   "metadata": {     "description": "object containing virtual network params"   } }

Then to reference an individual property I specify it after the parameter itself using dot notation for the hierarchy of properties:

"subnets": [   {     "name": "[parameters('VirtualNetwork').Subnet1Name]",     "properties": {       "addressPrefix": "[parameters('VirtualNetwork').Subnet1Prefix]"     }   } ]

The end result is a much better structure to my templates, where I am passing blocks of related information around. It’s easier to read, understand and debug.

Leave a Reply

Your email address will not be published. Required fields are marked *