How to Build and Deploy Azure IaaS VMs with PowerShell

The whole point of using a cloud service is to be able to use it intensively for a brief period just when it is needed and then clear out all your work when you've finished. This means automation to make the process as quick and easy as possible. It is likely to mean creating a VM, provisioning it from scratch and spinning it up using PowerShell. Relax, grab the popcorn, and let Adam Bertram show you how he does it in Azure.

In my personal opinion, one of the most convenient aspects of public cloud-based services is the ability to host virtual machines (VMs). Hosting VMs in the cloud doesn’t just mean putting your VMs in someone else’s datacenter. It’s a way to achieve a scalable, low-cost and resilient infrastructure in a matter of minutes. What once required hardware purchases, layers of management approval and weeks of work now can be done with no hardware and in a fraction of the time. We still probably have those management layers though, unfortunately.

Microsoft Azure is one of those cloud-based services and is one that is in the lead pack along with Google and Amazon. Azure has made great strides lately in their Infrastructure as a Service (IaaS) service which offers hosting VMs in their cloud. Microsoft provides a few different ways to build and deploy VMs in Azure. You could choose to use the Azure portal, build VMs through Azure Resource Manager templates and PowerShell or simply use a set of PowerShell cmdlets to provision a VM and all its components from scratch. Each has its advantages and drawbacks. However, the main reason to use PowerShell is for automation tasks. If you’re working on automated VM provisioning for various purposes, PowerShell is the way to go.

Let’s look at how we can use PowerShell to build all of the various components that a particular VM requires in Azure to eventually come up with a fully-functioning Azure VM.

Before we get too far, you should know that currently there are two sets of PowerShell cmdlets that can be used to provision Azure VMs; the Azure Service Management (ASM or classic method) and the Azure Resource Manager (ARM) cmdlet. Each will get the job done but Microsoft is deprioritizing the ASM method and this may eventually be removed all together. Microsoft now advises everyone to provision VMs with ARM so this is what we’ll be focusing on today.

To get started, you’ll first obviously need an Azure subscription. If you don’t, you can always sign up for a free trial to play around. Once you have a subscription, I’m also going to be assuming you’re using at least Windows 8.1 with PowerShell version 4. Even though the commands I’ll be showing you might work fine on older versions of PowerShell, it’s always a good idea to work alongside of me with the same version, if possible.

You’ll also need to have the Azure PowerShell module installed. This module contains hundreds of various cmdlets and sub-modules. The one we’ll be focusing on is called Azure.RM. This contains all of the cmdlets we’ll need to provision a VM in Azure.

Building a VM in Azure isn’t quite as simple as New-AzureVM; far from it actually. Granted, you might already have much of the underlying infrastructure required for a VM but, in case you don’t, and this is the first time you’re building a VM in Azure, I’ll be going over how to build every component necessary and will be assuming you’re beginning to work from a blank Azure subscription.

At its most basic, an ARM VM requires eight individual components

  1. A resource group
  2. A virtual network
  3. A storage account
  4. A network interface
  5. A public IP address (if you need to access it from the Internet)
  6. An operating system
  7. An operating system disk
  8. The VM itself

In order to build any components between numbers 2 and 7, they must all reside in a resource group so we’ll need to build this first. We can then use it to place all the other components in. To create a resource group, we’ll use the New-AzureRmResourceGroup cmdlet. You can see below that I’m creating a resource group called MyResourceGroup and placing it in the West US datacenter.

Next, I’ll build the networking that is required for our VM. This requires both creating a virtual subnet and adding that to a virtual network. I’ll first build the subnet where I’ll assign my VM an IP address dynamically in the 10.0.1.0/24 network when it gets built.

Next, I’ll create my virtual network and place it in the resource group I just built. You’ll notice that the subnet’s network is a slice of the virtual network (my virtual network is a /16 while my subnet is a /24). This allows me to segment out my VMs.

Next, we’ll need somewhere to store the VM so we’ll need to build a storage account. You can see below that I’m building a storage account called mystorageaccount.

Once the storage account is built, I’ll now focus on building the public IP address. This is not required but if you’re just testing things out now it’s probably easiest to simply access your VM over the Internet rather than having to worry about setting up a VPN.

Here I’m calling it MyPublicIP and I’m ensuring that it’s dynamic since I don’t care what the public IP address is. I’m using many of the same parameters as the other objects as well.

Once the public IP address is created, I then need somehow to get connected to my virtual network and ultimately the Internet. I’ll create a network interface again using the same resource group and location again. You can also see how I’m slowly building all of the objects I need as I go along. Here I’m specifying the subnet ID I created earlier and the public IP address I just created. Each step requires objects from the previous steps.

Once we’ve got the underlying infrastructure defined, it’s now time to build the VM. First, you’ll need to define the performance of the VM. Here I’m choosing the lowest performance option (and the cheapest) with a Standard A3. This is great for testing but might not be enough performance for your production environment, however.

Next, we need to create the OS itself. Here I’m specifying that I need a Windows VM, the name it will be, the password for the local administrator account and a couple other Azure-specific parameters. However, by default, an Azure VM agent is installed anyway but does not automatically update itself. You don’t explicitly need a VM agent but it will come in handy if you begin to need more advanced automation capabilities down the road.

Next, we need to pick what image our OS will come from. Here I’m picking Windows Server 2012 R2 Datacenter with the latest patches. This will pick an image from the Azure image gallery to be used for our VM.

Next, we’ll attach the NIC we’ve built earlier to the VM and specify the NIC ID on the VM that we’d like to add it as in case we need to add more NICs later.

At this point, Azure still doesn’t know how you’d like the disk configuration on your VM. To define where the operating system will be stored, you’ll need to create an OS disk. The OS disk is a VHD that’s stored in your storage account. Here I’m putting the VHD in a vhds storage container (folder) in Azure. This step gets a little convoluted since we must specify the VhdUri. This is the URI to the storage account we created earlier.

Whew! We now have all the components required to finally bring up our VM. To build the actual VM, we’ll use the New-AzureRmVM cmdlet. Since we’ve already done all of the hard work ahead of time, at this point, I simply need to pass the resource group name, the location, and the VM object which contains all of the configuration we just applied to it.

Your VM should now be showing up under the Virtual Machines section in the Azure portal. If you’d like to check on the VM from PowerShell you can also use the Get-AzureRmVM cmdlet.

Now that you’ve got all the code required to build a VM in Azure, I suggest you build a PowerShell script from this. Once you’re able to bring this code together into a script, building your second, third or seventieth VM will be a piece of cake!