In this lab we will create an Azure Automation Account, and configure automation assets in Azure. We will then use a Windows PowerShell-based runbook to deploy two load balanced Virtual Machines (VMs) to Azure, in parallel.

DevOps Course Source:

This lab is used in the following courses.

Pre-requisites:

  • A Microsoft account
  • An Azure Subscription

Lab Tasks:

  • Create an Azure Automation Account (Azure Portal)
  • Update AzureRM modules (PowerShell Gallery)
  • Configure Automation Variables (Azure Portal)
  • Create and run an Automation Windows PowerShell, workflow-based, textual runbook that provisions two load-balanced Azure VMs, in parallel (Azure Portal)
  • Create and run an Automation Windows PowerShell-based textual runbook that deprovisions the lab environment (Azure Portal)

Estimated Lab Time:

  • Approx. 45 minutes

Task 1: Create an Automation Account (Azure Portal)

  1. Sign in to Azure Portal. From the menu on the left, choose All services. Type automation into the Filter text entry field, and select Automation Accounts.

    Screenshot of the Azure Portal home screen with four areas highlighted. Each highlighted area corresponds to a textual description of a step in the process for creating an Automation Account.

  2. In the Add Automation Account pane, create a new Automation Account with the following settings:

    • Name: DevOpsLabs1.
    • Subscription: Choose your Azure subscription.
    • Resource Group: Select DevOpsLab1RG if you already created a Resource Group with this name in a previous lab. If you have not already created a Resource Group, choose Create new, and enter DevOpsLab1RG as the name of the new Resource Group.
    • Location: Select an Azure region close to your lab location.
    • Create Azure Run As Account: Choose Yes.

    Screenshot of the Add Automation Account pane in Azure Automation portal. The image shows the setting fields that need to be completed as described previously.

    Select the Create button to create your new DevOpsLabs1 Azure Automation Account.

  1. Go to the Powershell Gallery and search for the AzureRM module.

    Screenshot of the PowerShell Gallery home page.

    Screenshot of the PowerShell Gallery showing the results of a keyword search for the term 'AzureRM'. The AzureRM module is shown highlighted among the search results, to illustrate how to locate AzureRM from among the search results.

    Note: The newer Az module is a replacement for the AzureRM module`. The Az module has feature parity with the AzureRM module, but there are some minor inconsistences. For the purposes of this lab, we use the AzureRM module because it supports provisioning two VMs from a Windows PowerShell-based runbook in parallel. At the time of writing (February 2019), Azure Automation does not support using the Az module to perform these operations.

    For more information about the Az module, see the page Introducing the new Azure PowerShell Az module.

  2. Open the AzureRM page and locate version 5.5.0.

    Note: At the time of writing, February 2019, the current version of the AzureRM module a is 6.13.1. AzureRM version 6.13.1 breaks the lab file workflow. This lab was tested successfully with version 5.5.0. You must use version 5.5.0 of the AzureRM module. Later versions of the module may work, but have not been tested fully. Using a later version may cause your workflow to fail. If your workflow fails, you should check that you are using version 5.5.0 of the AzureRM module.

    Screenshot of the PowerShell Gallery showing the version history of the AzureRM module. Version 5.5.0 of AzureRM is highlighted, to illustrate the correct version of AzureRM to choose.

  3. Go to the Azure Automation tab and select Deploy to Azure Automation

    Screenshot of an overview of the AzureRM module version 5.5.0 within PowerShell Gallery. The Deploy to Azure Automation button is highlighted inside the Azure Automation tab, to illustrate how to deploy the AzureRM from PowerShell Gallery into Azure Automation.

  4. You will be brought into Azure. If prompted, enter your Azure Automation Account details. Choose your Azure Automation DevOpsLabs1 account and select OK.

    Screenshot of the Import Module area of the Automation Account pane inside Azure portal. The DevOpsLabs1 Automation Account is highlighted, to illustrate how to select your Automation Account. The AzureRM module is shown as ready for importing into the DevOpsLabs1 Automation Account.

  5. Select the Notifications icon in the Azure dashboard, and choose Deployment in progress.

    Screenshot of the Notifications pane in Azure Portal. The Notifications icon is highlighted, to illustrate how to access the Notifications pane from the top menu in Azure Portal. The Deployment in progress message is highlighted, to illustrate how to access the runbook deployment overview pane.

  6. You will be brought to the Azure runbook overview pane. From within the pane, you can view the progress of your update to the AzureRM module. Azure will update and deploy all modules associated with AzureRM. Be advised that the update and deployment can take up to 30 mins to complete.

    Screenshot of the Azure runbook overview pane in Azure Portal for the deployment of the AzureRM module. The image shows the message 'Your deployment is underway'.

  7. Once the update and deployment are complete, you need to check the details of the AzureRM module and associated modules. From the main menu on the left, choose All resources, and select your Azure Automation DevOpsLabs1 Automation Account.

    Screenshot of the All Resources section within the main menu in Azure Portal. The All Resources filter button and DevOpsLabs1 Automation Account resource are highlighted, to illustrate how to access the DevOpsLabs1 Automation Account from Azure Portal.

  8. From within the Automation Accounts pane for your DevOpsLabs1 Automation Account, scroll down to the Shared Resources section, and choose Modules.

    Screenshot of the Automation Accounts pane for the DevOpsLabs1 Automation Account. The Modules blade is highlighted to illustrate how to access a list of the resources contained within the DevOpsLabs1 Automation Account from the Automation Accounts pane.

  9. Scroll down through the list of modules and locate modules with the prefix AzureRM. Verify that the module versions match the following versions.

    • AzureRM version = 5.5.0
    • AzureRM.Network version = 5.3.0
    • AzureRM.Profile version = 4.4.0

    Screenshot of a list of resources that are contained within the DevOpsLabs1 Automation Account. The three previously described AzureRM-related are highlighted to illustrate how to check the version numbers of the relevant AzureRM modules.

Note: You can also update the AzureRM module from within Azure Automation. However, we updated using the PowerShell Gallery to allow us to specify the version of AzureRM to use.

Task 3: Configure Automation Variables (Azure Portal)

  1. In Azure Portal, choose Variables. Variables are listed under the Shared Resources section in the Automation Accounts pane for your DevOpsLabs1 Automation Account.

    Screenshot of the Variables pane, shown under the Shared Resources section of the DevOpsLabs1 Automation Account. Three areas of the Variables pane are highlighted which illustrate how to locate the Add a variable button within the Variables pane.

  2. Select Add a variable. Create and configure six new variables with the following values.

    • Name: VM1Name
      • Description: Leave empty
      • Type: String
      • Value: vm1
      • Encrypted: No
    • Name: VM2Name
      • Description: Leave blank
      • Type: String
      • Value: vm2
      • Encrypted: No
    • Name: ResourceGroupName
      • Description: Leave blank
      • Type: String
      • Value: Choose a name for the new Resource Group that is different from the DevOpsLab1RG Resource Group you created earlier in this lab. Use a short name such as rg1, for example. The name of the new Resource Group will be appended to the name of any resources you assign to the new Resource Group. Some resource types can only use a limited number of characters in the resource name.
      • Encrypted: No
    • Name: UserName
      • Description: Leave blank
      • Type: String
      • Value: Student
      • Encrypted: No
    • Name: Password
      • Description: Leave blank
      • Type: String
      • Value: Pa55w.rd1234
      • Encrypted: No
    • Name: Location
      • Description: Leave blank
      • Type: String
      • Value: The short-name for the location your DevOpsLabs1 Automation Account is using, without spaces. For example, East US becomes eastus.
      • Encrypted: No

Note: You can get Azure location names by running one of the following commands either in the Azure CLI 2.0 or in Windows PowerShell (with the Azure PowerShell module installed).

  • Azure Location list (requires the Az module)
  • Get-AzureRmLocation (requires the AzureRM module)

You can also run the commands in Azure Cloud Shell, for details see the page Quickstart for PowerShell in Azure Cloud Shell.

Alternatively, you can use one of the Region Names listed on the page Azure Locations. Remove any white spaces if you add a Region Name as a value to your Location Variable. For example, East US will become eastus.

For information about using PowerShell with Azure see the page Overview of Azure PowerShell.

Task 4: Create and run an Automation Windows PowerShell workflow-based textual runbook that provisions two load-balanced Azure VM in parallel (Azure Portal)

Choose one of the following two options to complete Task 4:

  • a) Copy the code that is provided below and paste it into a new runbook, by following steps 1 to 3, below.

    or

  • b) Import a pre-existing runbook that contains the code provided below, by following steps 4 to 6 below.

    Note: Option b) is recommended, as this option reduces the risk of encountering formatting errors that are associated with copying and pasting code.

  1. From the Azure Portal, in the Automation Account you created earlier, go to Process Automation > Runbooks. Choose Create a runbook.

    Screenshot of the Process Automation section of Azure Portal. Three previously described display elements used for creating a new runbook are highlighted.

  2. Enter the following values into the fields provides, then select Create.

    • Name: Provision-lab-textual-workflow
    • Runbook type: PowerShell Workflow

    Screenshot of the Create a runbook blade. Three previously described data entry fields are highlighted to illustrate the display elements that require user input, to configure and create a new runbook.

  3. Copy the following code and paste it into the Edit PowerShell Workflow Runbook pane. When you have pasted the code, proceed to Step 7.

    Screenshot of the Edit PowerShell Workflow Runbook pane. The previously described display element is highlighted to illustrate where to paste the copied code to, within the Edit PowerShell Workflow Runbook pane.

    
     workflow Provision-lab-textual-workflow
     {
     $c = Get-AutomationConnection -Name 'AzureRunAsConnection'
     Add-AzureRmAccount -ServicePrincipal -Tenant $c.TenantID -ApplicationID $c.ApplicationID -CertificateThumbprint $c.CertificateThumbprint
     $vm1Name = Get-AutomationVariable -Name 'VM1Name'
     $vm2Name = Get-AutomationVariable -Name 'VM2Name'
     $resourceGroupName = Get-AutomationVariable -Name 'ResourceGroupName'
     $location = Get-AutomationVariable -Name 'Location'
     $username = Get-AutomationVariable -Name 'UserName'
     $password = Get-AutomationVariable -Name 'Password'
    
     $vmSize = 'Standard_A1'
    
     $vnetName = $resourceGroupName + '-vnet1'
     $vnetPrefix = '10.0.0.0/16'
     $subnet1Name = 'subnet1'
     $subnet1Prefix = '10.0.0.0/24'
    
     $avSetName = $resourceGroupName + '-avset1'
    
     $publisherName = 'MicrosoftWindowsServer'
     $offer = 'WindowsServer'
     $sku = '2016-Datacenter'
     $version = 'latest'
     $vmosDiskSize = 128
    
     $publicIpvm1Name = $resourceGroupName + $vm1Name + '-pip1'
     $publicIpvm2Name = $resourceGroupName + $vm2Name + '-pip1'
    
     $nic1Name = $resourceGroupName + $vm1Name + '-nic1'
     $nic2Name = $resourceGroupName + $vm2Name + '-nic1'
    
     $vm1osDiskName = $resourceGroupName + $vm1Name + 'osdisk'
     $vm2osDiskName = $resourceGroupName + $vm2Name + 'osdisk'
    
     ##$resourceGroup = New-AzureRmResourceGroup -Name $resourceGroupName -Location $location
    
     InlineScript {
    
     $resourceGroup = Get-AzureRmResourceGroup -Name $using:resourceGroupName -ErrorAction SilentlyContinue
     if(!$resourceGroup)
     {
         Write-Host "Creating resource group '$resourceGroupName' in location $location";
         New-AzureRmResourceGroup -Name $using:resourceGroupName -Location $using:location -Verbose
     }
     else{
         Write-Host "Using existing resource group '$resourceGroupName'";
     }
     }
    
     $securePassword = ConvertTo-SecureString -String $password -AsPlainText -Force
     $credentials = New-Object System.Management.Automation.PSCredential -ArgumentList $username,$securePassword
    
     $avSet = New-AzureRmAvailabilitySet -ResourceGroupName $resourceGroupName -Name $avSetName -Location $location -PlatformUpdateDomainCount 5 -PlatformFaultDomainCount 3
    
     InlineScript {
         $subnet = New-AzureRmVirtualNetworkSubnetConfig -Name $using:subnet1Name -AddressPrefix $using:subnet1Prefix
         $vnet = New-AzureRmVirtualNetwork -Name $using:vnetName -ResourceGroupName $using:resourceGroupName -Location $using:location -AddressPrefix $using:vnetPrefix -Subnet $using:subnet
         Set-AzureRmVirtualNetwork -VirtualNetwork $vnet
     }
    
     Parallel
     {
     InlineScript {
         $vnet = Get-AzureRmVirtualNetwork -Name $using:vnetName -ResourceGroupName $using:resourceGroupName
    
    
         $publicIpvm1 = New-AzureRmPublicIpAddress -Name $using:publicIpvm1Name -ResourceGroupName $using:resourceGroupName -Location $using:location -AllocationMethod Dynamic
         $nic1 = New-AzureRmNetworkInterface -Name $using:nic1Name -ResourceGroupName $using:resourceGroupName -Location $using:location -SubnetId $vNet.Subnets[0].Id -PublicIpAddressId $publicIpvm1.Id
         $vm1 = New-AzureRmVMConfig -VMName $using:vm1Name -VMSize $using:vmSize -AvailabilitySetId $using:avSet.Id
    
     $randomnumber1 = Get-Random -Minimum 0 -Maximum 99999999
     $tempName1 = $using:resourceGroupName + $using:vm1Name + $randomnumber1
     $nameAvail1 = Get-AzureRmStorageAccountNameAvailability -Name $tempName1
     If ($nameAvail1.NameAvailable -ne $true) {
         Do {
             $randomNumber1 = Get-Random -Minimum 0 -Maximum 99999999
             $tempName1 = $using:resourceGroupName + $using:vm1Name + $randomnumber1
             $nameAvail1 = Get-AzureRmStorageAccountNameAvailability -Name $tempName1
         }
         Until ($nameAvail1.NameAvailable -eq $True)
     }
     $storageAccountName1 = $tempName1
     $storageAccount1 = New-AzureRmStorageAccount -ResourceGroupName $using:resourceGroupName -Name $storageAccountName1 -SkuName "Standard_LRS" -Kind "Storage" -Location $using:location
    
     $vm1 = Set-AzureRmVMOperatingSystem -VM $vm1 -Windows -ComputerName $using:vm1Name -Credential $using:credentials -ProvisionVMAgent EnableAutoUpdate
     $vm1 = Set-AzureRmVMSourceImage -VM $vm1 -PublisherName $using:publisherName -Offer $using:offer -Skus $using:sku -Version $using:version
     $blobPath1 = 'vhds/' + $using:vm1osDiskName + '.vhd'
     $osDiskUri1 = $storageAccount1.PrimaryEndpoints.Blob.ToString() + $blobPath1
     $vm1 = Set-AzureRmVMOSDisk -VM $vm1 -Name $using:vm1osDiskName -VhdUri $osDiskUri1 -CreateOption fromImage
    
     $vm1 = Add-AzureRmVMNetworkInterface -VM $vm1 -Id $nic1.Id
     New-AzureRmVM -ResourceGroupName $using:resourceGroupName -Location $using:location -VM $vm1
     }
     InlineScript {
     $vnet = Get-AzureRmVirtualNetwork -Name $using:vnetName -ResourceGroupName $using:resourceGroupName
     $publicIpvm2 = New-AzureRmPublicIpAddress -Name $using:publicIpvm2Name -ResourceGroupName $using:resourceGroupName -Location $using:location -AllocationMethod Dynamic
     $nic2 = New-AzureRmNetworkInterface -Name $using:nic2Name -ResourceGroupName $using:resourceGroupName -Location $using:location -SubnetId $vNet.Subnets[0].Id -PublicIpAddressId $publicIpvm2.Id
     $vm2 = New-AzureRmVMConfig -VMName $using:vm2Name -VMSize $using:vmSize -AvailabilitySetId $using:avSet.Id
    
     $randomnumber2 = Get-Random -Minimum 0 -Maximum 99999999
     $tempName2 = $using:resourceGroupName + $using:vm2Name + $randomnumber2
     $nameAvail2 = Get-AzureRmStorageAccountNameAvailability -Name $tempName2
     If ($nameAvail2.NameAvailable -ne $true) {
         Do {
             $randomNumber2 = Get-Random -Minimum 0 -Maximum 99999999
             $tempName2 = $using:resourceGroupName + $using:vm2Name + $randomnumber2
             $nameAvail2 = Get-AzureRmStorageAccountNameAvailability -Name $tempName2
         }
         Until ($nameAvail2.NameAvailable -eq $True)
     }
     $storageAccountName2 = $tempName2
     $storageAccount2 = New-AzureRmStorageAccount -ResourceGroupName $using:resourceGroupName -Name $storageAccountName2 -SkuName "Standard_LRS" -Kind "Storage" -Location $using:location
    
         $vm2 = Set-AzureRmVMOperatingSystem -VM $vm2 -Windows -ComputerName $using:vm2Name -Credential $using:credentials -ProvisionVMAgent EnableAutoUpdate
         $vm2 = Set-AzureRmVMSourceImage -VM $vm2 -PublisherName $using:publisherName -Offer $using:offer -Skus $using:sku -Version $using:version
    
     $blobPath2 = 'vhds/' + $using:vm2osDiskName + '.vhd'
     $osDiskUri2 = $storageAccount2.PrimaryEndpoints.Blob.ToString() + $blobPath2
     $vm2 = Set-AzureRmVMOSDisk -VM $vm2 -Name $using:vm2osDiskName -VhdUri $osDiskUri2 -CreateOption fromImage
    
     $vm2 = Add-AzureRmVMNetworkInterface -VM $vm2 -Id $nic2.Id
     New-AzureRmVM -ResourceGroupName $using:resourceGroupName -Location $using:location -VM $vm2
     }
     }
    
     InlineScript {
     $publicIplbName = $using:resourceGroupName + 'lb-pip1'
     $feIplbConfigName = $using:resourceGroupName + '-felbipconfig'
     $beAddressPoolConfigName = $using:resourceGroupName + '-beipapconfig'
     $lbName = $using:resourceGroupName + 'lb'
    
     $publicIplb = New-AzureRmPublicIpAddress -Name $publicIplbName -ResourceGroupName $using:resourceGroupName -Location $using:location -AllocationMethod Dynamic
     $feIplbConfig = New-AzureRmLoadBalancerFrontendIpConfig -Name $feIplbConfigName -PublicIpAddress $publicIplb
     $beIpAaddressPoolConfig = New-AzureRmLoadBalancerBackendAddressPoolConfig -Name $beAddressPoolConfigName
     $healthProbeConfig = New-AzureRmLoadBalancerProbeConfig -Name HealthProbe -RequestPath '\' -Protocol http -Port 80 -IntervalInSeconds 15 -ProbeCount 2
     $lbrule = New-AzureRmLoadBalancerRuleConfig -Name HTTP -FrontendIpConfiguration $feIplbConfig -BackendAddressPool $beIpAaddressPoolConfig -Probe $healthProbe -Protocol Tcp -FrontendPort 80 -BackendPort 80
     $lb = New-AzureRmLoadBalancer -ResourceGroupName $using:resourceGroupName -Name $lbName -Location $using:location -FrontendIpConfiguration $feIplbConfig -LoadBalancingRule $lbrule -BackendAddressPool $beIpAaddressPoolConfig -Probe $healthProbeConfig
     $nic1 = Get-AzureRmNetworkInterface -Name $using:nic1Name -ResourceGroupName $using:resourceGroupName
     $nic1.IpConfigurations[0].LoadBalancerBackendAddressPools = $beIpAaddressPoolConfig
     $nic2 = Get-AzureRmNetworkInterface -Name $using:nic2Name -ResourceGroupName $using:resourceGroupName
     $nic2.IpConfigurations[0].LoadBalancerBackendAddressPools = $beIpAaddressPoolConfig
    
     Set-AzureRmNetworkInterface -NetworkInterface $nic1
     Set-AzureRmNetworkInterface -NetworkInterface $nic2
     }
     }
    
  4. If you prefer, you can import a pre-existing version of the runbook from the Lab files directory in Microsoft’s Parts Unlimited GitHub repository.

  5. Download the RAW file Provision-lab-textual-workflow-v1.ps1 from GitHub and save it to your local environment. You can also copy the contents of the file from GitHub, paste them into a new file and save the file in your local environment with the filename Provision-lab-textual-workflow-v1.ps1.

    Screenshot of the Microsoft GitHub repository. The repository name, hyperlink to the .psl file for the current lab, and the save as dialog, are highlighted to illustrate how to download a .psl file from GitHub in accordance with the previously described steps.

  6. From the Azure Portal, in the Automation Account you created earlier, go to Process Automation > Runbooks. Choose Add a runbook, and import the runbook with the following settings. Then, select Create.

    • Runbook file: Select the local path to the .ps1 file you downloaded/ saved.
    • Runbook type: PowerShell Workflow

    Screenshot of the Import a runbook pane. Six display elements are highlighted that require user action, to illustrate an implementation of the previously described steps for importing a runbook from a .psl file.

  7. With your runbook open in the Edit PowerShell Workflow Runbook pane, select the Test pane button, Then, choose Start. Wait for the test completed message to be displayed.

    Screenshot of the Edit PowerShell Workflow Runbook pane showing an imported runbook file. The Test pane and Start buttons are highlighted to illustrate areas where user actions are required to start the imported runbook .psl file.

    Note: The test and start runbook operations can take more than 15 minutes to complete. It is normal to encounter errors when you test the runbook for the first time. You should resolve the errors, one-by-one, by using the output displayed in the Test pane as a guide.

    A useful approach to resolving errors is to run the test runbook operation, identify a reported issue, apply a fix for the reported issue, then re-run a test to verify that you have fixed the issue. You should repeat this pattern until you have fixed all of the issues, and the script runs successfully.

    You may encounter the following common errors

    • Missing operators or brackets. If you have copied and pasted the script code directly from this lab, you can download the RAW script file from GitHub to your local environment instead. You can also copy the contents of the file on GitHub, paste it into a new file and save the file in your local environment with the filename Provision-lab-textual-workflow-v1.ps1. You can then import the script file into Azure. This may be the quickest way to resolve formatting errors.
    • Dash operator (-). Verify any parameters following a dash that are wrapped to the next line. Check for unnecessary space between the operator and the parameter or cmdlet. A required dash operator may be missing altogether.
    • Workflow or runbook name errors. The workflow name in the script must match the file name of the runbook.
    • Use PowerShell ISE. Another option is to copy and paste the code from this lab into Powershell ISE. You can then use the PowerShell ISE’s editing features to help debug and run the runbook, or export the runbook as a .ps1 file. The option to export may be greyed out until you publish the runbook.
    • Unique Resource Group name. You may need to delete pre-existing Resource Groups that use the same Resource Group name you specified earlier for use in this lab.
    • Resource or parameter value not available in region. Some resources are only available from certain regions. You may need to change the region you specified to a different one. You can determine the VM sizes available for a particular location/ region, such as westus for example, by running the command az vm list-sizes --location westus -output table with Azure CLI or PowerShell (requires Az module).
  8. Verify that the runbook provisions two Virtual Machines (VMs), an external Load Balancer (LB), and the other resources required by the VMs and LB. Choose All resources from the left menu. Filter by Resource Group type by selecting the value you assigned to the ResourceGroupName variable in Task 3. Select the Refresh button.

    The runbook should have provisioned the resources outlined in the following screenshot.

    Screenshot of the resources provisioned by the runbook running in Azure Portal under the Automation Account.

  9. Go back to the Edit PowerShell Workflow Runbook pane, and select the publish button to publish the runbook.

    Screenshot of a runbook inside the Edit PowerShell Workflow Runbook pane. The Publish button is highlighted to indicate that the button is used for publishing a runbook from within the Edit PowerShell Workflow Runbook pane.

Task 5: Create and run an Automation Windows PowerShell-based textual runbook that deprovisions the lab environment (Azure Portal)

Create a new runbook to remove the Resource Group that contains all the resources we created in this lab.

  1. From within the Azure Portal, in the Automation Account you created previously, create a new Automation runbook with the following settings:

    • Name: Deprovision-lab-textual-runbook
    • Runbook type: PowerShell
  2. Add the following runbook code:

     $c = Get-AutomationConnection -Name 'AzureRunAsConnection'
     Add-AzureRmAccount -ServicePrincipal -Tenant $c.TenantID -ApplicationID $c.ApplicationID -CertificateThumbprint $c.CertificateThumbprint
     $resourceGroupName = Get-AutomationVariable -Name 'ResourceGroupName'
     Remove-AzureRmResourceGroup -Name $resourceGroupName -Force
    
    

    Note: Similar to Task 4, as an alternative, you can use an existing version of the runbook from GitHub. Download the RAW file Deprovision-lab-textual-runbook.ps1, and then import it. You can also copy the files contents, paste them into a new file, save the file as Deprovision-lab-textual-runbook.ps1, then import the file.

  3. Test the runbook in the Test pane, verify that it runs successfully, and publish the runbook.

    Screenshot of a finished runbook inside the Edit PowerShell Workflow Runbook pane. The runbook completed message is highlighted.

Note: If you delete the Resource Group and all resources within with this de-provisioning script (Task 5), you can run the provisioning runbook again that you created previously (Task 4). Running the provisioning runbook again will re-deploy the Virtual Machines, Load Balancer, etc. These resources are required by the upcoming Infrastructure as Code labs.

Summary

In this lab you have:

  • Created an Azure Automation Account
  • Defined Azure Automation variables and updated modules
  • Created or imported a workflow-based textual runbook, tested the runbook, and run it to provision two load-balanced Azure VMs in parallel
  • Created and run an Automation Windows PowerShell-based textual runbook that deprovisions the lab environment