This course covers the Architect An Azure Compute Infrastructure part of the 70-534 exam, which is worth 10 - 15% of the exam. The intent of the course is to help fill in an knowledge gaps that you might have, and help to prepare you for the exam.
Welcome back. In this lesson, we'll talk about defining infrastructure as code with Azure Resource Manager templates.
As solution architects, we tend to think about things holistically. For example, if you have back-end application that's comprised of some virtual machines, a queue, and some persistent storage, these are all part of the same group of resources.
Since we consider these things to be conceptually one unit, it makes sense to manage them as one unit. That's what Azure Resource Manager offers. It allows you to manage all of the different resources that make up your solutions, as a single group.
Resource Manage has a concept called resource groups, which consists of one or more resources that we want to manage as a single unit. A single solution can have as many resource groups as needed.
As an example, if you had an implementation of the competing consumers pattern, you might use one resource group for the application resources, another for the message queue, and another for the resources in the messages processing pool. And since each resource is in its own group, those groups can all be managed independently.
If the application group consists of virtual machines or virtual network et cetera, then you can manage that group as a single entity. What that means is that you can create all of those resources at the same time. You could monitor all of those resources as a single unit and you can manage the role based access, to all of the resources for the entire group.
Resource Manager has given us, as engineers, a way to treat solutions in the same way we think about them, conceptually, and it's added a lot of value. With this new way to work with resources, Azure also provides a native infrastructure as code solution based on Resource Manger, making it easier to create consistent solutions.
Azure Resource Manage templates, also called ARM templates, are a JSON based template that declares which resources are required for a solution. ARM templates allow you to specify which resource you need and then have them created by having the template process to be at the portal, PowerShell, the rest API, or the command line interface.
Let's check out the ARM template structure. All templates will follow this same basic pattern and this here, is just a skeleton for that pattern. The schema property defines the URL to a JSON file that defines the templating language for the specific version of this file.
The content version is something that you can set for yourself and its purpose is to make sure that you're using the correct version of the file for your deployment, based on whichever versioning you use. Parameters allow you to click information at deployment time.
Now, this can be anything you want, however, as an example, you could use something like the name of a resource or maybe a password that you need provided at deployment time.
Now, variables here are no different than variables anywhere else in the development world. There are values that you can use elsewhere in the template. Resources are where you define which resources you actually want to create. Each resource will be its own JSON object with optional child resources. The resource object becomes even more powerful due to a few properties, such as the copy property, which allows a resource to be looped over, thereby creating multiple copies.
So, if you wanted to create multiple virtual machines, then you could do that with the copy. There's also the dependsOn property, that allows a resource to have its creation delayed while it waits for the creation of another resource or resources that use specify.
Then we have outputs. This property allows you to specify the values that you want returned after deployment and this can be particularly useful if you're using PowerShell or the command line interface to automate the creation of resources, because then you can get back the object with the values you need, to maybe move on to the next step in the process.
Let's walk through a simple template and then we'll deploy it. Instead of writing all of this out, I'm going to grab an existing template from Azure's github page. Azure has a repo on github named, Azure quick start templates, and it has an extensive collection of templates to create all kinds of different resources. It's a fantastic reference and I recommend that you check it out.
Looking through the list, you can see that there are a lot templates here. I'm going to use the one named simple windows vm template and then I'll click on this. And I'll click on the azuredeploy.json file. It starts out the same way as the skeleton that I just showed. And it starts with a schema end version.
Then we have some parameters here. Now, since the goal of this template is to start up a windows vm, it needs the administrative username and password. Notice the username has a type of string and the password has a type of secured string. Now the difference is what you'd expect, the secure string would be masked anywhere you're prompted to enter it.
This meditative section is where you can specify the description that will be displayed to whomever performs the deployment. Now, looking at the Windows OS version parameter, you can see that you can even specify a list of allowed values to select from and that comes in handy when you don't want to allow free formed text.
Okay, down here in the variables section, you get a glimpse of the first function that is used in this template, which is the concatenate function. And you can specify functions by putting them inside square brackets.
In this example, the concat function, which combines strings, takes this hard coded string and joins it with the result of this other function, which creates a deterministically unique string. The function themselves in this example aren't really that important. What's important is that you understand that you can execute functions by putting them inside square brackets.
So, there are several variables here which are used throughout the rest of the template and then in the next section, we have the resources and this is where all the resources are specified.
The first resource is going to be used to ensure that there is a storage account based on the name that's pulled from the storageAccountname variable. The type property here represents the namespace for the resource joined by the resource type.
The API version is the property that specifies the version of the rest API to use for this specific resource. The location property is the location where your resource will be created and you'll notice that here, it's using a function that fetches the location from the resource group that's actually being used.
As I scroll down, notice that the resource declarations roughly look the same and that's because they all follow the same basic pattern. Looking at the network interface resource here, you can see the dependsOn property, that I mentioned previously, which allows you to delay the creation of a resource until dependent resources are created.
Here, the public IP and virtual networks are required before the NIC can be created. If I jump down to the outputs section, you can see that you can create you own output here and in this example, the host name as a string data type and it returns the fully qualified domain. So, this template will allow you to input a username, password, DNS prefix, and then select the version of Windows, and then it's going to create the resources listed here.
Alright, let's see how this actually works by doing this in the portal. I'm going to start by searching for templates and then I'll select it here from the list. You can see that I don't have any templates at the moment, so I'm going to click add and I'll fill out a name and description, perfect. And with that done, I'll paste in the template.
It's worth noting that you could have also done this by clicking on the button in the github repo and have Azure pull the results of the JSON file automatically and it does this because it passes Azure the URL to that JSON file via a URL parameter. Now, if I save this, it will take just a second to create and once created, it doesn't show up right away. So, I'll just need to refresh this list.
And now, if I click on it, it's going to open up a blade and I'll have this deploy button. If I click it, I can fill out this form. Notice that these are the parameters from the template. The secure string data type for the password, causes it to be masked. Also, the allowed options for the Windows version, cause a drop down to be created. So, I'm going to populate this and agree to the license and then I'll click purchase.
So, this is just going to take a moment to complete, however, by looking at the resource group that I created for this and clicking refresh, you can see that it's creating everything specified in the template and in order.
Because all of the resources are a part of the same resource group, you can manage the permissions for all of these resources by setting permissions on the group itself. And you can monitor all of the resources at the group level too. Again, since all of the resources belong to the same group, if you delete the group itself, all of the resources in that group are deleted. So, that's how you deploy through the portal.
Now, if you want to use PowerShell, there are two commandlets worth knowing about. The first is the Test-AzureRmResourceGroupDeployment and it allows you to validate you deployment. And then, if you want to actually perform the deployment, you can use the New-AzureRmResourceGroupDeployment commandlet. If you want to do it from the command line, it's pretty simple. You can use the group deployment create sub commands of the Azure executable.
Okay, that's going to wrap up this lesson. In the next lesson, I'm going to cover availability. So, if you're ready to keep learning, then let's get started on the next lesson.
About the Author
Ben Lambert is the Director of Engineering and was previously the lead author for DevOps and Microsoft Azure training content at Cloud Academy. His courses and learning paths covered Cloud Ecosystem technologies such as DC/OS, configuration management tools, and containers. As a software engineer, Ben’s experience includes building highly available web and mobile apps.
When he’s not building the first platform to run and measure enterprise transformation initiatives at Cloud Academy, he’s hiking, camping, or creating video games.