Lab: How to Create Infrastructure with ARM Templates

March 29, 2017 The Editors

In this lab, you’ll be deploying a VM and supporting infrastructure from a template. This is going to be wholly separate infrastructure from the previous lab, as linking templates and manually-created resources can be challenging in a lab situation.

This lab requires you to have installed Visual Studio Code. Any text editor will work, but VS Code has a number of features which make it easier to work with ARM Templates. You will also want to install the Azure Resource Manager extension. To do this, in open Visual Studio Code, press Ctrl-P, and type “ ext install azurerm-vscode-tools ” and press enter.

You will also need the Azure PowerShell cmdlets installed to do this. If you are on Windows 10, installing the cmdlets is super-easy: open an administrative PowerShell window and type:

This will install the Azure modules. You may need to also change the default ExecutionPolicy:
Set-ExecutionPolicy AllSigned
If you’re on Windows 7, you need to download and install from this link:

Next, log into your Azure account. Keep this window open.

The folder contains four files:

  • azureDeploy.json
  • azureDeploy.params.json
  • metadata.json

The and azureDeploy.params.json files are stylistic, and good practice; the metadata.json is required for the specific repository – for searchability on is parsed by GitHub into the description of the template you can read lower down on the page. The azureDeploy.json file is the actual template, and the azureDeploy.params.json can be used to provide values for the parameters defined in the azureDeploy.json file. This is useful for re-deployments, as you have a perfect record of the data passed into the template.

Click on the azureDeploy.json file, and have a look through the file. Note the structure (parameters, variables, and resources).

Click the “Raw” button at the top right side of the file view.


Save the file locally (Ctrl-S – and ensure it saves as a .json file, not .txt) and open with VS Code. You should now have something like this:


Locate the variables section, and identify the “storageAccountName” variable. Note that it has a value containing ‘uniquestring’. This is a function that is very useful for quick demos, as it generates a unique string every time the template is deployed. However, it makes behaviour slightly unpredictable, so change the value to something containing your name, or something else unique:

The trailing comma is very important, as are the quotes you use. There is a difference between  ,    and " . If you’re using VS Code, this is probably fine; however, some applications automatically “correct” this to use the prettified version. You should have something that looks like this:


Scroll down to the first resource. Note that the location value refers to the Resource Group that you’re deploying to, and is dynamically referenced. Good practice is to hard-code as few items as possible – if you wanted to change the location, good practice would be to change this to reference a parameter, which could be passed in at time of deployment. Otherwise, each time the location changes, the template would have to be edited directly. Don’t make any changes here.


Now, we will deploy the VM. Bring up your PowerShell window and run the following command, replacing the pieces in <> with your unique input. DNSLabelPrefix needs to be all lowercase (replace the <> as well, so you’ll get something like -TemplateFile "c:\Users\me\azuredeploy.json

Open the Azure Portal. Navigate to the VMs Resource Group (use the search bar at the top, or list the Resource Groups using the link on the sidebar). Click on the Deployments status bar (it should say ‘running’):

Click on the deployment “myFirstDeploy” – this may be different if you specified a different name above, in the New-AzureRMResourceGroupDeployment command. Here, you can see what is being deployed, what has already been deployed, and some of the parameters that were passed in. This is useful for troubleshooting – it’s one of the places you can come to view errors. You can refresh the page to view progress. Once it’s completed, or if it’s taking too long, open up the template again.

Find the VM resource, and the vmSize parameter (approximately line 132). Change this from Standard_A1 to Standard_D2:


Depending on the datacenter you’re using, you may have to use Standard_D2_v2. The Canadian Datacenter, for example, only has the v2; most US datacenters have both. You can determine this information programmatically using Get-AzureRmVMSize -Location "Canada East" , replacing Canada East with the desired datacenter’s name.

Go back to the portal and check the progress of your deployment. Once the deployment is successful (Deployments pane in Azure says ‘completed’), save the template, and re-run the command, specifying a different “Name” parameter


You cannot change most of the input parameters now – the VM OS version, for example, is fixed now, as is the admin username/password.

Return to the Resource Group view, and look at the new deployment (mySecondDeploy). Note that the existing components are untouched, and don’t take any time – the deployment engine skips past this. However, the VM is redeploying with a new size.


Navigate to the Resource Group View, and click on the VM object that was just created. Click the ‘Connect’ button, and the browser will download an RDP file. You may connect to the server now.


The connect button only appears when there is a clear path from a public IP to the VM – i.e. the VM has a public IP address, and a Network Security Group rule to allow access via port 3389 from the Internet. There is nothing ‘special’ about this file – it only contains the IP of the server.

About the Author

The Editors

The Softchoice editorial team consists of industry professionals with range of cloud and IT services experience. Together they provide editorial oversight and creative direction for all hub content. To contact the editors, email

More Content by The Editors
Previous Article
Say Hello to Azure’s Arsenal of Backup and Disaster Recovery Solutions
Say Hello to Azure’s Arsenal of Backup and Disaster Recovery Solutions

We used to just worry about unlikely natural disaster and communication breakdowns when planning for backup...

Next Article
Cloud Security - A shared responsibility
Cloud Security - A shared responsibility

Find out what Microsoft and Amazon will and won't do for you.