Azure Resource Manager (ARM) PowerShell
During this demonstration, we will explore the process of deploying an Azure Resource Manager (ARM) JSON Template, using the ARM PowerShell module. We'll deploy an ARM JSON Template directly from the web, and provide input parameters to it, using a PowerShell HashTable. As an added bonus, we'll also use the PowerShell Splatting technique to specify our deployment parameters!
Let's take a look at how to create a resource group deployment now. So I'm going to call Get-Command, specify the AzureRm.Resources module, and then under the name, I'm going to specify anything with resource group in the name. So this is a list of all the other Azure resource group commands that we can use to manage resource groups. We've already taken a look at Get-AzureRmResourceGroup and New-AzureRmResourceGroup, and all those similar commands to manage the group itself, however, what you'll also see in this list here is a bunch of commands that pertain to resource group deployments. So what is a resource group deployment? Well, when we want to deploy an Azure Resource Manager JSON template to a resource group, we do that by using a resource group deployment. So what we're going to do now is actually go out and deploy an Azure resource Manager JSON template using the Azure PowerShell module. So the first thing I'm going to do is come to the Azure-quickstart-templates GitHub project, which is publicly available. And as you can see, we've got a large list of different templates that we can choose from. We don't actually have to build a template from the ground up, we can simply take an existing template and deploy it. So I'm going to do a Control + F in my browser to search for different templates. As you can see, I've got a template here called simple-windows-vm and simple-linux-vm, simple-windows-vm with a data disk. So let's just go ahead and grab one of these. And the azuredeploy.json file is the actual template file that we need to deploy. So let's go ahead and click on that. And then we'll click on Raw which will give us a direct link to just the JSON file completely unformatted. As you can see here, the parameters are all predefined in the template. The variables, such as the image that we're going to use for the virtual machine, some of the virtual network details, and some of the public IP address details to access that virtual machine, are all prepopulated in the template. So we're, actually, gonna deploy this template directly from this URI. And in order to do so, we're going to call the New-AzureRmResourceGroupDeployment command. So let's go ahead and first create our resource group called CloudAcademyRG. And I'm gonna change the region of the resource group to West Europe. So I'm gonna hit F8 to deploy that new resource group. But the resource group is going to be empty. So we're going to use the deployment to actually instantiate resources inside of that resource group. So New-AzureRmresourceGroupDeployment is our command. And there's a whole bunch of different parameters that we can specify on this command, which we'll take a look at in a second. The first thing I'm going to do though is demonstrate how to use a PowerShell hash table to splat command parameters. So as you've seen with some of these other commands, they start to get very, very long, and they start getting cutoff on the right-hand side of the screen. So what we can do is, actually, declare our parameters inside of a hash table and then simply reference that hash table when we call the command. So I'm gonna create a new variable called Parameters, and I'm going to assign a hash table to it. Essentially, what I'm gonna do is take all the parameters that I specify on this command and then put them into the hash table instead. So the resource group that I want to deploy to is called CloudAcademyRG. So I'm gonna take that parameter and put it in the hash table. The template parameter URI that we want to deploy is, actually, from our browser. So I'm gonna go ahead and just copy and paste that URI to the ARM template file. Now, the template file has a bunch of input parameters that we need to specify. To do that, we can call either TemplateParameterObjects, TemplateParameterFile, or TemplateParameterUri. We're gonna use TemplateParameterObjects because that, actually, allows us to specify a hash table of input parameters for the template. I'm sorry, this parameter here should actually be TemplateUri. So let's just go ahead and close that off. So we, actually, want TemplateUri instead of TemplateParameterUri. And then the TemplateParameterObjects is going to be a hash table of input parameters for the template. So for PowerShell splattings purpose, we have kind of this outer hash table. And then as far as input parameters to the actual template in this JSON file go, we're, actually, gonna create a separate hash table for that purpose. So there's a bunch of parameters that we need to specify. And all those are contained under the parameters section of the Azure Resource Manger JSON template. First, we have newStorageAccountName; then we have the adminUsername that'll get assigned to the virtual machine that is instantiated by the template; the adminPassword, of course; the DNS name that we'll use to publicly access that virtual machine; and then we also need to specify the size of the data disk in gigabytes. The Windows operating system version, actually, does not matter because this one has a default value specified. So we don't, actually, have to specify an input value for this parameter, because if we don't, the default value will simply be used. So let's go ahead and start defining these parameters in our hash table. I'm just gonna copy the name of each parameter and set it to a blank string, and then go back and, actually, fill it out. So dnsNameForPublicIP. We're not gonna specify the Windows OS version, but then we need to specify the size of the data disk that gets attached. Okay, so let's go ahead and start filling this out. I'm gonna call the storage account name cloudacademyrg just to be consistent with the name of the resource group. The admin username for the virtual machine will be CloudAcademy. The admin password, we'll assign to Password. Then I'm going to call the DNS name for the virtual machine cloudacademyrg. And then the size of the data disk, we'll just attach a 20-gigabyte data disk. And we can, actually, just make that an integer. So now I've specified the parameters for my resource group deployment, and to splat them onto the command, I'm gonna use the at sign and then the variable name. So let's go ahead and just select this code and hit F8 in the PowerShell ISE to deploy. As you can see, we're getting a template validation error saying that the size is invalid for the data disk. So let's go ahead and change that to a string value. And as you can see, it's now deploying successfully. The reason we, actually, had a bug right here is because the parameter was declared as a string, and because I specified an integer value without the single quotes around the size of disk, it, actually, gave me an exception. So what really should have happened is, in this template, the size of disk in gigabytes should, actually, be changed to an integer instead of just a string value. So now we've called the New-AzureRmResourceGroupDeployment command, we've passed in all of these parameters, the resource group that we're deploying to, the ARM JSON template that we want to deploy, and then the input parameters for that JSON template. So what we can do now is go out to the Microsoft Azure portal, and we can, actually, watch the progression of this resource group deployment. So now I'm in the Azure portal, I'm gonna click on Resource groups. And I can filter my resource groups by simply typing a partial name. As you can see here, I've got a resource group called CloudAcademyRG, so I'm going to select that. It tells me exactly which subscription that belongs to. And it shows me the current status of it. Also, in the Summary section, I can see a list of all the resources that are being deployed into that resource group. And I can also monitor the deployment as time goes on. So if I click on the actual status of the resource group deployment, you'll see that I have a single deployment called azuredeploy. When I select that, I can scroll down to the bottom and, actually, see what resource is currently being provisioned. So right now, the network interface for the VM, the virtual network, the public IP address that's bound to the Nic, and the storage account have all been successfully created. And the last step is still in process, which is, actually, creating the Windows virtual machine. Now, if for some reason I decide that I don't, actually, want the resources in this resource group anymore, I can either delete the resource group directly here in the Azure portal, or, to save time, I can simply use PowerShell and call Remove-AzureRmResourceGroup Name CloudAcademyRG. And because this deployment is till, actually, running, the command prompt has hung. But I can just go ahead and hit Control + C, and after a few seconds, it will go ahead and return control to me. At that point, I can call the Remove-AzureRmResourceGroup command to prevent the continued provisioning of these resources and, actually, delete them so that I no longer have them in my Azure subscription.
Trevor Sullivan is a Microsoft MVP for Windows PowerShell, and enjoys working with cloud and automation technologies. As a strong, vocal veteran of the Microsoft-centric IT field since 2004, Trevor has developed open source projects, provided significant amounts of product feedback, authored a large variety of training resources, and presented at IT functions including worldwide user groups and conferences.