ARM Templates are written with JSON and are at the core of Azure Resource Manager deployments. I have used and developed templates for months. Although successful, I ran into issues with formatting and syntax this week and decided to take a step back and get a better understanding of the underlying JSON used in these templates. In this post, I start from the beginning, exploring JSON as it relates to ARM templates.
What is JSON?
The best place to start is with the question, what is JSON? JSON stands for JavaScript Object Notation. JSON is a data file format, similar XML. JavaScript is not the same as Java, it actually has nothing to do with Java, its name was a marketing decision made many years ago that stuck. There is an interesting history on how that came to be, but off topic for this post.
There is a lot of resources available to learn about JSON. I try to limit this post to what is relevant to formatting ARM Templates in Azure.
JSON Syntax
A JSON document is a text file that holds data. Data is in the format of a key-value pairs. These data pairs are objects that can be nested in multiple levels. It uses specific characters, or syntax, to format the data. The characters used are:
{ } Curly brackets are used to hold objects and all data is considered an object. JSON documents start and end with brackets so everything will be in a bracket at some level.
“ ” Double quotes hold the string values.
: The colon separates keys and values in key-value pair object.
, The comma separates objects as well as values in an array.
[ ] Brackets hold arrays or ordered list of objects. An array can contain a list of data or a list of key, value pairs.
‘ ‘ Single quotes. These, technically, are not supported for JSON, but they can be passed to JavaScript functions. They are used to quote within double quotes without the need for escape characters in ARM templates.
A JSON document can represent specific data types. Below are the supported data types and examples:
Number | 1234 |
String | “Hello World” |
Boolean | true or false, note no double quotes |
Array | “Hello”, “World” |
Object | “color”:”red” |
Null | :null |
Tools
JSON can be written in any text editor including notepad or Vi. I suggest something that is JSON aware and can help with formatting and syntax. Below is a list of a few free options that come to mind.
Visual Studio Code – My favorite. Add the Microsoft PowerShell and Resource Manager extension. Also, the Prettier Code Formatter can help with the appearance of many types of code.
Brackets – I just started using this and so far it seems to work and look great. Add the Pretty Json Extension for formatting JSON docs.
NotePad++ – The old standby that should be in everyone’s toolbox. A great all around editor, but one of the above tools may be better for heavy JSON editing.
PowerShell – ConvertTo-Json and ConvertFrom-Json can import JSON as a PowerShell Object and output to JSON.
jq – For those who like the command-line, jq is a lightweight JSON processor.
Online Editors – a search for “JSON Online Editors” will turn up a bunch of options that will let you dump unformatted JSON text and convert it to a formatted, human-readable version.
Formatting JSON
Now that we have the basics out of the way, let’s look at examples. I am using parts of an ARM Template for this example. The focus, for now, is on formatting JSON. I will go deeper into ARM Templates in another post.
The beginning of an ARM Template looks like this:
Here are the labeled elements:
1, This is the opening and closing curly bracket. Every JSON document has these as everything in the document is an object. In this case, there are two complex objects in the document.
2, This is the key of the key-value pair. Notice it’s in double quotes. All string values are in double quotes.
3, This is the string value of the key-value pair. Again, notice the double quotes.
4, The colon separates the key-value pairs. To the left is the key, to the right is the value.
5, the comma separates the key-value objects.
The white spaces and line breaks are not necessary for JSON. A computer has no problem interpreting the same information as above in this format:
{"$schema":"http://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#","contentVersion": "1.0.0.0"}
That may not seem too bad, but a full, unformated ARM template would be impossible to read. That’s where Brackets or the Prettier extension in VS Code comes in handy. These tools can properly format unformatted JSON files.
Moving on with the example, let’s add a parameter and examine the formatting. Below we add a parameter of WindowsOSVersion. You can see where formatting becomes important as every object needs an opening and closing bracket.
This example shows the nesting of objects in the JSON file. While $schema and contentVersion represent a simple key-value pair, windowsOSVersion contains a list of other key-value pair objects. You can see the relationship by mapping out the keys from this section of code.
We can explore this data in PowerShell by running the Convertfrom-Json command to load the data as a PowerShell Object. First, load the data into PowerShell with the command below. Replacing the path and file name with your own.
$json = (Get-Content .\Template1.json -Raw) | ConvertFrom-Json
From there you can drill down to get the values at each level of the JSON file using .psobject.properties.name as shown below. In the end, we can query the allowedValues property name to see the value of that key. In this case, its an array of string values.
Although the above exercise may not seem directly related to creating ARM templates in Azure, it does illustrate that JSON templates represent a data file like any other JSON file with the same formatting and methods. An ARM JSON Template is nothing more than a data structure that defines the deployment.
Arrays
In the example above, windowsOSVersion contains other key-value pair complex objects. The key “allowedValues” contains a different object type, this is an array of string values. Arrays are identified by the leading and trailing [] brackets and contain an ordered list of values. These can be queried for a specific value by adding the numeric identifier in brackets like below. Note that the first element starts with [0].
Key-value pairs only have one value, however, that value can be an array of values. The windowsOSVersion key contains one array of multiple string values. It is also valid for a key to contain an array of key-value pairs, such as below. The Key “car” contains an array of key-value pairs. These key-value pairs can have nested values and those can have nested values and so on.
Matter of fact, the entire Resources section of an arm template is made up of a single “resources” key and an array of values.
If you made it this far, thanks! I hope it helped. In my next post, I’m going to expand on this and begin building a working ARM template. The link to that post is here.