If you need to deploy a VM in Azure these days with PowerShell, you've got a few options. You can either create them via the Service Management (classic) model, or you can create them with Azure Resource Manager (ARM). Microsoft now recommends building all VMs using ARM. If you choose to deploy Azure VMs with ARM JSON templates, though, you're faced with a choice: using templates or not.

In a previous 4sysops article, I showed you quite a bit of PowerShell code to provision an Azure VM. This was how you could spin up a VM without templates. Let's now go into how you can cut those dozens of lines of code down to just one using the New-AzureRmResourceGroupDeployment cmdlet and a few parameters.

Why would you choose to build Azure VMs with templates, anyway?  Well, other than requiring significantly less PowerShell code, you also get to provision Azure VMs in a declarative way. What this means is that you don't have to create your own logic to say "if this VM exists, do this" or "if this storage account does not exist, do this." ARM templates simply allow you to tell Azure "I want this VM with this network, public IP address, storage account, etc.," and it just works, regardless of how many times you run it.

In a nutshell, building Azure VM with ARM templates consists of two rough steps: building a JSON template file and executing the New-AzureRmResourceGroupDeployment cmdlet, which then reads all of the logic inside of this JSON template file to feed the Azure API the parameters it needs to provision a VM.

The hard part is understanding the schema for the JSON template file and figuring out how each component that makes up an Azure VM fits together. We're not going to dive into the nuances of the JSON template file here. However, I am going to give you some pointers on how to build an example VM to get you started down that path if you ever need to build template from scratch.

To get started, I recommend first heading over to the Azure Quickstart Templates page. This will show you lots of example templates which you can open up to see how a template is built. One of the best start templates I found was a template by Corey Sanders where he demonstrates provisioning a simple Windows VM in Azure.

Once you have an example template and have begun learning more about the schema the JSON template files use, you can then go more in depth and either begin tweaking some example templates or even authoring your own.

At this time, the authoring tools are limited, but if you have Visual Studio, it provides some assistance as it understands the template schema. However, since ARM templates are so new, there is no fully-functional editor that allows you to build templates from scratch with a WYSIWYG interface, which would be much easier.

To deploy your first VM, I suggest you download the simple Windows VM template and modify it as you see fit. However, due to the template's schema, you can provide parameters for the template at runtime, so all environment attributes don't have to be hardcoded into the template itself.

To deploy a VM with the simple Windows VM template, you'd first need to decide on the parameter values the template has. This means that you will need to know the storage account to place the VM on, the Windows admin username and password, the unique DNS name for its public IP and the version of Windows to deploy with it. Once you have all of these values, it's simply a matter of specifying them as parameters to the New-AzureRmResourceGroupDeployment cmdlet.

New-AzureRmResourceGroupDeployment -Name 'SimpleVMDeployment' -ResourceGroupName MyResourceGroup -TemplateUri https://raw.githubusercontent.com/azure/azure-quickstart-templates/master/101-simple-windows-vm/azuredeploy.json -newStorageAccountname mystorageaccount -adminUsername myuser -adminPassword 'Myp#44wrd' –dnsNameForPublicIP 'dnsname' –windowsOsVersion '2012-R2-Datacenter'

In this example, I am downloading the azuredeploy JSON template from Github, passing into that template file at runtime the parameter values for newStorageAccountName, adminUsername, adminPassword, dnsNameForPublicIp and windowsOSVersion. All the other key attributes of VM creation are already stored in the template itself.

Once you open up a JSON template, you'll see exactly why it takes so much less code to deploy an Azure VM with templates. It's because all of the logic required has shifted from PowerShell code to the JSON. You'll find that just a simple Windows VM will require at least a 140 line template. However, you now have all of this logic bundled up into a single "answer" file, plus you get the declarative nature of templates, which is a win-win.

If you're just getting started deploying Azure VMs with ARM, I suggest you first look at templates. It might be a little harder to understand at first but will pay off in the long run by preventing lots of PowerShell coding and by providing a platform agnostic way of building Azure VMs with JSON.

Subscribe to 4sysops newsletter!

In my next article I will discuss a simple example that demonstrates how to assign a public IP address with a JSON template.


Leave a reply

Please enclose code in pre tags

Your email address will not be published. Required fields are marked *


© 4sysops 2006 - 2021


Please ask IT administration questions in the forums. Any other messages are welcome.


Log in with your credentials


Forgot your details?

Create Account