Recently I was busy preparing a presentation for our Insight Innovation Day where I wanted to cover a topic about authoring ARM templates.
One of the main challenges that I see with customers and consultants is to author consistent templates following a standardized pattern. Even Microsoft isn’t always doing a great job if you look at the output of the resource explorer or automation option when creating a new resource through the portal UI
So what started as a prep session for a presentation, ended up in a jawbreaker to see how I could standardize templates without affecting the readability of the template itself.
To explore my options I started crawling through the ARM templates that I have created in the past and search for common patterns that could be improved. One of my big findings was the naming of resources.
Looking at my templates I noticed that for each resource deployment through ARM the parameter for the resource name was different. vnetName, vmName, keyVaultName, etc, etc.
The solution is easy most of the time if you know what you’re looking for. In this case, my three-second memory didn’t let me down and I came with the bright idea that in all cases we are naming resources. So why not just use ‘resourceName’ as a standard parameter name.
Other patterns I discovered are parameters for the number of instances, environments, prefixes, and suffixes. All these findings resulted in a subset of default parameters that are commonly used across all ARM templates.
Now we’ve defined the minimum set of parameters we can start doing awesome things using user-defined functions. I’ve already done a blog post about this quite a while ago, but at that time it wasn’t possible to call a function from the variables section in the template. Now that we can start using that feature to create the resource name that we will use in various other sections of our template.
What you might have noticed is that the resourceName variable doesn’t have the instanceCount parameter in the name. This is because the variable is not part of a copy loop and therefore cannot use this as an input value when creating the variable.
We will use the instanceCount parameter in the concatenation in our resource deployment section as you can see in the following example.
Creating a resource lock can be a tricky one though because the name of the resource lock cannot be the same name as the resource it depends on. Also when creating the resource lock we need to add the resource provider ‘Microsoft.Authorization’ in the name of the resource to let it work.
As stated before, we would like to standardize the templates but also keep in readable and a long concat function will not help. As you can see, we are using the ‘resourceName’ variable again as input for our function to create the name for the resource lock. All magic is stuffed away in our function again resulting in a standard resource deployment for adding a lock to a resource that can be used in each of the templates without editing anything.
Another good use case is to use a user-defined function for adding resources to log analytics. When configuring log analytics for a resource there are a couple standard values that need to be added to the concatenation to retrieve the resourceId of the workspace.
By using standard parameters across ARM templates together with a standardized variable and user-defined functions we can heavily simply our templates. This will decrease the time needed to author a template and improves the consistency of the repository.
If you have any feedback or if this helped you authoring your templates, please let me know.