In this lab we will use Azure Resource Manager templates from different sources and with different deployment options, to deploy and configure virtual machines and infrastructure to Azure.

DevOps MPP Course Source


Lab Tasks:

  • Deploy a ‘QuickStart’ ARM Template from GitHub
  • Generate an ARM template based on an existing resource group via the Portal.
  • Deploy a template using Powershell that removes all resources in a resource group
  • Edit and Deploy template via the Azure Portal
  • Deploy ARM Templates using Azure CLI 2.0
  • Create and Deploy an ARM template using Visual Studio

Estimated Lab Time:

  • approx. 80 minutes

Task 1: Deploy a ‘QuickStart’ ARM Template from GitHub

  1. Go to

    RG resources

  2. Scroll through the template options that are available, and briefly read some of the opening details in the

  3. You can select any template for this exercise, but we’ll choose 101-vm-simple-linux,

    RG resources

  4. Once in the location click on Deploy to Azure.

    RG resources

  5. Once signed into your Azure subscription, fill in the Deploy a simple Linux VM pane details as follows:
    • Subscription: < your own subscription >
    • Resource group: < enter a new name i.e. qslinuxvmrg>
    • Location: < choose your nearest location >
    • Admin Username: adminuser
    • Admin password: Passw0rd01234
    • Dns Label Prefix: < enter a value i.e. linuxqsdeploy
    • Ubuntu OS Version: < accept the default >
    • Check the box to agree to the terms and conditions and click Purchase

    RG resources

  6. Open the resource group and in the *Overview wait until the Deployments goes from Deploying to Succeeded. It will take a few minutes.

    RG resources

    RG resources

  7. You can verify the deployment by connecting to the VM by opening the VM, clicking Connect and copying the ssh command listed i.e.

     ssh adminuser@
  8. Connect to the Linux VM, on a windows OS you can use PuTTY or Bash on Ubuntu on Windows. If you have any problems logging in, you can reset the password in the VM pane on SUPPORT + TROUBLESHOOTING > Reset password, and try again logging on again, you could also setit up to use ssh keys, a public/private key pair.

Quick start templates from github can be used to get up and running quickly. They can also be used as starter templates and customised to suit your needs. They are especially useful in more complex deployment scenarios, such as Azure Container Service (ACS), SharePoint Server Farms etc and have numerous Windows and Linux deployment scenarios and options available.

You can also download the templates once they are imported into Azure and saved locally for future use.

Task 2: Generate an ARM template based on an existing resource group via the Portal.

  1. From the Azure portal, navigate to the rg1 resource group, or whatever name you called the resource group generated in the Module 1 lab Azure Automation Runbook Deployments that contains your deployed resources, such as VMs, LB, PIP etc i.e. not the resource group containing you Automation account and assets.

    Note: All resources in the resource group will be deleted, so ensure you have the correct resource group.

    It should contain the resources as in the screenshot below.

    RG resources

Also, if you do not have the the deployed resources avaliable from Module 1 and do not have the time to go back and perform that lab now but wish to continue

  1. On the resource group blade, click Automation script. This will generate a template containing definition of all resources contained within the resource group.

    RG resources

  2. On the Template tab, click on Parameters, and scroll down through the items in the viewing pane also. Likewise, do the same for the Variables and Resources sections. This is just to get a feel for the structure and content.

  3. Scroll through the remaining tabs i.e. Parameters, CLI, PowerShell, .NET and Ruby.

  4. Click Add to library and enter a valid value for Name and Description and click Save

  5. Click Add to library, use the following details
    • Name: resource group name-ARMTemplate i.e. rg1-ARMTemplate
    • Description: rg1-ARMTemplate

      and click Save. This will store the template within your Azure subscription.

      RG resources

      RG resources

  6. View the template in the Azure Portal by going to More Services > and typing Templates in the search box and opening the template

    RG resources

    RG resources

Task 3: Deploy a template using Powershell that removes all resources in a resource group.

You can deploy an ARM Template a number of different ways, some of which are

We will deploy via a couple of those methods in this lab but you can view the references above for more details or options we do not cover in this lab.

  1. On your local machines, create the following Azure Resource Manager template and save it as EmptyTemplate.json.

    Note: Alternatively you can copy a version of the Emptytemplate.json file from github at and use that instead of creating the .json file yourself.

    Also, available in this GitHub location is the file Task2_PowerShell_commands.ps1 which contains the powershell commands which are run in this lab task, steps 2 to 7. You can download this file locally, open it in the PowerShell ISE, highlight the individually commands as needed and hit F8 to run them one at a time, modifying them if needed to specify your local folder locations.

    "$schema": "", 
    "contentVersion": "", 
    "parameters": { }, 
    "variables": { }, 
    "resources": [ ] 
  2. On your lcoal machines, start Windows PowerShell or the Windows PowerShell ISE as Administrator

  3. From Windows PowerShell, sign in to your Azure subscription by running the command below
  4. When prompted, enter the credentials you used for your Azure subscription.

    RG resources

  5. Still in Windows PowerShell, define a variable specifying the location of the JSON template by running one of the commands below

    #If you placed the folder in "mydocuments", or some other system defined location, you can run the below command
    $template = [environment]::getfolderpath(mydocuments) + "\EmptyTemplate.json" 
    #otherwise you can just use the full path and define the variable that way, as below
    $template = "C:\Labfiles\Devops200.2x-InfrastructureasCode\Mod03" +"\EmptyTemplate.json"
  6. From Windows PowerShell, deploy the template to the rg1 resource group, or whatever your resource group is called, by running the command below,

    New-AzureRmResourceGroupDeployment -ResourceGroupName 'rg1' -Mode Complete -TemplateFile $template -Force -Verbose

    RG resources

  7. Wait until the command completes. The resource group should still be in place but all resources within it removed.

Note: Note that you could also delete the resource group in a single step, however, this would delete any objects associated with that resource group, such as Role Based Access Control, assignments, policies, or locks. In some scenarios, you might want to preserve resource group level settings.

Task 4: Edit and Deploy template via the Azure Portal

  1. From the Azure portal, navigate to Templates blade and, on the list of templates, click rg1-ARMTemplate, or whatever you called your template file earlier.

  2. From the rg1-ARMTemplate blade, click Deploy. This will display the Custom deployment blade.

    RG resources

  3. On the Custom deployment blade, click Edit template.

  4. On the Edit template blade, remove the resources and parameters corresponding to the Windows PowerShell DSC extension. Click on the items in the parameters and resources list, as per the screenshots below, and then delete the full items between the corresponding curly brackets {} in the pane on the riught hand side in the portal. When the section is highlighted that you want to remove, just press delete.

    We remove the Windows PowerShell DSC extension related entries since they are not deployed via the template but instead via Azure Automation.

    RG resources

    RG resources

  5. Add passwod details to the parameter values by going to the parameters section and adding the code below as per the screenshot

     "virtualmachines_vm1_adminpassword": {
         "defaultValue": "Pa55w.rd1234",
             "type": "securestring"
     "virtualmachines_vm2_adminpassword": {
         "defaultValue": "Pa55w.rd1234",
             "type": "securestring"

    RG resources

  6. Add password details to the resource code definitions by going to the osProfile sections in the vm1 definition, and pasting the below line

     "adminPassword": "[parameters('virtualmachines_vm1_adminpassword')]",

    RG resources

  7. Add password details to the resource code definitions by going to the osProfile sections in the vm2 definition, and pasting the below line

     "adminPassword": "[parameters('virtualmachines_vm1_adminpassword')]",

    RG resources

  8. Remove all values defined in the “dependsOn” definition for each resource. i.e. search for dependsOn and remove any entries where they are leaving just the brakects, as in the below example and screenshots

     "dependsOn": [
     "[resourceId('Microsoft.Compute/availabilitySets', parameters('availabilitySets_rg2_avset1_name'))]",
     "[resourceId('Microsoft.Storage/storageAccounts', parameters('storageAccounts_rg2vm119719146_name'))]",
     "[resourceId('Microsoft.Network/networkInterfaces', parameters('networkInterfaces_rg2vm1_nic1_name'))]"

    remove all values so it loks like the below

     "dependsOn": []

    RG resources

    RG resources

    This needs to be done as runbook has defined dependencies from when it was run. If you do not remove the dependsOn values, you will receive errors stating there are ..Circular Dependancies.. when you go to run the template, i.e. resources need to be available before another resource can be created.

  9. Click Save.

  10. Back on the Custom deployment blade, use the following settings:

    • Resource group = rg1 (or whatever you called your resource group earlier),
    • virtualmachines_vm1_adminpassword = Pa55w.rd1234 (this value should already be populated now if you edited as above)
    • virtualmachines_vm1_adminpassword = Pa55w.rd1234 (this value should already be populated now if you edited as above)

    and click I agree to the terms and conditions stated above, and click Purchase.

    If you do receive errors, try work through them one by one, editing, saving and re-running.

  11. Wait for the deployment to complete.

    Once the deployment completes, to apply the DSC configuration, you could use Azure Automation, just as you did in the second lab of this course.

    Alternatively, you could use Azure VM DSC extension on the VMs you are deploying to automatically set them up as Azure Automation DSC-managed nodes, which will apply the DSC configuration automatically.

Task 5: Deploy ARM Templates using Azure CLI 2.0

In this task we will deploy a Template using two different scenarios with Azure CLI 2.0

  • Scenario 1: …using remote source
  • Scenario 2: …from local source using separate parameters file.

Scenario 1: Deploy a Template for Azure CLI 2.0 using remote source

The following steps can be performed on Windows, Linux or macOS.
  1. On your local machine, ensure Azure CLI 2.0 is installed. If it is not installed, follow the steps on the following page for your specific environment

  2. On your local machine, start the Azure CLI and login into Azure using the command

     az login
  3. Create a resource group to deploy into, using your preferred values.

     az group create --name rg4 --location eastus

    If the resource group is not available when you deploy it will return an error saying

    Resource group “xyz” could not be found

  4. You can deploy templates, from a local source, a public location or a private repository, once the template json is available. We will deploy a template directly from github, so this is a publicly available template. Run the following command

     az group deployment create --resource-group rg5 --template-uri "
     linux/azuredeploy.json " --parameters "{\"adminUsername\": {\"value\":
     \"adminuser\"}, \"adminPassword\": {\"value\": \"Passw0rd0987123\"},
     \"dnsLabelPrefix\": {\"value\": \"simplelinux\"}}"
  5. Note the following

    • Note the URI value, the has been replaced with and also note the master value before the template folder name. If you browse to the file in github and coy the URL form there it may also include a /tree or /branch in the URL. This needs to be removed if it is present, and only the folder master should be specified, as in the URI above, otherwise it will give a 404 not found error when the command is run.

    • You can also validate a template before deployment by using the command

        az group deployment validate ….etc

      If no errors are returned in the output it has been successfully validated, rerun the command above a verify the output.

    • If you do not specify the –parameters switch, you will be prompted to enter the values as the script runs.

    • The parameter values as listed in the command are case sensitive i.e. if you use

        --parameters "{\"adminusername\": 

      instead of

        --parameters "{\"adminUsername\":

      you will receive an error.

Scenario 2: Deploy a Template for Azure CLI from local source using separate parameters file.

  1. Download the 101-vm-simple-linux to your local machine, it will have four files
    • azuredeploy.json
    • azuredeploy.parameters.json
    • metadata.json
    • README…
  2. The two files we are interested in are
    • azuredeploy.json which is the ARM template, a
    • azuredeploy.parameters.json which has the parameter values separated out from the template
  3. Open the azuredeploy.parameters.json file in Visual Studio code, or some such editor, modify the below values and save the file
    • adminusername=adminuser
    • adminPassword=Pa$$w0rd0987123
    • dnsLabelPrefix=simplelinux
  4. At the Azure CLI command go to the folder where the .json files are located and run the following commands
     az group create --name rg6 --location eastus

    followed by

     az group deployment create --resource-group rg5 --template-file azuredeploy.json --parameters azuredeploy.parameters.json
  5. Verify that the deployment was successful

  6. Further details about the Azure CLI deployment are available in the help file, available by running the command az group deployment create –help , and also here

Task 6: Create and Deploy an ARM template using Visual Studio.

For this exercise, you will need Visual Studio 2017. You can download Visual Studio Community Edition free from

  1. On your local machine, once Visual Studio 2017 is installed and available, launch Visual Studio 2017.

  2. From the File menu, click New Project. In the New Project dialog box, navigate to Templates > Visual C# > Cloud and click Azure Resource Group from the list of installed templates.

  3. Set the name of the project and solution to AzureResourceGroup1 and set the location to the Documents folder. Ensure that the checkbox Create directory for solution is enabled and click OK.

  4. In the Select Azure Template dialog box, click Windows Server Virtual Machines with Load Balancer and click OK.

The template implements an internal load balancer (rather than an external one, which you implemented via Azure Automation earlier, however the purpose of this exercise is to simply illustrate the process of authoring and deploying a template by using Visual Studio.

  1. In the Solution Explorer window, click LoadBalancedVirtualMachine.json

  2. In the JSON Outline window, expand the Parameters section and click imageSKU.

  3. Modify the imageSKU section so it looks as follows:

    "imageSKU": { 
      "type": "string", 
      "defaultValue": "2016-Datacenter-Server-Core", 
      "allowedValues": [ 
      "metadata": { 
        "description": "The Windows version for the VM" 

  1. Note: The change made is for the defaultValue and adding that default value to the allowedValues list i.e. 2016-Datacenter-Server-Core

  2. Change the value of the “defaultValue” property of the vmSize parameter to “Standard_A3”.

  3. Go to View > Other Windows > JSON Outline to display the JSON Outline window, which should display on the left hand side of the screen beside the template LoadBalancedVirtualMachine.json

  4. Right-click the resources node in the JSON Outline window and click Add New Resource.

  5. In the Add Resource dialog box, scroll down, locate and click PowerShell DSC Extension. In the Name text box, type WebServer and click Add. If you get an error click OK to continue.
  6. In the Solution Explorer window, note a newly added DSC folder with the file named WebServer.ps1. Double-click WebServer.ps1.

  7. Replace the content of WebServer.ps1 with the following:

    Configuration Main 
    Param ( [string] $nodeName ) 
    Import-DscResource -ModuleName PSDesiredStateConfiguration 
    Node $nodeName 
        WindowsFeature WebServerRole 
        Ensure = 'Present' 
        Name = 'Web-Server' 
        IncludeAllSubFeature = $true 
  8. Click Save All in the toolbar.

  9. In the Solution Explorer window, right-click the project and click Deploy > New.

  10. In the Deploy to Resource Group dialog box, click Add an account and sign in with your Azure account details.

  11. In the Deploy to Resource Group dialog box, ensure that the subscription and resource group drop down-list entries contain the correct values representing the target Azure subscription

  12. Choose Create New and in the Create resource Group dialogue enter the values below and click Create
    • Resource group name= vs1rg
    • Resource group location = eastus
  13. Click Edit Parameters.

  14. In the Edit Parameters dialog box, specify the following:
    • adminUsername: Student
    • adminPassword: Pa55w.rd1234
  15. Click Save passwords as plain text in the parameters file and click Save.

  16. Back in the Deploy to Resource Group dialog box, click OK to start deployment

  17. Monitor the progress in the Output window within the Visual Studio interface and also verify it has successfully deployed to your Azure Subscription.

Note: You may want to delete all the resources you deployed in this lab to prevent being billed for Azure resources that are running, which you are not using.


You have successfully deployed configured resources in Azure using ARM templates. You successfully completed the following tasks

  • Deploy a ‘QuickStart’ ARM Template from GitHub
  • Generate an ARM template based on an existing resource group via the Portal.
  • Deploy a template using Powershell that removes all resources in a resource group
  • Edit and Deploy template via the Azure Portal
  • Deploy ARM Templates using Azure CLI 2.0
  • Create an ARM template by using Visual Studio