Published:
I’ve been working recently with modifications to ARM templates for clients specifically for Sitecore development, however this topic of ARM Templates isn’t really specific to Sitecore, but instead it’s a common theme of what is the basic structure of an ARM template. In this article I am going to start with the basics and then expand off of that with my next article where I demonstrate how you would modify an ARM template to solve specific scenarios related to a Sitecore deployment.
So what makes up an ARM template? First off you will always have these two files:
The azuredeploy.json
file, is the file that contains the instructions on what to deploy. Typically you will find two types of instructions (although I am sure there are more), which include infrastructure setup and then the application that sits on that infrastructure. Now you can definitely include all of the definitions for your infrastructure and the applications that live in your infrastructure in your azuredeploy.json
file, but it becomes a little cluttered the more you have in that document, so a common practice is to separate your definitions across multiple files. You would do this by nesting deploymentTemplates
resources into your primary azuredeploy.json
. If you are working on modifying the default Sitecore Azure templates, you will see when you pull down an ARM template for XP0 for example, that it contains a nested
folder. In this folder you will see json files prefixed with either Infrastructure or Application to represent the two types of environment setup you would need to accomplish.
###The Contents of the ARM Template json Files
Now that’s all great, but if you’ve ever opened the json files, either the nested ones or the primary azuredeploy.json file you will notice alot of things going on. Fundamentally these json files are made up of the following elements:
If you glance at the azuredeploy.json file, you will find at it’s core, that its made up of those same elements. There are a few other elements I haven’t listed, but those typically only apply to one off scenarios. If you are working on the Sitecore Azure PaaS ARM Templates, then you should see most of those same elements listed in the templates.
Schema is just a way to provide the schematics of the overall structure of your json documents. This is really what defines what should make up the main structure of the file. So for example, if you are working with Visual Studio Cloud Project, it will provide intellisense based on this schema definition to make it super simple to make changes to this deployment json script.
These are exactly as the name suggests. Its very similar to programming except it is in textual form. Typically you will find that they pull in a parameter (which I will describe shortly) into the variable and then manipulates that parameters value to make up a new variable that can be easily pulled throughout the current deployment template. You can also use them to store custom string values. A common variable that I see used fairly often is that when you are defining a piece of infrastructure such as a Web App, those resources require an ApiVersion
which is a versioning system to define what properties and settings that can be selected for that resource. So for example, for the deployment Templates, if you want to pull in a nested or external json file, you would have json that looks like the following:
It would be a resource in your azuredeploy.json
(or you can nest at multiple layers deep depending on your complexity) that would define another deploymentTemplate
to pull in. As you can see, I need to specify a version for the apiVersion
. This would be a great example of when you would want to use a Variable. You could also theoretically use a parameter. The big difference between a variable and a parameter, is that typically a parameter is something that can be passed in by human interaction (although you can specify a default value so it doesn’t always have to be passed in). A variable on the other hand, is something that will only ever change value when the program changes its value.
Once you’ve defined a variable at the top, you can then use that variable anywhere in the template definition by using [variables('variable_name')]
in a string value.
To learn more about a variable, refer to the Microsoft documentation.
A Parameter is a definition element in your deploymentTemplate
, that is probably one of the most important pieces to your Azure ARM Templates. These are values that can be changed either by your azuredeploy.parameters.json
file, or you can also change them in your main Powershell script that you are running to fire up your environment. Every deploymentTemplate will have parameters, and if you’ve nested multiple templates within each other, you would need to pass the parameters around from one file to another. This is another big different between a Variable and a Parameter. A parameter is a mechanism that can be used to pass around values, where as you can’t use a variable directly to pass around values (without using a parameter to pass around the variables value).
When you define a nested Template in your current deployment Template, you can pass parameters, which I showcased in my previous snippet. It’s as easy as defining the parameter name, creating an element called “value” and setting the string value to the value you want to pass to the next nested template. Keep in mind, you must define the parameter on the nested Template as well. If you pass a parameter that hasn’t been defined, than you will run into some issues with errors on your next deploy.
To use a parameter, it’s very similar to using a variable, you would just use the following snippet: [parameters('parameter_name')]
in a string value. That’s it, you are now set. If you want to learn more, refer to this documentation on parameters to learn more.
This wasn’t provided in my code snippet example, but it’s worth mentioning, because this introduces a pretty powerful feature available to your ARM Templates. Now Sitecore Azure PaaS Arm templates do not currently include any functions (this was written based on Sitecore 9.0.2 which just released). To learn more, refer to the documentation provided on Microsoft’s website.
This is where all the magic happens. Up until this point, you weren’t really able to do anything except set variables and pass around parameters. A resource can be another deploymentTemplate
as I’ve already displayed, or it can be infrastructure or application specific resources that you’d like to use to spin up your Azure environment. Some of the many resources that you could potentially deploy include some of the following (keep in mind this list is always changing, so this is a small sampling):
Another key concept to keep in mind, is that some resources can have child resources. A great example of this would be a Web App Plan or a Sql Server resource. A Web App plan can contain multiple Web Apps, as the same can be said for a Sql Server resource which could contain multiple databases.
If you want to learn more about resources and the limitations, review Microsoft’s documentation to learn more.
This is a less common element, especially when you are working with the default Sitecore Azure PaaS ARM Templates. But it can be used to pass a value out of a deploymentTemplate
back into the deploymentTemplate
that called it. Sitecore uses this parameter sparingly, but it’s commonly used for the SqlServerFqdn (fully qualified name).
Well this concludes our summary on ARM Templates. This is more on a general discussion of ARM templates, but for those of you that might have the need or desire to customize one of the OOTB Sitecore ARM templates, this will be very helpful on getting yourself to the point where you can make those changes. I plan to do a couple of videos coming up on the topic specifically, and will go a little more into what I consider the “Best Practice” when it comes to modifying an ARM Template for Sitecore. What should you customize and what should you avoid, to prevent you future headaches.