Chapter 3. Deploy and manage virtual machines (VMs)

Microsoft Azure offers many features and services that can be used to create inventive solutions for almost any IT problem. Two of the most common services for designing these solutions are Microsoft Azure Virtual Machines (VM) and VM scale sets. Virtual machines are one of the key compute options for deploying workloads in Microsoft Azure. Virtual machines can provide the on-ramp for migrating workloads from on-premises (or other cloud providers) to Azure, because they are usually the most compatible with existing solutions.

The flexibility of virtual machines makes them a key scenario for many workloads. For example, you have a choice of server operating systems with various supported versions of Windows and Linux distributions. Azure Virtual Machines also provide you full control over the operating system along with advanced configuration options for networking and storage. VM Scale Sets provide similar capabilities to VMs. They provide the ability to scale out certain types of workloads to handle large processing problems, and they optimize cost by only running instances when needed.

In this chapter, you will learn the ins-and-outs of deploying and managing virtual machines in Azure as we cover creation through the portal and the command line tools, automation with templates, as well as core management tasks.

Skills covered in this chapter:

Skill 3.1: Create and configure a VM for Windows and Linux

Microsoft Azure Virtual Machines are a flexible and powerful option for deploying workloads into the cloud. The support of both Windows and Linux-based operating systems allows for the deployment of a wide variety of workloads that traditionally run in an on-premises environment. This section will cover how to create and configure virtual machines and virtual machine scale sets including configuring for high availability.

Creating virtual machines

There are multiple ways to create virtual machines, depending on your intended use. The easiest way to create an individual virtual machine is to use the Azure portal. If you have a need for automated provisioning (or you just enjoy the command line), the Azure PowerShell cmdlets and the Azure cross-platform command-line tools (CLI) are a good fit. For more advanced automation, that can even include orchestration of multiple virtual machines, Azure Resource Manager templates can also be used. Each method brings its own capabilities and tradeoffs, and it is important to understand which tool should be used in the right scenario.

Create an Azure VM (Azure Portal)

To create a virtual machine using the Azure portal, click the Create Resource button, and you can then either search for an image or solution, or you can browse by clicking Compute, as shown in Figure 3-1. Within the Compute category, you will see the featured images, and if one of those images is not appropriate, you can click the See All option to view a larger selection.

A screen shot shows the featured VM images and the search box for the Azure Marketplace.

Figure 3-1 The Azure Marketplace view for virtual machines

The Azure portal allows you to provision virtual machines from a wide variety of virtual machine images and pre-defined templates for entire solutions such as SQL Server Always On, or even a complete SharePoint farm using only your web browser. For individual virtual machines you can specify some, but not all, configuration options at creation time.

Using the Azure portal, you can create virtual machines individually or you can deploy an ARM template that can deploy many virtual machines (including other Azure resources as well). You can even use the Azure portal to export an ARM template from an existing deployed resource. Through the integrated Azure Cloud Shell, you can also execute commands from the command line that can be used to provision virtual machines. After an image is selected, you can navigate through several screens to configure the virtual machine.

The first blade to complete is the Basics blade, as shown in Figure 3-2, which allows you to set the following configuration options:

  • The Azure subscription to create the VM in (if you have more than one)

  • The resource group name to deploy the virtual machine and its related resources in, such as network interface or public IP

  • The name of the virtual machine

  • The Azure region the virtual machine is created in

  • The availability options needed for the virtual machine

  • The administrator credentials

  • The operating system image name

  • The virtual machine size

  • User name and password for Windows and Linux

  • An SSH key for Linux VMs

  • Inbound port rules such as port 3389 for RDP or 22 for SSH

  • Choose to use the hybrid use benefit if you already have licenses for Windows Server

A screen shot that shows setting the basic properties of a Windows-based VM such as user name and password, resource group, and region.

Figure 3-2 The Basics blade of the portal creation process for a Windows-based virtual machine

More Info Understanding the Hybrid use Benefit

If you already own Windows or SQL Server licenses you may be eligible to re-use those licenses in the cloud and achieve significant cost savings. See the following for more detail:
https://azure.microsoft.com/pricing/hybrid-benefit/.

More Info Azure Powershell Cmdlets and CLI Tool

The Azure PowerShell cmdlets and CLI tools can be downloaded and installed at: https://azure.microsoft.com/downloads/. Scroll down to the Command-Line Tools section for installation links and documentation.

Create an Azure VM (PowerShell)

The PowerShell cmdlets are commonly used for automating common tasks such as stopping and starting virtual machines, deploying ARM templates, or for making configuration settings on a vast number of resources at the same time. Using the Azure PowerShell cmdlets, you can also create virtual machines imperatively and declaratively.

The approach we’ll use is to programmatically create the resources needed for the virtual machine such as storage, networking, availability sets and so on, and then associate them with the virtual machine at creation time.

Before you can create or manage any resources in your Azure subscription using the Azure PowerShell cmdlets, you must login by executing the Connect-AzAccount.

Connect-AzAccount

A virtual machine and all its related resources such as network interfaces, disks, and so on must be created inside of an Azure Resource Group. Using PowerShell, you can create a new resource group with the New-AzResourceGroup cmdlet.

$rgName   = "ExamRefRG"
$location = "West US"
New-AzResourceGroup -Name $rgName -Location $location

This cmdlet requires you to specify the resource group name, and the name of the Azure region. These values are defined in the variables $rgName, and $location. You can use the Get-AzResourceGroup cmdlet to see if the resource group already exists or not, and you can use the Get-AzLocation cmdlet to view the list of available regions.

Azure virtual machines must be created inside of a virtual network. In the portal example, networking was not mentioned. Should probably remove this here, OR show the networking and disk tabs in the Portal example above, using PowerShell you can specify an existing virtual network, or you can create a new one. In the code example next, the New-AzVirtualNetworkSubnetConfig cmdlet is used to create two local objects that represent two subnets in the virtual network. The virtual network is actually created within the call to New-AzVirtualNetwork. It is passed in the address space of 10.0.0.0/16, and you can also pass in multiple address spaces similar to how the subnets are passed in using an array.

$subnets = @()
$subnet1Name = "Subnet-1"
$subnet2Name = "Subnet-2"
$subnet1AddressPrefix = "10.0.0.0/24"
$subnet2AddressPrefix = "10.0.1.0/24"
$vnetAddresssSpace = "10.0.0.0/16"
$VNETName = "ExamRefVNET-PS"
$subnets += New-AzVirtualNetworkSubnetConfig -Name $subnet1Name `
                  -AddressPrefix $subnet1AddressPrefix
$subnets += New-AzVirtualNetworkSubnetConfig -Name $subnet2Name `
                  -AddressPrefix $subnet2AddressPrefix
$vnet = New-AzVirtualNetwork -Name $VNETName `
                  -ResourceGroupName $rgName `
                  -Location $location `
                  -AddressPrefix $vnetAddresssSpace `
                  -Subnet $subnets

To connect to the virtual machine from the public Internet, create a public IP address resource.

$ipName = "examRefIP"
$pip = New-AzPublicIpAddress -Name $ipName `
                -ResourceGroupName $rgName `
                -Location $location `
                -AllocationMethod Dynamic `
                -DomainNameLabel $dnsName

By default, adding a public IP to a VM’s network interface will allow in all traffic regardless of the destination port. To control this, create a network security group and only open the ports you will use. The next example creates an array that will be used for the rules and populates the array with the New-AzNetworkSecurityRuleConfig cmdlet.

# Add a rule to the network security group to allow RDP in
$nsgRules = @()
$nsgRules += New-AzNetworkSecurityRuleConfig -Name "RDP" `
                   -Description "RemoteDesktop" `
                   -Protocol Tcp `
                   -SourcePortRange "*" `
                   -DestinationPortRange "3389" `
                   -SourceAddressPrefix "*" `
                   -DestinationAddressPrefix "*" `
                   -Access Allow `
                   -Priority 110 `
                   -Direction Inbound

The New-AzNetworkSecurityGroup cmdlet creates the network security group. The rules are passed in using the SecurityRules parameter.

$nsgName     = "ExamRefNSG"
$nsg = New-AzNetworkSecurityGroup -ResourceGroupName $rgName `
                -Name $nsgName `
                -SecurityRules $nsgRules `
                -Location $location

Now that all the resources are created that the virtual machine requires, use the New-AzVMConfig cmdlet to instantiate a local configuration object that represents a virtual machine to associate them together. The virtual machine’s size and the availability set are specified during this call.

$vmSize = "Standard_DS1_V2"
$vmName = "ExamRefVM"
$vm = New-AzVMConfig -VMName $vmName -VMSize $vmSize

After the virtual machine configuration object is created there are several configuration options that must be set. This example shows how to set the operating system and the credentials using the Set-AzVMOperatingSystem cmdlet. The operating system is specified by using either the Windows or the Linux parameter. The ProvisionVMAgent parameter tells Azure to automatically install the VM agent on the virtual machine when it is provisioned. The Credential parameter specifies the local administrator username and password with the values passed to the $cred object.

$cred = Get-Credential 
Set-AzVMOperatingSystem -Windows `
               -ComputerName $vmName `
               -Credential $cred `
               -ProvisionVMAgent `
               -VM $vm

The operating system image (or existing VHD) must be specified for the VM to boot. Setting the image is accomplished by calling the Set-AzVMSourceImage cmdlet and specifying the Image publisher, offer, and SKU. These values can be retrieved by calling the cmdlets Get-AzVMImagePublisher, Get-AzVMImageOffer, and Get-AzVMImageSku.

$pubName   = "MicrosoftWindowsServer"
$offerName = "WindowsServer"
$skuName   = "2019-Datacenter"
Set-AzVMSourceImage -PublisherName $pubName `
            -Offer $offerName `
            -Skus $skuName `
            -Version "latest" `
            -VM $vm
Set-AzVMOSDisk -CreateOption fromImage -VM $vm

Images Exam Tip

In the previous example of creating a virtual machine, managed disks were used to create the virtual machine by omitting two parameters. For unmanaged disks the Set-AzOSDisk cmdlet would have also required the -VhdUri and -Name parameters. The -VhdUri would point to the Uri of where the disk would be created in an Azure storage account.

Use the New-AzNetworkInterface cmdlet to create the network interface for the VM. This cmdlet accepts the unique ID for the subnet, public IP, and the network security group for configuration.

$nicName    = "ExamRefVM-NIC"
$nic = New-AzNetworkInterface -Name $nicName `
                -ResourceGroupName $rgName ` 
                -Location $location `
                -SubnetId $vnet.Subnets[0].Id `
                -PublicIpAddressId $pip.Id `
                -NetworkSecurityGroupId $nsg.ID

Add-AzVMNetworkInterface -VM $vm `
             -NetworkInterface $nic

Images Exam Tip

In addition to knowing how to provision a virtual machine from an image, it is also important to understand how to create from an existing disk using the Set-AzVMOSDisk and the -CreateOption attach parameter (for more information see:
https://docs.microsoft.com/powershell/module/az.compute/set-azvmosdisk)

The final step is to provision the virtual machine by calling the New-AzVMConfig cmdlet. This cmdlet requires you to specify the resource group name to create the virtual machine in and the virtual machine configuration, which is in the $vm variable.

New-AzVM -ResourceGroupName $rgName -Location $location -VM $vm

It is also possible to create a virtual machine with just the New-AzVM cmdlet. This is useful to quickly spin up a VM for testing or demonstration purposes where you don’t need to set the individual characteristics of the virtual machine. See the following for more examples: https://docs.microsoft.com/powershell/module/azurerm.compute/new-Azvm.

Create an Azure VM (CLI)

The Azure CLI tools are used in a similar fashion to the PowerShell cmdlets. They are built to run cross platform on Windows, Mac, or Linux. The syntax of the CLI tools is designed to be familiar to users of a Bash scripting environment. Let’s walk through an example that creates the same resources as the previous PowerShell example, except creating a Linux-based virtual machine instead.

Like the PowerShell cmdlets, you first must login to access Azure using the CLI tools. The approach is slightly different, after executing the command az login, the tools provide you with a link to navigate to in the browser, and a code to enter. After entering the code and your credentials you are logged in to the command line.

az login

Create a new resource group by executing the az group create command and specifying a unique name and the region.

rgName="ExamRefRG"
location="WestUS"
az group create --name $rgName --location $location

The following command can be used to identify available regions that you can create resources and resource groups in.

az account list-locations

From here you have two options. You can create a virtual machine with a very simple syntax that generates much of the underlying configuration for you such as a virtual network, public IP address, storage account, and so on, or you can create and configure each resource and link to the virtual machine at creation time. Here is an example of the syntax to create a simple stand-alone virtual machine:

# Creating a simple virtual machine
vmName="myUbuntuVM"
imageName="UbuntuLTS"
az vm create --resource-group $rgName --name $vmName --image $imageName
--generate-ssh-keys

Note Ssh Keys

The generate-ssh-keys parameter dynamically generates keys to connect to the Linux virtual machine for you if they are missing. The new keys are stored in ~/.ssh. You can also specify a user name and password using the admin-username and admin-password parameters if you set the authentication-type parameter to password (default is ssh).

To create all the resources from scratch, as shown in the section on creating a virtual machine using the PowerShell cmdlets, you can start with the virtual network. Use the az network vnet create command to create the virtual network. This command requires the name of the virtual network, a list of address prefixes, and the location to create the virtual network in.

vnetName="ExamRefVNET-CLI"
vnetAddressPrefix="10.0.0.0/16"
az network vnet create --resource-group $rgName -n ExamRefVNET-CLI --address-prefixes
 $vnetAddressPrefix -l $location

The az network vnet subnet create command is used to add additional subnets to the virtual network. This command requires the resource group name, the name of the virtual network, the subnet name, and the address prefix for the subnet to create.

Subnet1Name="Subnet-1"
Subnet2Name="Subnet-2"
Subnet1Prefix="10.0.1.0/24"
Subnet2Prefix="10.0.2.0/24"
az network vnet subnet create --resource-group $rgName --vnet-name $vnetName
 -n $Subnet1Name --address-prefix $Subnet1Prefix
az network vnet subnet create --resource-group $rgName --vnet-name $vnetName
 -n $Subnet2Name --address-prefix $Subnet2Prefix

The az network public-ip create command is used to create a public IP resource. The allocation-method parameter can be set to dynamic or static.

dnsRecord="examrefdns123123"
ipName="ExamRefCLI-IP"
az network public-ip create -n $ipName -g $rgName --allocation-method Dynamic
--dns-name $dnsRecord -l $location

The az network nsg create command is used to create a network security group.

nsgName="webnsg"
az network nsg create -n $nsgName -g $rgName -l $location

After the network security group is created, use the az network rule create command to add rules. In this example, the rule allows inbound connections on port 22 for SSH and another rule is created to allow in HTTP port 80.

# Create a rule to allow in SSH
az network nsg rule create -n SSH --nsg-name $nsgName --priority 100 -g $rgName
--access Allow --description "SSH Access" --direction Inbound --protocol Tcp
--destination-address-prefix "*" --destination-port-range 22
--source-address-prefix "*" --source-port-range "*"
# Create a rule to allow in HTTP
az network nsg rule create -n HTTP --nsg-name webnsg --priority 101 -g $rgName
--access Allow --description "Web Access" --direction Inbound --protocol Tcp
--destination-address-prefix "*" --destination-port-range 80
--source-address-prefix "*" --source-port-range "*"

The network interface for the virtual machine is created using the az network nic create command.

nicname="WebVMNic1"
az network nic create -n $nicname -g $rgName --subnet $Subnet1Name
--network-security-group $nsgName --vnet-name $vnetName
--public-ip-address $ipName -l $location

To create a virtual machine, you must specify whether it will boot from a custom image, a marketplace image, or an existing VHD. You can retrieve a list of marketplace images by executing the following command:

az vm image list --all

The command az image list is used to retrieve any of your own custom images you have captured.

Another important piece of metadata needed to create a virtual machine is the VM size. You can retrieve the available form factors that can be created in each region by executing the following command:

az vm list-sizes --location $location

The last step is to use the az vm create command to create the virtual machine. This command allows you to pass the virtual machine size, the image the virtual machine should boot from, and other configuration data such as the username and password, availability and storage configuration.

imageName="Canonical:UbuntuServer:16.04-LTS:latest"
vmSize="Standard_DS1_V2"
user=demouser
vmName="WebVM"
az vm create -n $vmName -g $rgName -l $location --size $vmSize
--nics $nicname --image $imageName
--generate-ssh-keys

Images Exam Tip

To use unmanaged disks with the Azure CLI you will need to specify the use-unmanaged-disk parameter and specify the disk name, the storage account name, and the storage container.

Stopping a virtual machine from the Azure portal, Windows PowerShell with the Stop-AzVM cmdlet, or the az vm deallocate command puts the virtual machine in the Stopped (deal-located) state (az vm stop puts the VM in the Stopped state). It is important to understand the difference between Stopped (deallocated) and just Stopped. In the Stopped state a virtual machine is still allocated in Azure, and the operating system is simply shut down. You will still be billed for the compute time for a virtual machine in this state. A virtual machine in the Stopped (deallocated) state is no longer occupying physical hardware in the Azure region, and you will not be billed for the compute time (you are still billed for the underlying storage).

Operating system images

In addition to using the VM images from the Azure Marketplace, Azure also provides the ability to upload your own image or create a custom image directly in the cloud.

VM images are captured from an existing VM that has been prepared using the Windows program sysprep.exe or the Microsoft Azure Linux Agent (waagent) to make the operating system generalized. Generalized means that unique settings such as hostname, security IDs, personal information, user accounts, domain join information, and so on are removed from the operating system, so it is in a state to be provisioned on a new VM. Generalization does not remove customizations, such as installation of software, patches, additional files, and folders. This capability is what makes VM images a great solution for providing pre-configured and tested solutions for VMs or VM scale sets.

There are two types of VM image types available: managed and unmanaged where managed is the recommended option. Prior to the launch of Azure Managed Disks, unmanaged images were your only option. With unmanaged images, you can only create a new VM in the same storage account that the image resides in. This means that if you want to use the image in another storage account you have to use one of the storage tools to copy it to the new storage account first and then create the VM from it. Managed images solve this problem by removing the direct dependency on the storage account. Once a managed image exists you can create a VM based on it without worrying about the storage account configuration. This applies only to VMs created in the same region. If you want to create the VM in a remote region you must still copy the managed image to the remote region first.

More Info Shared Image Gallery

Using virtual machine images across regions will be simplified using a shared image gallery which is currently in preview. You can learn more about shared image galleries here:
https://docs.microsoft.com/azure/virtual-machines/windows/shared-image-galleries/.

Preparing the operating system for capture

To create a VM image you first generalize the operating system. In Windows this is using the sysprep.exe tool as shown in Figure 3-3. After this tool has completed execution, the VM is in a generalized state and it’s shut down.

A screen shotscreen shot shows using the System Preparation tool to generalize a Windows VM. The Enter System Out-of-Box Experience (OOBE) and Shutdown options are selected.

Figure 3-3 Using the System Preparation tool to generalize a Windows VM

Here is the command to generalize a Linux VM using the waagent program that you would execute from the Linux command line:

sudo waagent -deprovision+user

More Info Generalizing a VM Cannot be Undone

A virtual machine can no longer be used after it is generalized. Make sure you make a copy of the VM prior to generalization if you need it.

Capturing a managed VM image (Azure portal)

After the virtual machine is generalized, you can capture the image. The image can be captured using the Azure portal, PowerShell, or the CLI. To capture the virtual machine in the portal, click the Capture button at the top of the Virtual Machine blade. This will open a dialog box, shown in Figure 3-4, where you can specify the image Name and the Resource Group to store the image in. You can also specify to delete the virtual machine after the image is created since it has been generalized.

A screen shot that shows the image capture dialog for the Azure portal.

Figure 3-4 Creating an image using the Azure portal

Capturing a managed VM image (PowerShell)

This example shows how to create a managed VM image using PowerShell. This snippet uses the New-AzImageConfig and New-AzImage cmdlets.

$rgName = "Contoso"
$vmName = "ImageVM"
$location = "WestUS"
# Set the status of the virtual machine to Generalized
Set-AzVm -ResourceGroupName $rgName -Name $vmName -Generalized
# Create a managed VM from a VM
$imageName = "WinVMImage"
$vm = Get-AzVM -ResourceGroupName $rgName -Name $vmName
$image = New-AzImageConfig -Location $location -SourceVirtualMachineId $vm.ID
New-AzImage -Image $image -ImageName $imageName -ResourceGroupName $rgName
Capturing a managed VM image (CLI)

This example uses the az vm generalize and az image commands from the CLI tools to create a managed VM image.

# Create a Managed Image
rgName="Contoso"
vmName="ImageVM"
imageName="LinuxImage"
# Deallocate the VM
az vm deallocate --resource-group $rgName --name $vmName
# Set the status of the virtual machine to Generalized
az vm generalize --resource-group $rgName --name $vmName
az image create --resource-group $rgName --name $imageName --source $vmName
Creating a VM from an image

Creating a VM from an image is very similar to creating an image using an Azure Marketplace image. There are differences depending on if you start with an unmanaged image or a managed image. You can create a virtual machine from a managed image with the Azure portal by navigating to Images, selecting your image, and then Create Virtual Machine, Create Virtual Machine.

If you have a legacy unmanaged image you can only provision virtual machines using the command line. To do so you must ensure that the destination operating system and data disk URIs for your VM references the same storage account that your image resides in, and then reference the operating system image by its URI in the storage account and this is only available from the command line tools since it is no longer recommended.

To specify a legacy unmanaged image using PowerShell, set the SourceImageUri parameter of the Set-AzOsDisk cmdlet to the full URI of VHD in an Azure Storage account in the same region.

# In this example, $vm was a variable you created earlier using New-AzConfig
# This example is not meant to run directly on its own since the VM creation process
 has already been shown
$osDiskUri = "https://examrefstorage.blob.core.windows.net/vhd/os-disk"
$imageUri = "https://examrefstorage.blob.core.windows.net/images/legacy-image.vhd"
$vm = Set-AzVMOSDisk -VM $vm -Name $osDiskName -VhdUri $osDiskUri `
    -CreateOption fromImage -SourceImageUri $imageURI -Windows

Using the CLI tools, specify the URI using the image parameter of the az vm create command.

az vm create --resource-group $rgName --name $vmName --image $osDiskUri
--generate-ssh-keys

To create using a manage image with PowerShell, you first retrieve the image ID and pass it to Set-AzVMOSDisk instead.

$image = Get-AzImage -ImageName $imageName -ResourceGroupName $rgName
$vmConfig = Set-AzVMSourceImage -VM $vmConfig -Id $image.Id

Using the CLI tools saves a step because it retrieves the image ID for you, as long as you specify the name of your managed image.

az vm create -g $rgName -n $vmName --image $imageName

Images Exam Tip

Image management is an incredibly important topic, and having a solid understanding of the various options and techniques is undoubtedly valuable for passing the exam. Understanding how to create VMs from images, URIs, attach data disks, and copying disks between storage accounts will certainly not hurt your chances. You can learn more about managing images using the CLI tools at: https://docs.microsoft.com/azure/virtual-machines/linux/capture-image, and using PowerShell at: https://docs.microsoft.com/azure/virtual-machines/windows/capture-image-resource.

Configuring high availability

Resiliency is a critical part of any application architecture. Azure provides several features and capabilities to make it easier to design resilient solutions. The platform helps you to avoid a single point of failure at the physical hardware level and provides techniques to avoid downtime during host updates. Using features like availability zones, availability sets, and load balancers provides you the capabilities to build highly resilient and available systems.

Availability zones

At a high level, availability zones help to protect you from datacenter-level failures. They are located inside an Azure region, and each zone has its own independent power source, network, and cooling. To ensure resiliency, there’s a minimum of three separate zones in all enabled regions. The physical and logical separation of availability zones within a region protects applications and data from zone-level failures. Availability zones provide a 99.99 percent SLA uptime when two or more VMs are deployed. Figure 3-5 demonstrates how a 3-tier application can be deployed with a virtual machine from each tier deployed in each of the three zones for increased availability.

A screen shot shows how a server in each tier of an application is split across multiple zones in the availability zone.

Figure 3-5 Architectural view of an availability zone

To deploy a VM to an availability zone, select the zone you want to use on the Basics blade of the virtual machine creation dialog, as shown in Figure 3-6. If you add a virtual machine to an availability zone, you cannot also join it to an availability set.

A screen shot shows specifying the availability zone for a VM in the Azure portal.

Figure 3-6 Specifying the availability zone for a VM

At the time of this writing the following services are supported with availability zones (see: https://docs.microsoft.com/azure/availability-zones/az-overview#services-that-support-availability-zones for more information):

  • Linux Virtual Machines

  • Windows Virtual Machines

  • Virtual Machine Scale Sets

  • Managed Disks

  • Load Balancer

  • Public IP address

  • Zone-redundant storage

  • SQL Database

  • Event Hubs

  • Service Bus

  • VPN Gateway

  • ExpressRoute

  • Application Gateway (preview)

Currently supported regions :

  • Central US

  • East US 2

  • France Central

  • North Europe

  • Southeast Asia

  • West Europe

  • West US 2

Availability sets

Availability sets are used to control availability for multiple virtual machines in the same application tier. To provide redundancy for your virtual machines, it is least two virtual machines in an availability set. This configuration ensures that at least one virtual machine is available in the event of a host update, or a problem with the physical hardware the virtual machines are hosted on. Having at least two virtual machines in an availability set is a requirement for the service level agreement (SLA) for virtual machines of 99.95 percent.

Virtual machines should be deployed into availability sets according to their workload or application tier. For instance, if you are deploying a three-tier solution that consists of web servers, a middle tier, and a database tier, each tier would have its own availability set, as Figure 3-7 demonstrates.

An illustration shows availability set configurations for a multi-tier solution.

Figure 3-7 Availability set configurations for a multi-tier solution

Each virtual machine in your availability set is assigned a fault domain and an update domain. Each availability set has up to 20 update domains available, which indicates the groups of virtual machines and the underlying physical hardware that can be rebooted at the same time for host updates. Each availability set is also comprised of up to three fault domains, which represent which virtual machines will be on separate physical racks in the datacenter for redundancy. This limits the impact of physical hardware failures such as server, network, or power interruptions. It is important to understand that the availability set must be set at creation time of the virtual machine.

Create an availability set (Azure portal)

To create an availability set, specify a name for the availability set that is not in use by any other availability sets within the resource group, along with the number of fault and updates domains, as well as whether you will use managed disks with the availability set or not. Figure 3-8 demonstrates the Create Availability Set blade in the portal.

A screen shotscreen shot shows creating availability set using the Azure portal.

Figure 3-8 Creating an availability set

Create an availability set (PowerShell)

The New-AzAvailabilitySet cmdlet is used to create an availability set in PowerShell. The PlatformUpdateDomainCount and PlatformFaultDomainCount parameters control the number of fault domains and upgrade domains. The Sku parameter should be set to Aligned if you intend to deploy VMs that use managed disks. The following example shows how to create the availability set using PowerShell. The example assumes the resource group already exists.

# Create an availability set
$rgName = "ExamRefRG"
$avSetName = "WebAVSet"
$location = "West US"
New-AzAvailabilitySet -ResourceGroupName $rgName `
                            -Name $avSetName `
                            -Location $location `
                            -PlatformUpdateDomainCount 10 `
                            -PlatformFaultDomainCount 3 `
                            -Sku "Aligned"
Create an availability set (CLI)

The az vm availability-set create command is used to create an availability set using the CLI tools. The platform-update-domain-count and platform-fault-domain-count parameters are used to control the number of fault and upgrade domains. By default, an availability set is created as aligned unless you pass the parameter unmanaged. The following example shows how to create the availability set using CLI. The example assumes the resource group already exists.

# Create an availability set
rgName="ExamRefRGCLI"
avSetName="WebAVSet"
location="WestUS"
az vm availability-set create --name $avSetName --resource-group $rgName
--platform-fault-domain-count 3 --platform-update-domain-count 10
Availability sets and managed disks

For VMs that use Azure Managed Disks, VMs are aligned with managed disk fault domains when using an aligned availability set, as shown in Figure 3-9. This alignment ensures that all the managed disks attached to a VM are within the same managed disk fault domain. Only VMs with managed disks can be created in a managed availability set. The number of managed disk fault domains varies by region, with either two or three managed disk fault domains per region.

An illustration shows aligning managed disks with an availability set.

Figure 3-9 Aligning managed disks with an availability set

More Info Understanding Availability in Azure VMS

You can learn more about update and fault domains and how to manage availability of your Azure VMs here:
https://docs.microsoft.com/azure/virtual-machines/windows/manage-availability.

Configure virtual machine size

There are many situations where the amount of compute processing your workload needs varies dramatically from day to day or even hour to hour. For example, in many organizations line of business (LOB) applications are used heavily during the workweek, but on the weekends, they see little actual usage. Other examples are workloads that require more processing time due to scheduled events such as backups or maintenance windows where having more compute time may make it faster to complete these tasks. Azure Resource Manager-based VMs make it relatively easy to change the size of a virtual machine even after it has been deployed. There are a few things to consider with this approach.

The first consideration is to ensure that the region your VM is deployed to supports the instance size that you want to change the VM to. In most cases this is not an issue, but if you have a use case where the desired size isn’t in the region the existing VM is deployed to, your only options are to either wait for the size to be supported in the region, or to move the existing VM to a region that already supports it.

The second consideration is if the new size is supported in the current hardware cluster your VM is deployed to. This can be determined by clicking the Size link in the virtual machine configuration blade in the Azure portal of a running virtual machine, as Figure 3-10 demonstrates. If the size is available, you can select it. Changing the size reboots the virtual machine. It also reallocates it as you're pushed to a new host so it's slower than a reboot where you stay on the same host.

A screen shotscreen shot that shows the size configuration of a virtual machine in the Azure portal

Figure 3-10 Changing the size of a virtual machine using the Azure portal

A third consideration is the form factor of the new size compared to the old size. Consider scaling from a DS3_V2 to a DS2_V2. A DS3_V2 supports up to eight data disks and up to four network interfaces. A DS2_V2 supports up to four data disks and up to two network interfaces. If the VM you are sizing from (DS3_V2) is using more disks or network interfaces than the target size, the resize operation will fail.

Resizing a VM (PowerShell)

Use the Get-AzVMSize cmdlet and pass the name of the region to the location parameter to view all the available sizes in your region to ensure the new size is available. If you specify the resource group and the VM name, it returns the available sizes in the current hardware cluster.

# View available sizes
$location = "WestUS" 
Get-AzVMSize -Location $location

After you have identified the available size, use the following code to change the VM to the new size.

$rgName = "ExamRefRG"
$vmName = "Web1"
$size = "Standard_DS2_V2"
$vm = Get-AzVM -ResourceGroupName $rgName -VMName $vmName
$vm.HardwareProfile.VmSize = $size
Update-AzVM -VM $vm -ResourceGroupName $rgName

If the virtual machine(s) are part of an availability set, the following code can be used to shut them all down at the same time and restart them using the new size.

$rgName = "ExamRefRG"
$vmName = "Web1"
$size = "Standard_DS2_V2"
$avSet = "WebAVSet"
Resizing a VM (CLI)

The az vm list-vm-resize-options command can be used to see which VM sizes are available in the current hardware cluster.

rgName="ExamRefRG"
vmName="Web1"
az vm list-vm-resize-options --resource-group $rgName --name $vmName --output table

The az vm list-sizes command is used to view all sizes in the region.

az vm list-sizes --location westus

The az vm resize command is used to change the size of an individual VM.

az vm resize --resource-group $rgName --name $vmName --size Standard_DS3_v2

Authentication options

For Windows-based virtual machines usernames can be a maximum of 20 characters in length and cannot end in a period (".”) and many common usernames are blocked during the creation process. Examples of blocked account names include: 1, 123, a, admin, administrator, john and several other easily guessable names. Passwords must be between 12 and 123 characters in length and meet several complexity requirements.

For Linux-based virtual machines, you can specify an existing SSH public key or a password when creating a Linux VM. Linux usernames must be between 1 and 32 characters in length and passwords must be between 6 and 72 characters. Like Windows, certain easily guessable usernames and passwords are automatically when creating through the Portal.

If you choose to use the SSH public key option, you must paste in the public key for your SSH certificate. You can create the SSH certificate using the following command:

ssh-keygen -t rsa -b 2048

To retrieve the public key for your new certificate, run the following command in a bash console:

cat ~/.ssh/id_rsa.pub

From there, copy all of the data starting with ssh-rsa and ending with the last character on the screen, pasting it into the SSH public key box, as shown on the Create a virtual machine blade in the Azure portal.. Ensure you don’t include any extra spaces.

A screen shots shows setting the basic properties of a Linux-based VM such as user name and SSH key, resource group, and region.

Figure 3-11 The Basics blade of the portal creation process for a Linux-based virtual machine

More Info Learn more About Username and Password Requirements

For information on username and password requirements on Windows VMs, see: https://docs.microsoft.com/azure/virtual-machines/windows/faq, or for Linux-based VM requirements, see: https://docs.microsoft.com/azure/virtual-machines/linux/faq.

Configure storage

The storage subsystem for virtual machines is configured using Azure virtual machine disks. There are many options and features to consider when configuring disks. Options such as whether to use managed or unmanaged disks, which disk types (Premium SSD, Standard SSD, and Standard HDD, Ultimate SSD), as well as when and how to take advantage of disk read/write caching.

Azure virtual machine disks

Each Azure virtual machine can have three different type of disks:

  • Operating System Disk (OS Disk) The C drive in Windows or /dev/sda on Linux. This disk is registered as a SATA drive and has a maximum capacity of 2048 gigabytes (GB). This disk is persistent and stored in Azure Storage.

  • Temporary Disk The D drive in Windows or /dev/sdb on Linux. This disk is used for short term storage for applications or the system. Data on this drive can be lost during a maintenance event and if the VM is moved to a different host because the data is stored on the local disk.

  • Data Disk Registered as a SCSI drive. These disks can be attached to a virtual machine, the number of which depends on the VM instance size. Data disks have a maximum capacity of 4095 gigabytes (GB) currently, No longer in preview. GA'd on 3/25 https://azure.microsoft.com/blog/larger-more-powerful-managed-disks-for-azure-virtual-machines/. These disks are persistent and stored in Azure Storage.

More Info Disks and VHDS

See the following for more information on Disks and VHDs:
https://docs.microsoft.com/azure/virtual-machines/windows/about-disks-and-vhds.

OS disks and data disks can be created as managed or an unmanaged disk.

MANAGED DISKS

Managed disks handle storage for you by automatically distributing your disks in storage accounts for capacity and by integrating with Azure Availability Sets to provide isolation for your storage just like availability sets do for virtual machines. Managed disks also make it easy to change between Standard and Premium storage (HDD to SSD) without the need to write conversion scripts.

UNMANAGED DISKS

With unmanaged disks you are responsible for ensuring for the correct distribution of your VM disks in storage accounts for capacity planning as well as availability. An unmanaged disk is also not a separate manageable entity. This means that you cannot take advantage of features like role-based access control (RBAC) or resource locks at the disk level. Managed disks are recommended for all new workloads and suggests migrating existing workloads to managed as well.

CHOOSING THE RIGHT DISK TYPE

Table 3-1 provides a summary of when to use which disk type, including the suggested workload types, max IOPS and throughput.

Table 3-1 Summary of performance and recommended workloads per disk type

Disk Type Premium SSD Standard SSD Standard HDD
Summary Designed for IO intensive enterprise workloads. Delivers consistent performance with low latency and high availability. Designed to provide consistent performance for low IOPS workloads. Delivers better availability and latency compared to HDD Disks. Optimized for low-cost mass storage with infrequent access. Can exhibit some variability in performance.
Workload Demanding enterprise workloads such as SQL Server, Oracle, Dynamics, Exchange Server, MySQL, Cassandra, MongoDB, SAP Business Suite, and other production workloads. Web servers, low IOPS application servers, lightly used enterprise applications, and Dev/Test. Backup storage.
Max IOPS 7,500 IOPS provisioned Up to 500 IOPS Up to 500 IOPS
Max Throughput 250 MBPS provisioned Up to 60 MBPS Up to 60 MBPS

More Info Ultra SSD DISKS

Ultra SSD Disks are a fourth disk type that is currently in preview and promises to deliver top of the line performance as well as the ability to dynamically change the performance of disks without the need to restart virtual machines. You can learn more about this upcoming offering here: https://docs.microsoft.com/azure/virtual-machines/linux/disks-ultra-ssd.

Images Exam Tip

Ultra and Standard SSD disks are only creatable as managed disks.

Using the Azure portal on the Disks configuration blade, you can specify the OS disk type to Standard SSD, Standard HDD, or Premium SSD when provisioning a virtual machine. You can also attach additional data disks and specify whether the disks are managed or unmanaged during the provisioning process or after the virtual machine is provisioned.

A screen shot that shows the blade for adding a new disk to a virtual machine. In the image you can see links for create and attach a new disk as well as attach an existing disk.

Figure 3-12 Configuring disks during creation

Planning for storage capacity

Planning for storage capacity is a key exercise when you are deploying a new workload or migrating an existing workload. For an Azure virtual machine, the maximum capacity of a disk is 4095 GB (4 TB). Disk sizes larger than 4095 GB are currently available: https://azure.microsoft.com/blog/larger-more-powerful-managed-disks-for-azure-virtual-machines/.

Virtual machine disk caching

Azure disks (operating system and data) have configurable cache settings that you can configure that affects durability and performance. The caching behavior differs whether you are using Standard storage or Premium storage.

Caching works on Standard HDD storage by buffering the reads and write on the local physical disk on the host server the virtual machine is running on. Virtual machines that use SSD-based storage have a multi-tier caching technology called BlobCache. BlobCache uses a combination of the Virtual Machine RAM and local SSD for caching. This cache is available for Standard and Premium SSD. By default, this cache setting is set to Read/Write for operating system disks and Read Only for data disks hosted on SSD storage. With disk caching enabled on storage disks, virtual machines can achieve extremely high levels of performance that exceed the underlying disk performance.

There are three settings that can be applied to your disks:

  • None Configure host-cache as None for write-only and write-heavy disks (data disk only).

  • Read Only Configure host-cache as ReadOnly for read-only and read-write disks (OS and data disk).

  • Read Write Configure host-cache as ReadWrite only if your application properly handles writing cached data to persistent disks when needed (OS and data disk).

You can set the host caching setting at any time, but understand that when the cache setting is changed that the disk will be unattached and then reattached to the virtual machine. For best practice, you should ensure that none of your applications are actively using the disk when you change the cache setting. Changing the operating system disk’s host cache setting, results in the virtual machine being rebooted.

The host cache setting can be modified for a disk by using the Azure portal as shown in Figure 3-13. This setting can also be modified using the command line tools, a template, or a call to the Azure REST API.

A screen that shot shows editing a disk to change the host caching options in the Azure portal.

Figure 3-13 Setting the Host Caching options

With PowerShell, use the Set-AzVMDataDisk cmdlet to modify the cache setting of a disk.

In the following example, an existing virtual machine configuration is returned using the Get-AzVM cmdlet, the disk configuration is modified using Set-AzVMDataDisk, and then the virtual machine is updated using the Update-AzVM cmdlet. Use the Set-AzVMOSDisk cmdlet instead to update the operating system disk. The Set-AzVMDataDisk cmdlet also supports a Name parameter if you would rather update the disk by name instead of using the LUN.

$rgName = "ExamRefRG"
$vmName = "ExamRefVM"
$vm = Get-AzVM -ResourceGroupName $rgName -Name $vmName
Set-AzVMDataDisk -VM $vm -Lun 0 -Caching ReadOnly
Update-AzVM -ResourceGroupName $rgName -VM $vm

There are two commands to use with Azure CLI, depending on whether the virtual machine is an unmanaged or a managed disk. Also, the host cache setting can only be specified when attaching a disk using the az vm unmanaged-disk for unmanaged disks, or az vm disk attach for managed, specifying the caching parameter. This means you detach and then attach an existing VHD to modify the cache setting, or you can specify it during the creation of a new disk as the following example demonstrates.

rgName="StorageRG"
vmName="StandardVM"
diskName="ManagedDisk"
az vm disk attach --vm-name $vmName --resource-group $rgName --size-gb 128
--disk $diskName --caching ReadWrite –new

To configure the disk cache setting using a resource manager template specify the caching property of the OSDisk, or each disk in the dataDisks collection of the virtual machine’s OSProfile configuration. The following example shows how to set the cache setting on a data disk for an unmanaged disk.

"dataDisks": [
  {
    "name": "datadisk1",
    "diskSizeGB": "1023",
    "lun": 0,
    "caching": "ReadOnly",
    "vhd": { "uri": "[variables('DISKURI')]" },
    "createOption": "Empty"
  }
]
Capacity planning with unmanaged disks

A Standard Azure Storage account supports a maximum of 20,000 IOPS. A Standard Tier Azure Virtual Machine using Standard storage supports 500 IOPS per disk, and basic tier supports 300 IOPS per disk. If the disks are used at maximum capacity, a single Azure Storage account can handle 40 disks hosted on standard virtual machines, or 66 disks on basic virtual machines. Storage accounts also have a maximum storage capacity of 2 PB for US and Europe and 500 TB for all other regions. When performing capacity planning, the number of Azure Storage accounts per the number of virtual machines can be derived from these numbers. Table 3-2 provides the disk and storage account limits for basic and standard tier virtual machines using standard storage.

Table 3-2 Standard unmanaged virtual machine disks: per disk and account limits

VM Tier Basic Tier VM Standard Tier VM
Disk size 4095 GB 4095 GB
Max 8 KB IOPS per persistent disk 300 500
Max number of disks performing max IOPS (per storage account) 66 40

A premium Azure storage account supports a maximum of 35 TB of total disk capacity, with up to 10 TB of capacity for snapshots. The maximum bandwidth per account (ingress + egress) is <= 50 Gbps. Table 3-3 lists the storage account limits when using premium unmanaged disks.

Table 3-3 Premium storage account limits when using unmanaged disks

Resource Default Limit
Total disk capacity per account 35 TB
Total snapshot capacity per account 10 TB
Max bandwidth per account (ingress + egress1) <=50 Gbps

This means that just like when using standard storage, you must carefully plan how many disks you create in each storage account. You should also consider the maximum throughput per Premium disk type, because each type has a different max throughput, which affects the overall max throughput for the storage account. Table 3-4 shows the disk and storage account capacity limits for unmanaged Premium disks.

Table 3-4 Premium unmanaged virtual machine disks: per disk limits

Type Size IOPS per disk Throughput MAX DISKS/Account
P10 128 GiB 500 100 MB/s 280
P20 512 GiB 2300 150 MB/s 70
P30 1024 GiB 5000 200 MB/s 35
P40 2048 GiB 7500 250 MB/s 17
P50 4095 GiB 7500 250 MB/s 8
Capacity planning with managed disks

A significant difference for managed disks over unmanaged disks is there no requirement for managing the underlying storage account for managed disks. This simplifies capacity planning because you must only consider the storage capacity size, IOPS, and overall throughput, and not how many disks per storage account. There are four types of managed disks to understand: Standard HDD, Standard SDD, Premium SDD, and the new Ultra SSD, which is currently in preview. Table 3-5 shows the disk sizes, IOPS, and throughput per disk for Standard HDD managed disks.

Table 3-5 Standard HDD managed virtual machine disks

Type Size IOPS per disk Throughput
S4 32 GB 500 60 MB/sec
S6 64 GB 500 60 MB/sec
S10 128 GB 500 60 MB/sec
S30 1024 GB 500 60 MB/sec
S40 2048 GB 500 60 MB/sec
S50 4095 GB 500 60 MB/sec
S60 8 TiB 1,300 300 MB/sec
S70 16 TiB 2,000 500 MB/sec
S80 32 TiB 2,000 500 MB/sec

Table 3-6 shows the disk sizes, IOPS, and throughput per disk for Standard SSD managed disks.

Table 3-6 Standard SSD managed virtual machine disks: per disk limits

Type Size IOPS per disk Throughput
E10 128 GiB Up to 500 Up to 60 MiB per second
E15 256 GiB Up to 500 Up to 60 MiB per second
E20 512 GiB Up to 500 Up to 60 MiB per second
E30 1,024 GiB Up to 500 Up to 60 MiB per second
E40 2,048 GiB Up to 500 Up to 60 MiB per second
E50 4,095 GiB Up to 500 Up to 60 MiB per second
E60 8,192 GiB Up to 1,300 Up to 300 MiB per second
E70 16,384 GiB Up to 2,000 Up to 500 MiB per second
E80 32,767 GiB Up to 2,000 Up to 500 MiB per second

Table 3-7 shows the disk sizes, IOPS, and throughput per disk for Premium SSD managed disks.

Table 3-7 Premium SSD managed virtual machine disks: per disk limits

Type Size IOPS per disk Throughput
P4 32 GB 120 25 MB/sec
P6 64 GB 240 50 MB/sec
P10 128 GB 500 100 MB/sec
P15 256 GB 1100 125 MB/sec
P20 512 GB 2300 150 MB/sec
P30 1024 GB 5000 200 MB/sec
P40 2048 GB 7500 250 MB/sec
P50 4095 GB 7500 250 MB/sec
P60 8 TiB 12,500 480 MB/sec
P70 16 TiB 15,000 750 MB/sec
P80 32 TiB 20,000 750 MB/sec

Each SSD backed storage-supported virtual machine size has scale limits and performance specifications for IOPS, bandwidth, and the number of disks that can be attached per VM.

When you use SSD disks with VMs, make sure that there is enough IOPS and bandwidth on your VM to drive disk traffic.

More Info Virtual Machine Scale Limits for Storage

For the most up-to-date information about maximum IOPS and throughput (bandwidth) for Premium storage-supported VMs, see Windows VM sizes at: https://docs.microsoft.com/azure/virtual-machines/windows/sizes or Linux VM sizes: https://docs.microsoft.com/azure/virtual-machines/linux/sizes.

Implementing disk redundancy for performance

If your workload throughput requirements exceed the maximum IOPS capabilities of a single disk or your storage requirements are greater than the size of a single disk you do have options. The first option is to add multiple data disks (depending on the virtual machine size) and implement RAID 0 disk striping, and create one or more volumes with multiple data disks. Be sure to only use RAID 0 striping or you will see performance degradation. This provides increased capacity and increased throughput.

If your virtual machine is hosted on Windows Server 2012 or above, you can use storage pools to virtualize storage by grouping industry-standard disks into pools, and then create virtual disks called Storage Spaces from the available capacity in the storage pools. You can then configure these virtual disks to provide striping capabilities across all disks in the pool, combining good performance characteristics. Storage pools make it easy to grow or shrink volumes depending on your needs (and the capacity of the Azure data disks you have attached).

This next example creates a new storage pool named VMStoragePool with all of the available data disks configured as part of the pool. The code identifies the available data disks using the Get-PhysicalDisk cmdlet and creates the virtual disk using the New-VirtualDisk cmdlet.

# Create a new storage pool using all available disks 
New-StoragePool -FriendlyName "VMStoragePool" `
        -StorageSubsystemFriendlyName "Windows Storage*" `
        -PhysicalDisks (Get-PhysicalDisk -CanPool $True)
# Return all disks in the new pool
$disks = Get-StoragePool -FriendlyName "VMStoragePool" `
            -IsPrimordial $false |
            Get-PhysicalDisk
# Create a new virtual disk
New-VirtualDisk -FriendlyName "DataDisk" `
        -ResiliencySettingName Simple `
        -NumberOfColumns $disks.Count `
        -UseMaximumSize -Interleave 256KB `
        -StoragePoolFriendlyName "VMStoragePool"

The NumberOfColumns parameter of New-VirtualDisk should be set to the number of data disks utilized to create the underlying storage pool. This allows IO requests to be evenly distributed against all data disks in the pool. The Interleave parameter enables you to specify the number of bytes written in each underlying data disk in a virtual disk. Microsoft recommends in general that you use 256 KB for all workloads. After the virtual disk is created, the disk must be initialized, formatted, and mounted to a drive letter or mount point just like any other disk.

More Info Striping Disks for Performance on LINUX

Using storage pools allows you to combine disks on Windows for increased throughput and capacity. You can do the same thing on Linux as well using several options. See the following to learn more at: https://docs.microsoft.com/azure/virtual-machines/linux/configure-raid.

Images Exam Tip

Mounting data disks may come up on the exam. It is important to remember that on Windows, the drive D is mapped to the local resource disk, which is only for temporary data because it is backed by the local physical disk on the host server. The resource disk will be mounted on the / Dev/sdb1 device on Linux, with the actual mount point varying by Linux distribution.

Configure networking

During the virtual machine provisioning process in the portal you can set the following settings using the Networking blade as shown in Figure 3-14.

  • The virtual network and subnet and the public IP address

  • The network security group for the network interface card (NIC)

  • Which public inbound ports should be open (if any)

  • Enable accelerated networking

  • The option to include the VM in an existing Azure load balancer backend pool

A screen shotscreen shot shows the networking blade of a virtual machine created in the Azure portal.

Figure 3-14 Specifying the networking options for a virtual machine during creation

More Info Network Security Groups

A network security group (NSG) is a networking filter containing a list of security rules that when applied control network traffic. These rules can manage both inbound and outbound traffic. A network security group can be associated to a network interface, the subnet the network interface is in, or both. To simplify management of security rules, it’s recommended that you associate a network security group to individual subnets, rather than individual network interfaces within the subnet, whenever possible. You will learn more about NSGs in Chapter 4 Configure and Manage Virtual Networks.

There are several networking features to understand for effectively using Azure Virtual Machines as well as preparing for the exam. In this chapter you will learn some of these concepts, and in Chapter 4 Configure and Manage Virtual Networks you will learn in-depth about virtual networks, network security groups, subnets, IP addresses and DNS management.

More Info Application Security Groups

An application security group (ASG) enables you to define network security policies based on workloads with rules focused on applications instead of IP and network addresses. They provide the capability to group virtual machines with monikers and secure applications by filtering traffic from trusted segments of your network. Like NSGs, you will learn more about ASGs in Chapter 4 Configure and Manage Virtual Networks.

Accelerated networking

Accelerated networking enables single root I/O virtualization (SR-IOV) to a virtual machine, which greatly improves its networking performance. This feature improves performance by bypassing the virtual switch between the host VM and the physical switch. Figure 3-15 shows two deployments: the deployment on the left without accelerated networking and the deployment on the right with accelerated networking enabled.

A screen shot that shows a virtual machine deployment on the left without accelerated networking enabled where the traffic for the network card goes through a virtual switch. The accelerated networking deployment on the right shows the network card traffic going straight to the virtual machine.

Figure 3-15 Virtual machines deployed with and without accelerated networking enabled

Accelerated networking can be enabled at creation time or after the virtual machine is created if the following pre-requisites are followed:

  • The VM must be a supported size for Accelerated Networking

  • The VM must be a supported Azure Gallery image (and kernel version for Linux)

  • All VMs in an availability set or VMSS must be stopped/deallocated before enabling Accelerated Networking on any NIC

Supported sizes:

  • Accelerated Networking is supported on most general purpose and compute-optimized instance sizes with 2 or more vCPUs. These supported series are: D/DSv2 and F/Fs

  • On instances that support hyperthreading, Accelerated Networking is supported on VM instances with 4 or more vCPUs. Supported series are: D/DSv3, E/ESv3, Fsv2, and Ms/Mms

Supported Windows-based images from the Azure Marketplace:

  • Windows Server 2016 Datacenter

  • Windows Server 2012 R2 Datacenter

Supported Linux-based images from the Azure Marketplace:

  • Ubuntu 16.04

  • SLES 12 SP3

  • RHEL 7.4

  • CentOS 7.4

  • CoreOS Linux

  • Debian "Stretch” with backports kernel

  • Oracle Linux 7.4

To change an existing virtual machine, you must update the network interface. The following example shows how to accomplish this using PowerShell:

$nic = Get-AzNetworkInterface -ResourceGroupName "ExamRefRG" -Name "vmNicName"
$nic.EnableAcceleratedNetworking = $true
$nic | Set-AzNetworkInterface

The following example shows how to use the Azure CLI to accomplish the same task:

az network nic update 
   --name vmNicName 
   --resource-group ExamRefRG 
   --accelerated-networking true

More Info Learning more About Accelerated Networking

You can learn more about using Accelerated Networking on Windows virtual machines here: https://docs.microsoft.com/azure/virtual-network/create-vm-accelerated-networking-powershell or Linux-based VMs here: https://docs.microsoft.com/azure/virtual-network/create-vm-accelerated-networking-cli.

Connecting to virtual machines

There are many ways to connect to virtual machines. You should consider options such as connecting to VMs using their public IP addresses and protecting them with network security groups and allowing only the port for the service you are connecting to. You should also understand how to connect to a VM on its private IP address. This introduces additional connectivity requirements such as ExpressRoute, Site-to-Site VPN, or Point-to-Site VPN to put your client on the same network as your VMs. These technologies are discussed in Chapter 4. In this section we’ll review the most common tools to connect and manage your VMs.

Connecting to a Windows VM with remote desktop

The default connectivity option for a Windows-based virtual machine is to use the remote desktop protocol (RDP) and a Remote Desktop client such as mstsc.exe. The RDP service listens on TCP port 3389 and provides full access to the Windows desktop. This service is enabled by default on all Windows-based VMs provisioned from the Azure Marketplace. The Azure portal provides a Connect button that will appear enabled for virtual machines that have a public IP address associated with them, as shown in Figure 3-16.

A screen shot shows the Connect button for an Azure VM.

Figure 3-16 The Connect button for an Azure VM

You can launch a remote desktop session from Windows PowerShell by using the Get-AzRemoteDesktopFile cmdlet. The Get-AzRemoteDesktopFile cmdlet performs the same validation as the Azure portal. The API it calls validates that a public IP address is associated with the virtual machine’s network interface. If a public IP exists, it generates an .rdp file consumable with a Remote Desktop client. The .rdp file will have the IP address of the VIP and public port (3389) of the specified embedded virtual machine. There are two parameters that alter the behavior of what happens with the generated file.

Use the Launch parameter to retrieve the .rdp file and immediately open it with a Remote Desktop client. The following example launches the Mstsc.exe (Remote Desktop client), and the client prompts you to initiate the connection.

$rgName = "ExamRefRG"
$vmName = "ExamRefVM"
Get-AzRemoteDesktopFile -ResourceGroupName $rgName -Name $vmName -Launch

The second behavior is to specify the LocalPath parameter, as the following example shows. Use this parameter to save the .rdp file locally for later use.

$rgName = "ExamRefRG"
$vmName = "ExamRefVM"
$Path = "C:ScratchExamRefVM.rdp"
Get-AzRemoteDesktopFile -ResourceGroupName $rgName -Name $vmName -LocalPath $path
Connecting to a Linux virtual machine using SSH

The default connectivity option for a Linux-based virtual machine is to use the secure shell (SSH) protocol. This service listens on TCP port 22 and provides full access to a command line shell. This service is enabled by default on all Linux-based VMs. When you click the Connect button on a Linux-based virtual machine with a public IP associated with it you see a dialog advising you to use SSH to connect. Figure 3-17 shows how to use SSH to connect to a virtual machine using the Azure Cloud Shell.

A screen shot shows the SSH command executing from within the Azure Cloud Shell.

Figure 3-17 Using SSH to connect to a virtual machine from the Azure cloud shell

If the virtual machine is configured for password access, SSH then prompts for the password for the user you specified. If you specified the public key for an SSH certificate during the creation of the virtual machine, it attempts to use the certificate from the ~/.ssh folder.

Windows users have many options for connecting using SSH. For example, if you install the Linux subsystem for Windows 10, you will also install an SSH client that can be accessed from the bash command line. You can also install one of many GUI-based SSH clients like PuTTY.

More Info Options for Using SSH from Windows

There are plenty of options to connect to your Linux-based virtual machines from Windows. The following link has more detail on SSH certificate management and some available clients at: https://docs.microsoft.com/azure/virtual-machines/linux/ssh-from-windows.

Configure monitoring

There are several tools and services in Azure designed to help you monitor different aspects of an application or deployed infrastructure. In addition to the built-in tools, you also can monitor your virtual machines using existing monitoring solutions such as Systems Center Operations Manager, or many other third-party solutions. Let’s review some of the built-in capabilities.

Azure diagnostics

There are two levels of VM diagnostics: host and guest. With host diagnostics you can view and act on the data surfaced from the hypervisor hosting your virtual machine. This data is limited to high-level metrics involving the CPU, Disk, and Network. Enabling guest-level diagnostics involves having an agent running on the virtual machine that can collect a richer subset of data.

Azure Diagnostics extension

The Azure diagnostics extension is an agent on both Windows and Linux VMs that provides a rich set of diagnostics data. On Windows, this agent can collect a comprehensive set of performance counter data, event, IIS log files, and even crash dumps. It also provides the ability to automatically transfer this data to Azure Storage as well as surfacing telemetry to the Azure portal for visualization and alerts. The capabilities on Linux are more limited, but they still expose a broad range of performance telemetry to act on for reporting and alerts.

Enabling and configuring diagnostics (Windows)

During the creation of a VM, you can enable both guest operating system diagnostics and boot diagnostics. Diagnostics data for the virtual machine is stored in an Azure storage account. Figure 3-18 shows the Management blade which is where you can enable diagnostics at provisioning time.

A screen shotscreen shot that shows the Management blade of the virtual machine creation process in the Azure portal. Depicted are options for Monitoring, Identity, Auto-Shutdown, Backup with guest and boot diagnostics enabled.

Figure 3-18 Enabling boot and guest operating system diagnostics during VM creation

You can also enable diagnostics on a VM after it is created as long as the virtual machine is running. Figure 3-19 shows what it looks like to enable the Diagnostics extension on a Windows VM.

A screen shot shows enabling diagnostics on a Windows VM using the Azure portal.

Figure 3-19 Enabling diagnostics on a Windows VM

After the Diagnostics extension is enabled, you can then capture performance counter data. Using the portal, you can select basic sets of counters by category, as Figure 3-20 shows.

A screen shot shows configuring the capture of performance counters using the Azure portal.

Figure 3-20 Configuring the capture of performance counters

You can also configure diagnostics at a granular level by specifying exactly which counters to sample and capture, including custom counters, as Figure 3-21 shows.

A screen shot shows specifying a custom performance counter configuration in the Azure portal.

Figure 3-21 Specifying a custom performance counter configuration

Like capturing performance counters, the Diagnostics extension provides the option of collecting basic event log data, as Figure 3-22 shows. The custom view for capturing event logs supports a custom syntax to filter on certain events by their event source or the value.

A screen shot shows specifying event logs and levels to capture in the Azure portal.

Figure 3-22 Capturing event logs and levels to capture

Figure 3-23 shows how to configure the extension to automatically transfer IIS web and failed request logs to Azure storage containers for later diagnostics.

A screen shot shows specifying event logs and levels to capture in the Azure portal.

Figure 3-23 Capturing event logs and levels to capture

For .NET applications that emit trace data, the extension can also capture this data and filter by the following log levels: All, Critical, Error, Warning, Information, and Verbose, as Figure 3-24 shows.

A screen shot shows specifying the log level for application logs using the Azure portal.

Figure 3-24 Specifying the log level for application logs

Event Tracing for Windows (ETW) provides a mechanism to trace and log events that are raised by user-mode applications and kernel-mode drivers. ETW is implemented in the Windows operating system and provides developers a fast, reliable, and versatile set of event tracing features. Figure 3-25 demonstrates how to configure the Diagnostics extension to capture ETW data from specific sources.

A screen shot shows collecting Event Tracing for Windows (ETW) in the Azure portal.

Figure 3-25 Collecting Event Tracing for Windows (ETW)

The Azure Diagnostics extension can be configured to monitor processes and automatically capture crash dumps in the event of an unhandled exception, as shown in Figure 3-26. You can choose from mini-crash dumps to full crash dumps. The agent automatically moves the dump files to the Azure Storage container you specify.

A screen shot shows configuring the storage container location for IIS and failed request logs in the Azure portal.

Figure 3-26 Configuring process monitoring and crash dump collection

The agent optionally allows you to send diagnostic data to Application Insights, as Figure 3-27 shows. This is especially helpful if you have other parts of an application that use Application Insights natively, so you have a single location to view diagnostics data for your application.

A screen shot shows sending diagnostics data to Application Insights by specifying the account and instrumentation key.

Figure 3-27 Sending diagnostics data to Application Insights

The final diagnostics data to mention is boot diagnostics. If enabled, the Azure Diagnostics agent captures a screen shot to a specific Storage account of what the console looks like on the last boot. This helps you understand the problem if your VM does not start. Clicking the Boot Diagnostics link in the portal shows you the last captured screen shot of your VM as well as the serial log of the status of the virtual machine when it booted, as Figure 3-28 shows.

A screen shows the screens hot from the last boot for a Windows VM with boot diagnostics configured from the Azure portal.

Figure 3-28 The screen shot from the last boot for a Windows VM with boot diagnostics configured

Enabling and configuring diagnostics (Linux)

The Diagnostics agent on Linux supports capturing performance metrics, data from the Linux Syslog, as well as rich boot diagnostics data. Like the Windows agent, the Diagnostics extension can be enabled at provisioning time or after the VM is provisioned.

Figure 3-29 shows the basic performance metrics that are available for capture by the Azure Diagnostics agent.

A screen shot shows enabling diagnostics on a Linux VM with the Azure portal.

Figure 3-29 Enabling diagnostics on a Linux VM

Clicking Custom opens the blade shown in Figure 3-30, which allows much more fine grain control over which metrics to capture.

A screen shot shows enabling custom diagnostic metrics on a Linux VM with the Azure portal.

Figure 3-30 Custom performance metrics with the Azure Diagnostics agent

Figure 3-31 shows how to configure diagnostic capture for Linux Syslog data.

A screen shot shows configuring the log level for the LOG_AUTH syslog facility on a Linux virtual machine.

Figure 3-31 Configuring the log level for syslog on a Linux virtual machine

Like Windows, boot diagnostics on Linux provides both a screen shot of the console as well as the output of the boot sequence captured in the serial log as shown in Figure 3-32.

A screen shot shows boot diagnostic logs for a Linux VM from the Azure portal.

Figure 3-32 Boot diagnostics logs for a Linux VM

Images Exam Tip

The Azure Diagnostics agent can also be configured through resource manager templates and the command line tools by specifying a configuration file. For the exam you should be aware of the schema of this configuration and how to apply it using automated tools. You can learn more about the diagnostics schema at:
https://docs.microsoft.com/azure/monitoring-and-diagnostics/azure-diagnostics-schema.

Azure Monitor

Azure Monitor maximizes the availability and performance of your applications by delivering a comprehensive solution for collecting, analyzing, and acting on telemetry from your cloud and on-premises environments. It helps you understand how your applications are performing and proactively identifies issues affecting them and the resources they depend on. The Azure Monitor landing page provides a jumping off point to configure other more specific monitoring services such as Application Insights, Network Watcher, Log Analytics, Management Solutions, and so on. Data collected by Azure Monitor fits into one of two types: metrics and logs. Metrics are numerical values that describe some aspect of the system at a point in time. Logs contain different kinds of data organized into records with different properties. Examples of log data include telemetry data such as Azure platform actions, events and trace logs. Figure 3-33 shows some of the various data sources and how they are collected either as metric or log data. The data is consumed, visualized or acted on by various services in Azure.

A screen shot shows boot diagnostic logs for a Linux VM from the Azure portal.

Figure 3-33 Azure Monitor data sources for metric and log data and the ways you can act on the data

More Info Azure Monitor

To learn more about the capabilities of Azure Monitor see the following:
https://docs.microsoft.com/azure/monitoring-and-diagnostics/monitoring-overview-azure-monitor.

More Info Azure Monitor for VMS (Preview)

Azure Monitor for a VMs is an offering currently in preview that provides new capabilities for monitoring your virtual machines and virtual machine scale sets. You can learn more about the new capabilities here:
https://docs.microsoft.com/azure/azure-monitor/insights/vminsights-overview.

Creating an alert

You create a new alert by clicking Alerts from within the Azure resource configuration blade or from within Azure Monitor, and then click New alert rule. Figure 3-34 shows the Alerts blade from within Azure Monitor.

A screen shot shows the empty alerts blade from within Azure Monitor.

Figure 3-34 The alerts blade from within Azure Monitor

Figure 3-35 shows the Create Rule blade, which prompts for four pieces of information: the resources to monitor, the conditions to alert on, the action groups (which define what action to take when the alert is triggered), and the name and description of the alert.

A screen shot shows the Create rule blade after clicking New Alert Rule in Azure Monitor.

Figure 3-35 The create rule blade after clicking New Alert Rule in Azure Monitor

Clicking the Select button brings up a dialog where you filter on which resource in your subscription to create the alert on. Figure 3-36 shows the Select A Resource blade filtered by the virtual machines resource type. If you do not select a resource type you can filter on different Azure subscription activity log signals to receive alerts on.

A screen shot shows configuring the criteria for an alert in the Azure portal.

Figure 3-36 Configuring the criteria for an alert

The next step is to configure the alert criteria by clicking the Add condition button and then selecting the signal to measure. This is the metric to use, the condition, threshold, and the period. The alert shown in Figure 3-37 will trigger an alert when the Percentage CPU metric exceeds 70 percent over a five-minute period.

A screen shot showing the metric, condition, threshold and time period for an alert.

Figure 3-37 The configuration of the alert based on the CPU signal

An action group is a collection of actions that should occur in response to an alert being triggered. You can have up to 1000 email actions in an action group. In addition to sending email notifications you can execute the following actions:

  • ITSM You may have up to 10 IT Service Manager (ITSM) actions with an ITSM connection. The following ITSM providers are currently supported: ServiceNow, System Center Service Manager, Provance, and Cherwell. You can learn more about ITSM connections here: https://docs.microsoft.com/azure/azure-monitor/platform/itsmc-overview.

  • Webhook A webhook allows you to route an Azure alert notification to other systems for post-processing or custom actions. For example, you can use a webhook on an alert to route it to services that send text messages, log bugs, notify a team via chat/messaging services, or do any number of other actions. You can learn more about sending alert information to webhooks at: https://docs.microsoft.com/azure/monitoring-and-diagnostics/insights-webhooks-alerts.

  • Runbook A set of PowerShell code that runs in the Azure Automation Service. See the following to learn more about using Runbooks to remediate alerts at: https://azure.microsoft.com/blog/automatically-remediate-azure-vm-alerts-with-automation-run-books/.

  • Function Apps A Function App is a set of code that runs "serverless” that can respond to alerts. This functionality requires Version 2 of Function Apps, and the value of the AzureWebJobsSecretStorageType app setting must be set to "files.”

  • Logic Apps A Logic App provides a visual designer to model and automate your process as a series of steps known as a workflow. There are many connectors across the cloud and on-premises to quickly integrate across services and protocols. When an alert is triggered the Logic App can take the notification data and use it with any of the connectors to remediate the alert or start other services. To learn more about Azure Logic Apps visit: https://docs.microsoft.com/azure/logic-apps/logic-apps-what-are-logic-apps.

  • SMS You may have up to 10 SMS actions in an Action Group.

  • Voice You may have up to 10 Voice actions in an Action Group.

Figure 3-38 shows the various actions that can take place when an alert is triggered.

A screen shot shows configuring notifications for an alert for emails, web hook, runbooks, or logic apps.

Figure 3-38 Configuring notifications for an alert

Application Insights

Application Insights is used for development and as a production monitoring solution. It works by installing a package into your app, which can provide a more internal view of what’s going on with your code. Its data includes response times of dependencies, exception traces, debugging snapshots, and execution profiles. It provides powerful smart tools for analyzing all this telemetry both to help you debug an app, and to help you understand what users are doing with it. You can tell whether a spike in response times is due to something in an app, or some external resourcing issue. If you use Visual Studio and the app is at fault, you can be taken right to the problem line(s) of code, so you can fix it. Application Insights provides significantly more value when your application is instrumented to emit custom events and exception information. You can learn more about Application Insights including samples for emitting custom telemetry at: https://docs.microsoft.com/azure/application-insights/.

Network Watcher

The Network Watcher service provides the ability to monitor and diagnose networking issues without logging in to your virtual machines (VMs). You can trigger packet capture by setting alerts and gain access to real-time performance information at the packet level. When you see an issue, you can investigate in detail for better diagnoses. This service is ideal for troubleshooting network connectivity or performance issues.

Azure Log Analytics

Log Analytics is a service that monitors your cloud and on-premises environments to maintain their availability and performance. Log Analytics collects data generated by resources in your cloud and on-premises environments and from other monitoring tool to provide analysis across multiple data sources. Log Analytics provides rich tools to analyze data across multiple sources, allows complex queries across all logs, and can proactively alert you on specified conditions. You can even collect custom data into its central repository, so you can query and visualize it. You can learn more about Log Analytics at: https://docs.microsoft.com/azure/log-analytics/log-analytics-overview.

Deploy and configure scale sets

For workloads that support the ability to dynamically add and remove instances to handle increased or decreased demand, VM scale sets (VMSS) should be considered. A VMSS is a compute resource that you can use to deploy and manage a set of identical virtual machines.

By default, a VMSS supports up to 100 instances. However, it is possible to create a scale set up to 1000 instances if they are deployed with the property singlePlacementGroup set to false. A placement group is a construct like an Azure availability set, with its own fault domains and upgrade domains. By default, a scale set consists of a single placement group with a maximum size of 100 VMs. If the scale set property called singlePlacementGroup is set to false, the scale set can be composed of multiple placement groups and has a range of 0-1,000 VMs. When set to the default value of true, a scale set is composed of a single placement group, and has a range of 0-100 VMs.

Using multiple placement groups is commonly referred to as a large-scale set. The singlePlacementGroup property can be set using ARM templates, the command line tools, or during portal creation. Working with large scale sets does have a few conditions to be aware of. If you are using a custom image instead of a gallery image, your scale set supports up to 300 instances instead of 1000. Another scalability factor for consideration is the Azure Load Balancer. The basic SKU of the Azure Load Balancer can scale up to 100 instances. For a large-scale set (> 100 instances) you should use the Standard SKU or the Azure Application Gateway.

Creating a virtual machine scale set (Azure portal)

Figure 3-39 shows a portion of the creation dialog for creating a new VM scale set using the Azure portal. Like other Azure resources, you must specify a name and the resource group to deploy to. All instances of the VMSS will use the same operating system disk image specified here. A scale set can be deployed to an availability zone or an availability set.

A screen shot shows creating a VM scale set using the Azure portal.

Figure 3-39 Creating a VM scale set

Figure 3-40 shows further down the blade. This allows you to configure more advanced properties such as scaling beyond 100 instances, Autoscale properties, how virtual machines are spread across fault domains, and networking options such as the virtual network and subnet to use plus which type of load balancer to use. Not shown in the image is a setting that allows the scale set to use managed disks.

A screen shot shows configuring the instances and the load balancer for a VM scale set with the Azure portal.

Figure 3-40 Configuring the instances and the load balancer for a VM scale set

Images Exam Tip

The spreading algorithm determines how VMs in the scale set are balanced across fault domains. With max spreading, VMs are spread across as many fault domains as possible in each zone. With fixed spreading, VMs are always spread across exactly five fault domains. In the case where fewer than five fault domains are available, a scale set using "Max spreading” will still complete deployment, while a scale set using "Fixed spreading” will fail to deploy.

When Autoscale is enabled, you are presented with a set of configuration options for setting the default rules, as shown in Figure 3-41. Here you can specify the minimum and maximum number of VMs in the set, as well as the actions to scale out (add more) or to scale in (remove instances).

A screen shot shows configuring the Autoscale rules (scale out, scale in, and minimum and maximum instances) for a virtual machine scale set.

Figure 3-41 Configuring Autoscale rules for a virtual machine scale set

The Azure portal creation process does not directly support applying configuration management options like VM extensions. However, they can be applied to a VMSS later using the command line tools or an ARM template.

More Info Virtual Machine Scale Sets

You can learn more about virtual machine scale sets here:
https://docs.microsoft.com/azure/virtual-machine-scale-sets/.

Upgrading a virtual machine scale set

During the lifecycle of running a virtual machine scale set you undoubtedly need to deploy an update to the operating system. The VMSS resource property upgradePolicy can be set to either the value manual or automatic. If automatic, when an operating system update is available all instances are updated at the same time, which causes downtime. If the property is set to manual, it is up to you to programmatically step through and update each instance using PowerShell with the Update-AzVmssInstance cmdlet or the Azure CLI tools az vmss update-instances command.

More Info Upgrading a Virtual Machine Scale Set

You can learn more about upgrading virtual machine scale sets at:
https://docs.microsoft.com/azure/virtual-machine-scale-sets/virtual-machine-scale-sets-upgrade-scale-set.

Creating a virtual machine scale set (PowerShell)

Creating a VM scale set using PowerShell is very similar to creating a regular virtual machine. You create a VMSS configuration object using the New-AzVmssConfig cmdlet. From there, you either create or retrieve existing dependent resources and set them on the returned configuration object. Typically, virtual machine scale sets use a VM extension to self-configure themselves during the instance startup. The Add-AzVmssExtension cmdlet is used to specify the extension configuration.

The following example is detailed and creates all the resources such as virtual network, load balancer, public IP address, as well as demonstrates how to apply a custom script extension to configure the VM instances on boot.

# Create a virtual machine scale set with IIS installed from a custom script extension
$rgName      = "ExamRefRGPS"
$location    = "WestUS"
$vmSize      = "Standard_DS2_V2"
$capacity    = 2

New-AzResourceGroup -Name $rgName -Location $location
# Create a config object
$vmssConfig = New-AzVmssConfig `
   -Location $location `
   -SkuCapacity $capacity `
   -SkuName $vmSize `
   -UpgradePolicyMode Automatic

# Define the script for your Custom Script Extension to run
$publicSettings = @{
   "fileUris" = (,"https://raw.githubusercontent.com/opsgility/lab-support-
public/master/script-extensions/install-iis.ps1");
   "commandToExecute" = "powershell -ExecutionPolicy Unrestricted -File
install-iis.ps1"
}

This section of the code adds a new custom script extension to the VM Scale Set configuration object ($vmssConfig). The script will execute automatically as a new node is added to the scale set.

# Use Custom Script Extension to install IIS and configure basic website
Add-AzVmssExtension -VirtualMachineScaleSet $vmssConfig `
   -Name "customScript" `
   -Publisher "Microsoft.Compute" `
   -Type "CustomScriptExtension" `
   -TypeHandlerVersion 1.8 `
   -Setting $publicSettings

This section specifies the load balancer network configuration, including the public IP address that the load balancer will use, the load balancer and the front end and backend pool of the scale set.

$publicIPName = "vmssIP"

# Create a public IP address
$publicIP = New-AzPublicIpAddress `
   -ResourceGroupName $rgName `
   -Location $location `
   -AllocationMethod Static `
   -Name $publicIPName 

# Create a frontend and backend IP pool
$frontEndPoolName = "lbFrontEndPool"
$backendPoolName = "lbBackEndPool"
$frontendIP = New-AzLoadBalancerFrontendIpConfig `
   -Name $frontEndPoolName `
   -PublicIpAddress $publicIP
$backendPool = New-AzLoadBalancerBackendAddressPoolConfig -Name $backendPoolName


# Create the load balancer
$lbName = "vmsslb"
$lb = New-AzLoadBalancer `
   -ResourceGroupName $rgName `
   -Name $lbName `
   -Location $location `
   -FrontendIpConfiguration $frontendIP `
   -BackendAddressPool $backendPool

# Create a load balancer health probe on port 80
$probeName = "lbprobe"
Add-AzLoadBalancerProbeConfig -Name $probeName `
   -LoadBalancer $lb `
   -Protocol http `
   -Port 80 `
   -IntervalInSeconds 15 `
   -ProbeCount 2 `
   -RequestPath "/"


# Create a load balancer rule to distribute traffic on port 80
Add-AzLoadBalancerRuleConfig `
   -Name "lbrule" `
   -LoadBalancer $lb `
   -FrontendIpConfiguration $lb.FrontendIpConfigurations[0] `
   -BackendAddressPool $lb.BackendAddressPools[0] `
   -Protocol Tcp `
   -FrontendPort 80 `
   -BackendPort 80
# Update the load balancer configuration
Set-AzLoadBalancer -LoadBalancer $lb

This section of the sample specifies the OS Image and the administrator credentials each node will use when provisioned.

# Reference a virtual machine image from the gallery
Set-AzVmssStorageProfile $vmssConfig `
   -ImageReferencePublisher MicrosoftWindowsServer `
   -ImageReferenceOffer WindowsServer `
   -ImageReferenceSku 2016-Datacenter `
   -ImageReferenceVersion latest `
   -OsDiskCreateOption FromImage 

# Set up information for authenticating with the virtual machine
$userName = "azureuser"
$password = "[email protected]!"
$vmPrefix = "ssVM"
Set-AzVmssOsProfile $vmssConfig `
   -AdminUsername $userName `
   -AdminPassword $password `
   -ComputerNamePrefix $vmPrefix

In this section of the sample, shows how to specify the virtual network configuration for the scale set.

# Create the virtual network resources
$subnetName = "web"
$subnet = New-AzVirtualNetworkSubnetConfig `
   -Name $subnetName `
   -AddressPrefix 10.0.0.0/24


$ssName = "vmssVNET"
$subnetPrefix = "10.0.0.0/16"


$vnet = New-AzVirtualNetwork `
   -ResourceGroupName $rgName `
   -Name $ssName `
   -Location $location `
   -AddressPrefix $subnetPrefix `
   -Subnet $subnet


$ipConfig = New-AzVmssIpConfig `
   -Name "vmssIPConfig" `
   -LoadBalancerBackendAddressPoolsId $lb.BackendAddressPools[0].Id `
   -SubnetId $vnet.Subnets[0].Id


# Attach the virtual network to the config object
$netConfigName = "network-config"
Add-AzVmssNetworkInterfaceConfiguration `
   -VirtualMachineScaleSet $vmssConfig `
   -Name $netConfigName `
   -Primary $true `
   -IPConfiguration $ipConfig

This last section shows how to create the scale set using New-AzVmss cmdlet.

$scaleSetName = "erscaleset"
# Create the scale set with the config object (this step might take a few minutes)
New-AzVmss `
   -ResourceGroupName $rgName `
   -Name $scaleSetName `
   -VirtualMachineScaleSet $vmssConfig
Creating a virtual machine scale set (CLI)

The Azure CLI tools takes a different approach than PowerShell by creating resources like load balancers and virtual networks for you as part of the scale set creation.

# Create a VM Scale Set with load balancer, virtual network, and a public IP address
rgName="Contoso"
ssName="erscaleset"
userName="azureuser"
password="[email protected]!"
vmPrefix="ssVM"
location="WestUS"
az group create --name $rgName --location $location
az vmss create --resource-group $rgName --name $ssName --image UbuntuLTS 
--authentication-type password --admin-username $userName --admin-password $password

The az vmss create command allows you to reference existing resources instead of creating them automatically by specifying the resources as parameters if you want to differ from the default behavior. For a VMSS use the az vmss extension set command as shown in the following example. The settings.json file should be in the same directory that execute the command.

#settings.json
{
   "fileUris": [
     "https://raw.githubusercontent.com/Azure/azure-quickstart-templates/master/
201-vmss-bottle-autoscale/installserver.sh"
 ],
 "commandToExecute": "bash installserver.sh"
}
az vmss extension set --publisher Microsoft.Compute --version 1.8 
--name CustomScriptExtension --resource-group $rgName --vmss-name $ssName 
--settings @settings.json

Skill 3.2: Automate deployment of VMs

The ability to provision virtual machines on-demand using the Azure portal is incredibly powerful. The true power of the cloud, however, is the ability to automatically deploy one or more resources defined in code such as a script or a template. Use cases such as defining an application configuration, and automatically deploying it on-demand, allows teams to be more agile by providing dev/test/production environments in a fast and repeatable fashion. Since the configuration is stored as code, changes to infrastructure can also be tracked in a version control system. In this skill you will learn some of the core capabilities for automating workload deployments in Azure.

Deploy Windows and Linux VMs

Azure Resource Manager templates are authored using JavaScript Object Notation (JSON) and provide the ability to define the configuration of resources like virtual machines, Storage accounts, and so on in a declarative manner. Templates go beyond just providing the ability to create the resources; some resources such as virtual machines also allow you to customize them and create dependencies between them. This allows you to create templates that have capabilities for orchestrated deployments of completely functional solutions.

The Azure team maintains a list of ARM templates with examples for most resources. This list is located at https://azure.microsoft.com/resources/templates/, and is backed by a source code repository in GitHub. If you want to go directly to the source to file a bug or any other reason you can access it at: https://github.com/Azure/azure-quickstart-templates.

The basic structure of a resource manager template has most of the following elements:

  {
     "$schema": "https://schema.management.azure.com/schemas/2015-01
  -01/deploymentTemplate.json#",
     "contentVersion": "1.0.0.0",
     "parameters": { },
     "variables": { },
     "functions": [ ],
     "resources": [ ],
     "outputs": { }
  }
  • $schema The URL to the JSON schema that defines the version of the template language.

    For resource group targeted deployments use:

    http://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#

    For subscription targeted deployments use:

    https://schema.management.azure.com/schemas/2018-05
    -01/subscriptionDeploymentTemplate.json#
  • contentVersion Version of the template (such as 1.0.0.0). You can provide any value for this element. Use this value to document significant changes in your template. When deploying resources using the template, this value can be used to make sure that the right template is being used.

  • parameters Values that are provided when deployment is executed to customize resource deployment.

  • variables Values that are used as JSON fragments in the template to simplify template language expressions.

  • functions User-defined functions that are available within the template.

  • resources Resource types that are deployed or updated in a resource group.

  • outputs Values that are returned after deployment.

Defining a virtual network

This skill is focused on learning how to deploy Windows and Linux virtual machines. A prerequisite of deploying a virtual machine is a virtual network. In this example, we’ll define the structure of the virtual network using several variables that describe the address space and subnet allocation. The last three variables are additional variables that will be referenced by other resources created later in the section.

"ExamRefRGPrefix": "10.0.0.0/16",
"ExamRefRGSubnet1Name": "FrontEndSubnet",
"ExamRefRGSubnet1Prefix": "10.0.0.0/24",
"ExamRefRGSubnet2Name": "BackEndSubnet",
"ExamRefRGSubnet2Prefix": "10.0.1.0/24",
"ExamRefRGSubnet1Ref": "[concat(variables('vnetId'), '/subnets/',
 variables('ExamRefRGSubnet1Name'))]",
"VNetId": "[resourceId('Microsoft.Network/virtualNetworks', variables('VirtualNetworkNa
me'))]",
"VirtualNetworkName": "ExamRefVNET",

After the variables are defined you can then add the virtual network resource to the resource’s element in your template. The following snippet creates a virtual network named ExamRefVNET, with an address space of 10.0.0.0/16 and two subnets: FrontEndSubnet 10.0.0.0/24 and BackEndSubnet 10.0.1.0/24. Note the syntax to read the value of variables: [variables('variablename')] is used heavily when authoring templates. The virtual network’s location is set based on the return value of the built-in resourceGroup() function, which returns information about the resource group the resource is being created or updated in.

  {
     "name": "[variables('VirtualNetworkName')]",
     "type": "Microsoft.Network/virtualNetworks",
     "location": "[resourceGroup().location]",
     "apiVersion": "2017-06-01",
     "dependsOn": [],
     "properties": { 
     "addressSpace": {
       "addressPrefixes": [
         "[variables('ExamRefRGPrefix')]"
        ]
     },
     "subnets": [
        {
           "name": "[variables('ExamRefRGSubnet1Name')]",
           "properties": {
           "addressPrefix": "[variables('ExamRefRGSubnet1Prefix')]"
           }
        },
        {
           "name": "[variables('ExamRefRGSubnet2Name')]",
           "properties": {
           "addressPrefix": "[variables('ExamRefRGSubnet2Prefix')]"
           }
        }
      ]
    }
  }
Defining a network interface

Every virtual machine has one or more network interfaces. To create one with a template, add a variable to the variables section to store the network interface resource name as the following snippet demonstrates:

"VMNicName": "VMNic"

The following code snippet defines a network interface named WindowsVMNic. This resource has a dependency on the ExamRefVNET virtual network. This dependency will ensure that the virtual network is created prior to the network interface creation when the template is deployed and is a critical feature of orchestration of resources in the correct order. The network interface is associated to the subnet by referencing the ExamRefRGSubnet1Ref variable.

{
   "name": "[variables('VMNicName')]",
   "type": "Microsoft.Network/networkInterfaces",
   "location": "[resourceGroup().location]",
   "apiVersion": "2017-06-01",
   "dependsOn": [
     "[resourceId('Microsoft.Network/virtualNetworks', 'ExamRefVNET')]"
   ],
   "properties": {
     "ipConfigurations": [
        {
          "name": "ipconfig1",
          "properties": {
            "privateIPAllocationMethod": "Dynamic",
            "subnet": {
               "id": "[variables('ExamRefRGSubnet1Ref')]"
            } 
        }
      } 
    ]
  }
}

Images Exam Tip

To specify a static private IP address in template syntax, specify an address from the assigned subnet using the privateIpAddress property and set the privateIpAllocation method to Static.

"privateIpAddress”: "10.0.0.10”,

"privateIpAllocationMethod”: "Static”,

Adding a Public IP Address

To add a public IP address to the virtual machine you must make several modifications. The first is to define a parameter that the user will use to specify a unique DNS name for the public IP. The following code goes in the parameters block of a template:

  "VMPublicIPDnsName": {
   "type": "string",
   "minLength": 1
  }

The second modification is to add the public IP resource itself. Before adding the resource, add a new variable in the variables section store the name of the public IP resource.

  "VMPublicIPName": "VMPublicIP"

The following snippet shows a public IP address resource with the public IP allocation method set to dynamic (it can also be set to static). The domainNameLabel property of the IP address dnsSettings element is populated by the parameter. This makes it easy to specify a unique value for the address at deployment time.

  {
     "name": "[variables('VMPublicIPName')]",
     "type": "Microsoft.Network/publicIPAddresses",
     "location": "[resourceGroup().location]",
     "apiVersion": "2017-06-01",
     "dependsOn": [ ],
     "properties": {
       "publicIPAllocationMethod": "Dynamic",
       "dnsSettings": {
         "domainNameLabel": "[parameters('VMPublicIPDnsName')]"
       }
     }
  }

The next modification is to update the network interface resource that the public IP address is associated with. The network interface must now have a dependency on the public IP address to ensure it is created before the network interface. The following example shows the addition to the dependsOn array as the following example demonstrates:

  "dependsOn": [
    "[resourceId('Microsoft.Network/virtualNetworks', 'ExamRefVNET')]",
    "[resourceId('Microsoft.Network/publicIPAddresses', variables('VMPublicIPName'))]"
  ],

The ipConfigurations -> properties element must also be modified to reference the publicIPAddress resource. The bolded code highlights the addition.

    "ipConfigurations": [
       {
         "name": "ipconfig1",
         "properties": {
         "privateIPAllocationMethod": "Dynamic",
         "subnet": {
            "id": "[variables('ExamRefRGSubnet1Name')]"
         },
         "publicIPAddress": {
            "id": "[resourceId('Microsoft.Network/publicIPAddresses',
variables('VMPublicIPName'))]"
         },
        } 
      }
    ]
Defining a virtual machine resource

Before creating the virtual machine resource, you will add several parameters and variables to define. Each virtual machine requires administrative credentials. To enable a user to specify the credentials at deployment time, add two additional parameters for the administrator account and the password.

   "VMAdminUserName": {
      "type": "string",
      "minLength": 1
   },
   "VMAdminPassword": {
      "type": "string",
      "minLength": 1
   }

Several variables are needed to define the configuration of the virtual machine resource. The following variables define the VM name, operating system image, and the VM size. These should be inserted into the variables section of the template.

   "VMName": "MyVM",
   "VMImagePublisher": "MicrosoftWindowsServer",
   "VMImageOffer": "WindowsServer",
   "VMOSVersion": "WS2019-Datacenter",
   "VMOSDiskName": "VM2OSDisk",
   "VMSize": "Standard_D2_v2",
   "VM2ImagePublisher": "MicrosoftWindowsServer",
   "VM2ImageOffer": "WindowsServer",
   "VM2OSDiskName": "VM2OSDisk",
   "VMSize": "Standard_D2_v2"

The VM has a dependency on the network interface. It doesn’t have to have a dependency on the virtual network, because the network interface itself does. This VM is using managed disks so there are no references to storage accounts for the VHD file. The following code snippet shows a sample virtual machine resource.

   {
      "name": "[parameters('VMName')]",
      "type": "Microsoft.Compute/virtualMachines",
      "location": "[resourceGroup().location]",
      "apiVersion": "2017-03-30",
      "dependsOn": [
        "[resourceId('Microsoft.Network/networkInterfaces', variables('VMNicName'))]"
      ],
      "properties": {
        "hardwareProfile": {
          "vmSize": "[variables('vmSize')]"
        },
        "osProfile": {
          "computerName": "[variables('VMName')]",
          "adminUsername": "[parameters('VMAdminUsername')]",
          "adminPassword": "[parameters('VMAdminPassword')]"
        },
        "storageProfile": {
          "imageReference": {
            "publisher": "[variables('VMImagePublisher')]",
            "offer": "[variables('VMImageOffer')]",
            "sku": "[variables('VMOSVersion')]",
            "version": "latest"
        },
        "osDisk": {
          "createOption": "FromImage"
        }
      },
        "networkProfile": {
          "networkInterfaces": [
            {
              "id": "[resourceId('Microsoft.Network/networkInterfaces',
variables('VMNicName'))]"
            }
          ]
        }
      }
   }

There are several properties of a virtual machine resource that are critical to its configuration.

  • hardwareProfile This element is where you set the size of the virtual machine. Set the vmSize property to the desired size such as Standard_D2_v2.

  • osProfile This element at a basic level is where you set the computerName and adminUsername properties. The adminPassword property is required if you do not specify an SSH key. This element also supports three sub elements: windowsConfiguration, linuxConfiguration and secrets.

  • osProfile, windowsConfiguration While the example doesn’t use this configuration, this element provides the ability to set advanced properties on Windows VMs. Examples include:

    • provisionVMAgent Enabled by default, but you can disable.

    • customData Specify base-64 encoded data to be added to the VM at creation time. This data can be found in C:AzureDataCustomData.bin.

    • timeZone Specify the time zone for the virtual machine.

    • additionalUnattendContent Pass unattended install configuration for additional configuration options.

    • winRM Configure Windows PowerShell remoting.

  • osProfile, linuxConfiguration

    • disablePasswordAuthentication If set to true you must specify an SSH key.

    • Ssh, publicKeys Specify the public key to use for authentication with the VM.

  • osProfile, secrets This element provides the ability to automatically deploy secrets from an Azure Key Vault.

  • storageProfile This element is where OS image is specified, and the OS and data disk configuration are set.

  • networkProfile This element is where the network interfaces for the virtual machine are specified.

More Info Resource Manager Template Schema

Reading through the Azure resource manager template schema is a great way to learn the capabilities of templates. The latest virtual machine schema is published here:
https://docs.microsoft.com/azure/templates/microsoft.compute/2018-10-01/virtualmachines.

The entire template is available here for reference:

{
   "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.
json#",
   "contentVersion": "1.0.0.0",
   "parameters": {
     "VMPublicIPDnsName": {
       "type": "string",
       "minLength": 1
   },
   "VMAdminUserName": {
     "type": "string",
     "minLength": 1
   }, 
   "VMAdminPassword": {
     "type": "string",
     "minLength": 1
   }
},
"variables": {
   "ExamRefRGPrefix": "10.0.0.0/16",
   "ExamRefRGSubnet1Name": "FrontEndSubnet",
   "ExamRefRGSubnet1Prefix": "10.0.0.0/24",
   "ExamRefRGSubnet2Name": "BackEndSubnet",
   "ExamRefRGSubnet2Prefix": "10.0.1.0/24",
   "ExamRefRGSubnet1Ref": "[concat(variables('vnetId'), '/subnets/',
variables('ExamRefRGSubnet1Name'))]",
   "VNetId": "[resourceId('Microsoft.Network/virtualNetworks',
variables('VirtualNetworkName'))]",
   "VirtualNetworkName": "ExamRefVNET",
   "VMPublicIPName": "VMPublicIP",
   "VMNicName": "VMNic",
   "VMName": "MyVM",
   "VMImagePublisher": "MicrosoftWindowsServer",
   "VMImageOffer": "WindowsServer",
   "VMOSVersion": "2019-Datacenter",
   "VMOSDiskName": "VM2OSDisk",
   "VMSize": "Standard_D2_v2"
},
"resources": [
  {
    "name": "[variables('VirtualNetworkName')]",
    "type": "Microsoft.Network/virtualNetworks",
    "location": "[resourceGroup().location]",
    "apiVersion": "2017-06-01",
    "dependsOn": [],
    "properties": {
      "addressSpace": {
        "addressPrefixes": [
          "[variables('ExamRefRGPrefix')]"
        ]
      },
      "subnets": [
        {
           "name": "[variables('ExamRefRGSubnet1Name')]",
           "properties": {
              "addressPrefix": "[variables('ExamRefRGSubnet1Prefix')]"
           }
        },
        {
           "name": "[variables('ExamRefRGSubnet2Name')]",
           "properties": {
              "addressPrefix": "[variables('ExamRefRGSubnet2Prefix')]"
           }
        }
      ]
    }
  },
  {
    "name": "[variables('VMNicName')]", 
    "type": "Microsoft.Network/networkInterfaces",
    "location": "[resourceGroup().location]",
    "apiVersion": "2017-06-01",
    "dependsOn": [
      "[resourceId('Microsoft.Network/virtualNetworks', 'ExamRefVNET')]",
      "[resourceId('Microsoft.Network/publicIPAddresses',
variables('VMPublicIPName'))]"
    ],
    "properties": {
      "ipConfigurations": [
        {
          "name": "ipconfig1",
          "properties": {
            "privateIPAllocationMethod": "Dynamic",
            "subnet": {
               "id": "[variables('ExamRefRGSubnet1Ref')]"
            },
            "publicIPAddress": {
               "id": "[resourceId('Microsoft.Network/publicIPAddresses',
variables('VMPublicIPName'))]"
            }
          }
        }
      ]
    }
 },
 {
    "name": "[variables('VMPublicIPName')]",
    "type": "Microsoft.Network/publicIPAddresses",
    "location": "[resourceGroup().location]",
    "apiVersion": "2017-06-01",
    "dependsOn": [],
    "properties": {
      "publicIPAllocationMethod": "Dynamic",
      "dnsSettings": {
         "domainNameLabel": "[parameters('VMPublicIPDnsName')]"
     }
   }
 },
 {
   "name": "[variables('VMName')]",
   "type": "Microsoft.Compute/virtualMachines",
   "location": "[resourceGroup().location]",
   "apiVersion": "2017-03-30",
   "dependsOn": [
     "[resourceId('Microsoft.Network/networkInterfaces', variables('VMNicName'))]"
   ],
   "properties": {
     "hardwareProfile": {
        "vmSize": "[variables('vmSize')]"
     },
     "osProfile": {
        "computerName": "[variables('VMName')]",
        "adminUsername": "[parameters('VMAdminUsername')]",
        "adminPassword": "[parameters('VMAdminPassword')]"
     },
     "storageProfile": {
        "imageReference": {
          "publisher": "[variables('VMImagePublisher')]",
          "offer": "[variables('VMImageOffer')]",
          "sku": "[variables('VMOSVersion')]",
          "version": "latest"
        },
        "osDisk": {
           "createOption": "FromImage"
        }
      },
      "networkProfile": {
        "networkInterfaces": [
           {
              "id": "[resourceId('Microsoft.Network/networkInterfaces',
 variables('VMNicName'))]"
           }
         ]
       }
     }
   }
 ],
 "outputs": {}
}

Configure VHD template

In the storageProfile section of a virtual machine resource you can specify the imageReference element that references an image from the Azure Marketplace.

"imageReference": {
   "publisher": "[variables('VMImagePublisher')]",
   "offer": "[variables('VMImageOffer')]",
   "sku": "[parameters('VMOSVersion')]",
   "version": "latest"
}

You also can specify a generalized VHD that you have previously created. To specify a user image, you must specify the osType property (Windows or Linux), and the URL to the VHD itself, and the URL to where the disk will be created in Azure storage (osDiskVhdName). The following alternative code snippet demonstrates this (this sample does not build on the previous example):

"storageProfile": {
   "osDisk": {
      "name": "[concat(variables('vmName'),'-osDisk')]",
      "osType": "[parameters('osType')]",
      "caching": "ReadWrite",
      "image": {
         "uri": "[parameters('vhdUrl')]"
      },
      "vhd": {
         "uri": "[variables('osDiskVhdName')]"
      }, 
      "createOption": "FromImage"
      }
}

For context, the following vhdUrl parameter, and osDiskVhdName variable is shown:

"vhdUrl": {
  "type": "string",
     "metadata": {
       "description": "VHD Url..."
       }
 }

"osDiskVhdName": "[concat('http://',parameters('userStorageAccountName'),
'.blob.core.windows.net/',parameters('userStorageContainerName'),'/',
parameters('vmName'),'osDisk.vhd')]"

See the following for a complete template example:
https://docs.microsoft.com/mt-mt/azure/marketplace/cloud-partner-portal/virtual-machine/cpp-deploy-json-template.

Deploy from template

You can deploy templates using the portal, the command line tools, or directly using the REST API. Let’s start with deploying a template that creates a virtual machine using the portal. To deploy a template from the portal, click the Create Resource button and search for Template Deployment, as shown in Figure 3-42, and select the Template Deployment name from the search results, and then click Create.

A screen shot shows the blade that shows the template deployment option from the Azure portal.

Figure 3-42 The Template Deployment option

From there, you have the option to build your own template using the portal’s editor (you can paste your own template in or upload from a file using this option too) or choose from one of the most common templates. Last of all, you can search the existing samples in the quick start samples repository and choose one of them as a starting point. Figure 3-43 shows the various options after clicking the template deployment search result.

A screen shot shows the Template Deployment blade with options for editing, choosing a common template, or selecting a template from GitHub.

Figure 3-43 Options for configuring a template deployment

Clicking the Build your own template in the editor option allows you to paste in template code directly. This allows you to author and then deploy them using the portal for simple testing. In Figure 3-44 you can see the Edit template view and the template explained earlier in the chapter.

A screen shot shows the Azure portal template editing experience.

Figure 3-44 Editing a template using the Azure portal editor

Clicking save from the previous screen takes you to the page shown in Figure 3-45 where you can specify the resource group, and any parameters needed to deploy the template.

A screen shot shows the view of a resource manager template in the editor view of the Azure portal.

Figure 3-45 The template editor view

The edit parameters button allows you to edit a JSON view of the parameters for the template, as shown in Figure 3-46. This file can also be downloaded and is used to provide different behaviors for the template at deployment time without modifying the entire template.

Common examples of using a parameters file:

  • Defining different instance sizes or SKUs for resources based on the intended usage (small instances for test environments for example)

  • Defining different number of instances

  • Different regions

  • Different credentials

screen shot shows editing template parameters using the Azure portal.

Figure 3-46 Editing template parameters using the Azure portal

The last step to creating a template using the portal is to click the Purchase button after reviewing and agreeing to the terms and conditions on the screen.

The Azure command line tools can also deploy templates. The template files can be located locally on your file system or accessed via HTTP/HTTPs. Common deployment models have the templates deployed into a source code repository or an Azure storage account to make it easy for others to deploy the template.

This example uses the Azure PowerShell cmdlets to create a new resource group, specify the location, and then deploy a template by specifying the URL from the Azure QuickStart GitHub repository.

# Create a Resource Group
$rgName = "ExamRefRG"
$location = "WestUs"
New-AzResourceGroup -Name $rgName -Location $location
# Deploy a Template from GitHub
$deploymentName = "simpleVMDeployment"

$templateUri = "https://raw.githubusercontent.com/Azure/azure-quickstart-
templates/master/101-vm-simple-windows/azuredeploy.json"
New-AzResourceGroupDeployment -Name $deploymentName `
                -ResourceGroupName $rgName `
                -TemplateUri $templateUri

If the template requires parameters without default values, the cmdlet will prompt you to input their values.

Images Exam Tip

The parameters to a template can be passed to the New-AzResourceGroupDeployment cmdlet using the TemplateParameterObject parameter for values that are defined directly in the script as .json. The TemplateParameterFile parameter can be used for values stored in a local .json file. The TemplateParameterUri parameter for values that are stored in a .json file at an HTTP endpoint.

The following example uses the Azure CLI tools to accomplish the same task.

#!/bin/bash
# Create the resource group
rgName="Contoso"
location="WestUS"
az group create --name $rgName --location $location
# Deploy the specified template to the resource group
deploymentName="simpleVMDeployment"
templateUri="https://raw.githubusercontent.com/Azure/azure-quickstart-
templates/master/101-vm-simple-linux/azuredeploy.json"
az group deployment create --name $deploymentName --resource-group $rgName
--template-uri $templateUri

Images Exam Tip

The parameters to a template can be passed to the az group deployment create command using the parameters section for values that are defined directly in the script as .json. The template-file parameter can be used for values stored in a local .json file. The template-uri parameter can be used for values that are stored in a .json file at an HTTP endpoint.

Modify Azure Resource Manager (ARM) template

Often you will need to modify a template that you have previously used to change the configuration. As previously mentioned, one of the key concepts of using templates to describe your infrastructure (commonly referred to as infrastructure as code) is so you can modify it and deploy in a versioned manner. To accommodate this behavior Azure Resource Manager supports two different deployment modes: Complete and Incremental.

In Complete mode, Azure Resource Manager deletes resources that exist in the resource group that are not in the template. This is helpful if you need to remove a resource from Azure and you want to ensure your template matches the deployment. You can remove the resource from the template, deploy using complete mode, and it would be removed.

In Incremental mode, Azure Resource Manager leaves unchanged resources that exist in the resource group but aren’t in the template. It will update the resources in the resource group if the settings in the template differ from what is deployed.

Incremental is the default mode for the portal and when deploying through the command line tools or Visual Studio. To use Complete mode, you must use the REST API or the command line tools with the mode/--mode parameter set to Complete.

The following example deploys a template in Complete mode using PowerShell.

New-AzResourceGroupDeployment `
  -Mode Complete `
  -Name simpleVMDeployment `
  -ResourceGroupName ExamRefRG

This example deploys a template in Complete mode using the Azure CLI.

az group deployment create 
   --name simpleVMDeployment 
   --mode Complete 
   --resource-group ExamRefRG

Save a deployment as an ARM Template

An existing deployment can be exported as a template that you can use to regenerate the environment or to just gain a better understanding of how the deployment is configured. There are two ways of exporting a template from a deployment within a resource group.

The first way is to export the actual template used for the deployment. This method exports the template exactly as it was used, including the values for parameters and variables during the original execution. This approach does not capture any changes made to the deployment after it was deployed. To export this template, navigate to the resource group in the Azure portal and click Deployments, select the deployment to export, and click View Template on the top navigation. Figure 3-47 depicts a deployment selected inside of a Resource Group.

A screen shot that shows the expanded deployments blade with a deployment selected.

Figure 3-47 The deployments view of an Azure Resource Group in the Azure portal

Clicking the View Template link opens in the Template deployment view as shown in Figure 3-48. From here, you can click Download to download the template locally, Deploy to redeploy the template using different parameters, or you can click Add to library to save to your template gallery for later deployment.

A screen shot that shows the expanded deployments blade with a deployment selected.

Figure 3-48 The deployments view of an Azure resource group in the Azure portal

The second approach generates a template that represents the current state of the resource group. The state may have been updated by multiple templates, changes from the portal or changes via the REST API or command line. It may include many hard-coded values and probably not as many parameters as you would expect in a template that was designed for reusability. This template is useful for redeploying to the same resource group due to the hard-coded values. Using it for other resource groups may require a significant amount of editing. You can access this template by navigating to the resource group and clicking the Automation Script link on the left navigation.

You can also export templates using the command line. The following examples show how to export the actual template using Azure PowerShell and then the Azure CLI.

The following PowerShell code will save the template to the current folder named MyDeployment.json.

Save-AzResourceGroupDeploymentTemplate -ResourceGroupName ExamRefRG -DeploymentName
simpleVMDeployment

The following CLI code will accomplish the same task, except it will output the template to the console.

az group deployment export --name simpleVMDeployment --resource-group ExamRefRG

The following code will export all resources in the resource group as a template using the Azure PowerShell cmdlets. In this example ExamRefRG is the name of the resource group.

Export-AzResourceGroup -ResourceGroupName ExamRefRG

The following code will export all resources in the resource group as a template using the Azure CLI. In this example ExamRefRG is the name of the resource group.

az group export --name ExamRefRG

Configure location of new VMs

Templates and the command line tools simplify reusability of templates with parameter files. A parameter file is simply a set of names and values that you define separately from the template or script. This makes it easy to design your templates with parameters that can be changed depending on the needs at deployment time and even save the parameters’ files separately for increased reusability.

A few of the more common use cases include:

  • Location of Azure resources Defining the region information in a parameters file makes it easy to reuse a template for any region without having to modify the template itself because the template can just reference the region based on the parameter versus hard-coding it.

  • Virtual machine size Depending on the environment (dev, test, or production) the expected load may differ greatly.

  • Number of resources Like virtual machine size, a development environment may only need a small footprint of the deployment to be functional compared to a full-blown production environment.

  • Tags Tagging resources based on cost-center for charge back, or environment is highly simplified using templates and parameter files.

The following example demonstrates an example template file that uses VM scale sets.. In this example, two different parameter files are defined. The dev-env.json template defines values for a development environment with the location specified as WestUS, the vmSize variable set to Standard_DS1, and the instanceCount set to 1.

dev-env.json
{
   "$schema": "https://schema.management.azure.com/schemas/2015-01-01/
deploymentParameters.json#",
   "contentVersion": "1.0.0.0",
   "parameters": {
      "location": {
         "value": "WestUS "
      },
      "vmSize": {
         "value": "Standard_DS1"
      },
      "instanceCount": {
         "value": "1"
      }
   }
}

The prod-env.json template defines values for a production environment with the location specified as EastUS, the vmSize variable set to Standard_DS3, and the instanceCount set to 4.

prod-env.json
{
   "$schema": "https://schema.management.azure.com/schemas/2015-01-01/
deploymentParameters.json#",
   "contentVersion": "1.0.0.0",
   "parameters": {
      "location": {
         "value": "EastUS"
      },
      "vmSize": {
         "value": "Standard_DS3"
      },
      "instanceCount": {
         "value": "4"
      }
   }
}

The following code snippet shows how to pass a template file during deployment using PowerShell and reference a parameters file:

New-AzResourceGroupDeployment -Name MyDeployment -ResourceGroupName ExamRefRG `
   -TemplateFile c:MyTemplatesAppTemplate.json `
   -TemplateParameterFile c:MyTemplatesdev-env.json

This example shows how to deploy a template using a parameters file using the Azure CLI.

az group deployment create 
   --name MyDeployment 
   --resource-group ExamRefRG 
   --template-file AppTemplate.json 
   --parameters @dev-env.json

Images Exam Tip

Virtual machine scale sets make it easy to create multiple instances of a virtual machine. To create multiple resources of other resource types such as storage accounts, web apps, and so on, you can use the copy element in conjunction with the copyIndex() function. Learn more about this feature here: https://docs.microsoft.com/azure/azure-resource-manager/resource-group-create-multiple.

Skill 3.3: Manage Azure VM

So far, this chapter has covered the creation and configuration of virtual machines, including techniques for automatically deploying VMs using templates and the command line tools. This section will focus on post creation tasks such as adding additional storage, adding additional network interfaces, redeploying VMs, changing VM sizes, and moving virtual machines to a different resource group and subscription. The chapter will close on automatic configuration techniques for updating the configuration of the virtual machine itself.

Add data disks

Adding a data disk to an existing Azure virtual machine using the Azure portal is almost identical to the creation process. From within the virtual machine configuration blade, click Disks, and then click Add Data Disk. This action will open the dialog displayed in Figure 3-49. From there, you can choose one of the existing disks that are available to attach, or you can click Create to create a new disk that will walk through the create disk user experience.

A screen shot that shows the expanded deployments blade with a deploymentselected.

Figure 3-49 The deployments view of an Azure resource group in the Azure portal

If your virtual machine was created with managed disks enabled, you will see the blade displayed in Figure 3-50 for Create Managed Disk. From here you can specify the Name of the disk, the Resource Group, the storage Account Type, and the Source Type.

You can use the following sources to create a new managed disk:

  • Snapshot If selected, you can browse for snapshots in the current subscription and location.

  • Storage blob If selected, you can browse storage accounts in all subscriptions you have access to, so you can select the VHD.

  • None (empty disk) If selected, a new empty VHD is created.

A screen shot that shows the Create Managed Disk blade in the Azure portal. Selected are Premium SSD and Storage blob.

Figure 3-50 The Create Managed Disk blade in the Azure portal

If the virtual machine was created with Use Unmanaged Disks selected, you will see the blade to attach an unmanaged disk as shown in Figure 3-51. This blade allows you to create a new empty disk or attach an existing VHD from the same storage account. You can also specify the container and blob name for the new VHD.

A screen shot that shows the Attach Unmanaged Disk blade in the Azure portal. Premium SSD is selected.

Figure 3-51 The Attach Unmanaged Disk blade in the Azure portal

The following example demonstrates how to attach a new managed disk using PowerShell.

$dataDiskName = "MyDataDisk"
$location = "WestUS"

# Create the disk configuration
$diskConfig = New-AzDiskConfig -SkuName Premium_LRS -Location $location
-CreateOption Empty -DiskSizeGB 128

# Create the disk
$dataDisk1 = New-AzDisk -DiskName $dataDiskName -Disk $diskConfig
-ResourceGroupName ExamRefRG

# Retrieve the currentVM

$vm = Get-AzVM -Name ExamRefVM -ResourceGroupName ExamRefRG

# Attach the disk
$vm = Add-AzVMDataDisk -VM $vm -Name $dataDiskName -CreateOption Attach
-ManagedDiskId $dataDisk1.Id -Lun 1 

# Update the VM
Update-AzVM -VM $vm -ResourceGroupName ExamRefRG

Images Exam Tip

If the virtual machine is deployed into an availability zone, use the Zone parameter with the New-AzDiskConfig cmdlet to specify which availability zone to create the disk in if you are creating the disk using PowerShell.

The Azure CLI tools can also accomplish the same task as the following example demonstrates:

az vm disk attach 
   -g ExamRefRG 
   --vm-name ExamRefVM 
   --name myDataDisk 
   --new 
   --size-gb 128 
   --sku Premium_LRS

Images Exam Tip

If the virtual machine is deployed into an availability zone, the disk is automatically placed into the same zone as the virtual machine using Azure CLI.

Add network interfaces

A network interface enables an Azure virtual machine to communicate with the Internet, Azure, and on-premises resources. Common use cases for having multiple network interfaces are:

  • Network and security function Multiple network interfaces enable virtual network appliances such as load balancers, firewalls, and proxy servers.

  • Network isolation Common best practices include isolating public facing services from internal networks.

  • Bandwidth isolation In certain cases, such as heartbeat signals, it is important to have isolated traffic to guarantee the minimal amount of bandwidth is available to the workload.

To add a new network interface to an Azure virtual machine, click the Networking link on the left navigation of the virtual machine configuration blade and then click the Attach Network Interface link at the top. The next screen allows you to attach an existing network interface or click Create network interface to create a new one. Figure 3-52 shows the blade for creating a new network interface.

A screen shot that shows creating a new network interface using the portal. A static private IP address of 10.0.1.100 is assigned.

Figure 3-52 Creating a new network interface in the Azure portal

After the network interface is created, you must first deallocate the virtual machine before you can attach it. You can deallocate the VM by clicking Stop in the Azure portal or using the command line tools.

A screen shot that shows attaching a network interface named BackendNic to a virtual machine.

Figure 3-53 Attaching a new network interface to a virtual machine

The following example demonstrates how to create and attach a new network interface to an existing virtual machine using PowerShell.

$vnetName = "ExamRefVNET" # Ensure your VNET Name matches
$subnetName = "Subnet-1" # Ensure your subnet matches
$rgName = "ExamRefRG"
$vmName = "ExamRefVM"
$nicName="newnic"

# Deallocate the VM first 
Stop-AzVm -Name $vmName -ResourceGroupName $rgName

# Retrieve the VM configuration
$vm = Get-AzVm -Name ExamRefVM -ResourceGroupName $rgName

# Get info for the back-end subnet
$myVnet = Get-AzVirtualNetwork -ResourceGroupName $rgName -Name $vnetName
$backEnd = $myVnet.Subnets|?{$_.Name -eq $subnetName}

# Create a virtual NIC
$newNic = New-AzNetworkInterface -ResourceGroupName $rgName `
   -Name $nicName `
   -Location $location `
   -SubnetId $newNic.Id

# Get the ID of the new virtual NIC and add to VM
$nicId = (Get-AzNetworkInterface -ResourceGroupName $rgName -Name $nicName).Id
Add-AzVMNetworkInterface -VM $vm -Id $nicId -Primary | Update-AzVm
-ResourceGroupName $rgName

The following example attaches a network interface using the Azure CLI.

vnetName="ExamRefVNET" # Ensure your VNET Name matches
subnetName="Subnet-1" # Ensure your subnet matches
rgName="ExamRefRG"
vmName="ExamRefVM"
nicName="newnic"

az network nic create 
   --resource-group $rgName 
   --name $nicName 
   --vnet-name $ExamRefVNET 
   --subnet $subnetName
az vm nic add -g $rgName --vm-name $vmName --nics $nicName --primary-nic

By default, the first network interface attached is defined as the primary network interface. All others are secondary. You can control which network interface you send outbound traffic to; by default, it will be the primary network interface.

More Info Multiple Network Interfaces

Beyond understanding the basics of adding network interfaces it is important to understand the nuances and constraints in this area. The Azure documentation does a great job of consolidating and summarizing this information and you can read more about it here: https://docs.microsoft.com/azure/virtual-network/virtual-network-network-interface-vm.

Manage VM sizes

Azure provides purpose built virtual machine sizes. This means that each family is designed for specific purposes to make it easier for you to choose the right VM size for the right workload.

The different types are:

  • General purpose Offers a balanced CPU-to-memory ratio. Ideal for testing and development, small to medium databases, and low to medium traffic web servers.

  • Compute optimized Offers high CPU-to-memory ratio and are good for medium traffic web servers, network appliances, batch processes, and application servers.

  • Memory optimized Offers high memory-to-CPU ratio that are great for relational database servers, medium to large caches, and in-memory analytics.

  • Storage optimized Offers high disk throughput and IO, and are ideal for Big Data, SQL, NoSQL databases, data warehousing, and large transactional databases. Examples include Cassandra, MongoDB, Cloudera, and Redis.

  • GPU optimized Specialized virtual machines available with single or multiple NVIDIA GPUs. These sizes are designed for compute-intensive, graphics-intensive, and visualization workloads. This article provides information about the number and type of GPUs, vCPUs, data disks, and NICs. Storage throughput and network bandwidth are also included for each size in this grouping.

  • High performance compute Specialized for handling batch processing, molecular modeling and fluid dynamics. These 8 and 16 vCPU VMs are built on the Intel Haswell E5-2667 V3 processor technology featuring DDR4 memory and SSD-based temporary storage. In addition to the substantial CPU power, the H-series offers diverse options for low latency RDMA networking using FDR InfiniBand and several memory configurations to support memory intensive computational requirements.

Azure virtual machines make it relatively easy to change the size of a virtual machine even after it has been deployed. There are a few things to consider with this approach.

The first consideration is to ensure that the region your VM is deployed to supports the instance size that you want to change the VM to. In most cases this is not an issue, but if you have a use case where the desired size isn’t in the region the existing VM is deployed to, your only options are to either wait for the size to be supported in the region, or to move the existing VM to a region that already supports it.

The second consideration is if the new size is supported in the current hardware cluster your VM is deployed to. This can be determined by clicking the Size link in the virtual machine configuration blade in the Azure portal of a running virtual machine, as Figure 3-54 demonstrates. If the size is available, you can select it. Changing the size reboots the virtual machine.

A screen shot that shows the user interface in the Azure portal to filter and change virtual machine sizes.

Figure 3-54 Changing the size of an Azure virtual machine using the Azure portal

If the size is not available, it means either the size is not available in the region or the current hardware cluster. You can view the available sizes by region at: https://azure.microsoft.com/regions/services/. In the event you need to change to a different hardware cluster you must first stop the virtual machine, and if it is part of an availability set you must stop all instances of the availability set at the same time. After all the VMs are stopped, you can then change the size, which moves all the VMs to the new hardware cluster as they are resized and started. The reason all VMs in the availability set must be stopped before performing the resize operation to a size that requires different hardware is that all running VMs in the availability set must use the same physical hardware cluster. Therefore, if a change of physical hardware cluster is required to change the VM size, all VMs must be first stopped and then restarted one-by-one to a different physical hardware cluster.

A third consideration is the form factor of the new size compared to the old size. Consider scaling from a DS3_V2 to a DS2_V2. A DS3_V2 supports up to eight data disks and up to four network interfaces. A DS2_V2 supports up to four data disks and up to two network interfaces. If the VM you are sizing from (DS3_V2) is using more disks or network interfaces then the target size, the resize operation will fail.

Resizing a VM (PowerShell)

Use the Get-AzVMSize cmdlet and pass the name of the region to the location parameter to view all of the available sizes in your region to ensure the new size is available. If you specify the resource group and the VM name, it returns the available sizes in the current hardware cluster.

# View available sizes
$location = "WestUS"
Get-AzVMSize -Location $location

After you have identified the available size, use the following code to change the VM to the new size.

$rgName = "EXAMREGWEBRG"
$vmName = "Web1" 
$size = "Standard_DS2_V2"
$vm = Get-AzVM -ResourceGroupName $rgName -VMName $vmName
$vm.HardwareProfile.VmSize = $size
Update-AzVM -VM $vm -ResourceGroupName $rgName

If the virtual machine(s) are part of an availability set, the following code can be used to shut them all down at the same time and restart them using the new size.

$rgName = "ExamRefRG"
$vmName = "Web1"
$size = "Standard_DS2_V2"
$avSet = "WebAVSet"
Resizing a VM (CLI)

The az vm list-vm-resize-options command can be used to see which VM sizes are available in the current hardware cluster.

rgName="ExamRefRG"
vmName="Web1"
az vm list-vm-resize-options --resource-group $rgName --name $vmName --output table

The az vm list-sizes command is used to view all sizes in the region.

az vm list-sizes --location westus

The az vm resize command is used to change the size of an individual VM.

az vm resize --resource-group $rgName --name $vmName --size Standard_DS3_v2

More Info Virtual Machine Sizes

There are a lot of considerations when choosing the correct virtual machine size. For more information on sizes in the context of Windows-based virtual machines see the following:
https://docs.microsoft.com/azure/virtual-machines/windows/sizes. For the Linux version of the article see the following:
https://docs.microsoft.com/azure/virtual-machines/linux/sizes.

Move VMs from one resource group to another

Azure provides the ability to move some resources from one subscription to another or from resource group to resource group.

To move a virtual machine using the Azure portal, open the VM blade as shown in Figure 3-55 and click the change link next to the Resource group label or the change button next to the subscription label.

A screen shot that shows the virtual machine blade with the change options visible for Resource Group and Subscription.

Figure 3-55 The virtual machine blade with the change options visible for Resource Group and Subscription

Clicking the change link by the by the resource group name will bring up a new blade as shown in Figure 3-56. This blade shows the resources related to the virtual machine, such as disks, network security groups, network interfaces and so on. From here, you can select the individual resources to move to the destination resource group and the destination resource group.

Since the resource group will change, any existing scripts that target resources in this resource group will no longer work until they have been updated. The portal prompts you to confirm that you are aware of this change before you can continue with the move.

A screen shot that shows the related resources blade which shows the related resources for the virtual machine. The target resource group ExamRefRG is selected and the checkbox for I Understand That Tools And Scripts Associated With Moved Resources Will Not Work Until I Update Them To Use New Resource IDs is checked.

Figure 3-56 The move resources blade showing the related resources for a virtual machine

The following example code shows how to use PowerShell to move a resource:

# Use Get-AzResource to identify the resource ID value 
Get-AzResource -ResourceGroupName ExamRefRG | Format-table -Property ResourceId
# Store the resource ID in a variable
$resourceID = "[your resource id here]"
# Specify the destination resource group and the resource ID to move
Move-AzResource -DestinationResourceGroupName ExamRefDestRG
-ResourceId $resourceID

# To move to a different subscription, use the -DestinationSubscriptionId parameter
$subscriptionID = "[your subscription id here]"
Move-AzResource -DestinationSubscriptionId $subscriptionID `
    -DestinationResourceGroupName ExamRefDestRG `
    -ResourceId $resourceID

The Azure CLI can accomplish the same task as shown here:

# List the resource IDs
az resource list -g ExamRefRG
resourceID="[your resource id here]"
# Move to a different resource group
az resource move --destination-group ExamRefDestRG --ids $resourceID
# Use the --subscription-id parameter to move to a different subscription
subscriptionID="[your resource id here]"
az resource move --destination-group ExamRefDestRG
–destination-subscription-id $suscriptionID --ids $resourceID

More Info Supported Resources for Moving

Not all resources are fully supported moving between resource groups and subscriptions, and there are several caveats regarding virtual machines. See the following for more details:
https://docs.microsoft.com/azure/azure-resource-manager/resource-group-move-resources.

Redeploy VMs

To help with troubleshooting issues such as RDP or SSH connectivity or application access redeploying the VM may help. When you redeploy a VM, it moves the VM to a new node within Azure and turns it back on. The Redeploy button is shown in Figure 3-57.

A screen shot that shows the redeploy blade and button in the Azure portal.

Figure 3-57 The redeploy blade in the Azure portal

To redeploy the VM using PowerShell use the Set-AzVM cmdlet as shown here:

Set-AzVM -Redeploy -ResourceGroupName ExamRefRG -Name ExamRefVM

To redeploy with the Azure CLI tools use the az vm redeploy command.

az vm redeploy --resource-group ExamRefRG --name ExamRefVM

Automate configuration management

Azure virtual machines have a variety of built-in extensions that can enable configuration management as well as a variety of other operations such as installing software agents and even enabling remote debugging for live troubleshooting purposes. The two most common extensions for configuration management are the Windows PowerShell Desired State Configuration (DSC) extension and the more generic Custom Script Extension. Both extensions can be executed at provisioning time or after the virtual machine has already been started. The Windows PowerShell DSC Extension allows you to define the state of a virtual machine using the PowerShell Desired State Configuration language and apply it as well as perform continuous updates when integrated with the Azure Automation DSC service. The custom script extension can be used to execute an arbitrary command such as a batch file, regular PowerShell script, or a bash script. In addition to these extensions there are also more specific extensions that allow you to configure your virtual machines to use open source configuration management utilities such as Chef or Puppet and many others.

The next step is the Guest config blade, depicted in Figure 3-58. This blade allows the user creating the virtual machine to install a custom script extension such as the custom script extension or one of many others.

A screen shot that shows the Guest config blade in the Azure portal. Depicted is an option to allow a user to select an extension to install and that the selected virtual machine does not support cloud init.

Figure 3-58 The Guest config blade in the Azure portal

Figure 3-59 depicts the custom script extension blade that appears when you click the option to select an extension to install.

A screen shot that shows some of the available custom script extensions that can be installed on the virtual machine during creation using the Azure portal.

Figure 3-59 The select a custom script extension menu

PowerShell Desired State Configuration

PowerShell Desired State Configuration (DSC) allows you to declaratively configure the state of the virtual machine. Using built-in resource providers or custom providers with a DSC script enables you to declaratively configure settings such as roles and features, registry settings, files and directories, firewall rules, and most settings available to Windows. One of the compelling features of DSC is that, instead of writing logic to detect and correct the state of the machine, the providers do that work for you and make the system state as defined in the script.

For example, the following DSC script declares that the Web-Server role should be installed, along with the Web-Asp-Net45 feature. The WindowsFeature code block represents a DSC resource. The resource has a property named Ensure that can be set to Present or Absent. In this example, the WindowsFeature resource verifies whether the Web-Server role is present on the target machine and if it is not, the resource installs it. It repeats the process for the Web-Asp-Net45 feature.

Configuration ContosoSimple
{
   Node "localhost"
   {
     #Install the IIS Role
     WindowsFeature IIS
     {
       Ensure = "Present"
       Name = "Web-Server"
     }
     #Install ASP.NET 4.5 
     WindowsFeature AspNet45
     {
       Ensure = "Present"
       Name = "Web-Asp-Net45"
     }
   }
}

In addition to the default DSC resources included by default with PowerShell DSC, there is an open source DSC resource kit hosted in GitHub that has many more resources that are maintained and updated by the Windows PowerShell engineering team, and of course you can write your own. To install a custom resource, download it and unzip it into the C:Program Files WindowsPowerShellModules folder. To learn about and download the latest DSC resource kit from Microsoft see the following GitHub repo at: https://github.com/PowerShell/DscResources.

The example uses the xPSDesiredStateConfiguration module from the DSC resource kit to download a .zip file that contains the website content. This module can be installed using PowerShellGet by executing the following commands from an elevated command prompt:

Install-Module -Name xPSDesiredStateConfiguration

After the module is installed locally the xPSDesiredStateConfiguration resource is available for use in your script.

# ContosoWeb.ps1
configuration Main
{
   # Import the module that defines custom resources
   Import-DscResource -Module xPSDesiredStateConfiguration
   Node "localhost"
   {
      # Install the IIS role
      WindowsFeature IIS
       {
          Ensure = "Present"
          Name = "Web-Server"
       }
       # Install the ASP .NET 4.5 role
      WindowsFeature AspNet45
      {
          Ensure = "Present"
          Name = "Web-Asp-Net45"
      }
      # Download the website content
      xRemoteFile WebContent
      {
         Uri = "https://cs7993fe12db3abx4d25xab6.blob.core.windows.net/
public/website.zip"
         DestinationPath = "C:inetpubwwwroot" 
         DependsOn = "[WindowsFeature]IIS"
      }
      Archive ArchiveExample
      {
          Ensure = "Present"
          Path = "C:inetpubwwwrootwebsite.zip"
          Destination = "C:inetpubwwwroot"
          DependsOn = "[xRemoteFile]WebContent"
      }
    }
}

Before the DSC script can be applied to a virtual machine, you must use the Publish-AzVMDscConfiguration cmdlet to package the script into a .zip file. This cmdlet also imports any dependent DSC modules such as xPSDesiredStateConfiguration into the .zip.

Publish-AzVMDscConfiguration -ConfigurationPath .ContosoWeb.ps1
-OutputArchivePath .ContosoWeb.zip

To apply the extension, open the virtual machine blade in the portal and click Extensions. Click Add and then click the PowerShell Desired State Configuration extension as shown in Figure 3-60.

A screen shot shows adding the PowerShell Desired State Configuration extension to a virtual machine.

Figure 3-60 Adding the PowerShell Desired State Configuration extension

The Configuration Modules or Script field expects the .zip file created by the call to the Publish-AzVMDscConfiguration cmdlet. The Module-Qualified Name of Configuration field expects the name of the script file (with the .ps1 extension) concatenated with the name of the function in the script, which in the example shown in Figure 3-61 is ContosoWeb.ps1Main. The PowerShell DSC extension is versioned, in this example we are using version 2.76.

A screen shot shows specifying the configuration for the Azure Desired State Configuration extension on an Azure VM.

Figure 3-61 Configuring the Azure Desired State Configuration extension

One of the powerful features of PowerShell DSC is the ability to parameterize the configuration. This means you can create a single configuration that can exhibit different behaviors based on the parameters passed. The Configuration Data PSD1 file field is where you can specify these parameters in the form of a hashtable. You can learn more about how to separate configuration from environment data at: https://docs.microsoft.com/powershell/dsc/separatingenvdata.

The PowerShell DSC extension also allows you to specify whether to use the latest version of the Windows Management Framework (WMF) and to specify the specific version of the DSC extension to use, and whether to automatically upgrade the minor version or not.

More Info Azure Desired State Configuration Extension Version

See the following to see the current version and change history of the Azure Desired State Configuration extension:
https://docs.microsoft.com/powershell/dsc/getting-started/azuredscexthistory.

PowerShell DSC configurations can also be applied programmatically during a PowerShell deployment by using the Set-AzVmDscExtension cmdlet. In the example below, the Publish-AzVMDscConfiguration cmdlet is used to publish the packaged script to an existing Azure storage account before applying the configuration using the Set-AzVMDscExtension cmdlet on an existing virtual machine.

$rgName = "ExamRefRG"
$location = "WestUS"
$vmName = "ExamRefVM"
$storageName = "dscstorageer1"
$configurationName = "Main"
$archiveBlob = "ContosoWeb.ps1.zip"
$configurationPath = ".ContosoWeb.ps1"
#Publish the configuration script into Azure storage
Publish-AzVMDscConfiguration -ConfigurationPath $configurationPath `
                    -ResourceGroupName $rgName `
                    -StorageAccountName $storageName
#Set the VM to run the DSC configuration
Set-AzVmDscExtension -Version 2.76 `
                -ResourceGroupName $rgName `
                -VMName $vmName `
                -ArchiveStorageAccountName $storageName `
                -ArchiveBlobName $archiveBlob `
                -AutoUpdate:$false `
                -ConfigurationName $configurationName

The PowerShell DSC extension can also be applied to a virtual machine created through a resource manager template by extending and adding the resource configuration in the virtual machine’s resource section of the template. This template takes a parameter to a URL hosting the DSC configuration file (.zip). Typically, these are stored in a storage account or Git repository accessible from the template. For example, the previous example code used PublishAzVMDscConfiguration to publish to a storage account named dscstorageer1. The resulting URI would be: https://dscstorageer1.blob.core.windows.net/windows-powershell-dsc/ContosoWeb.ps1.zip. The path windows-powershell-dsc was added by the cmdlet.

 {
   "name": "Microsoft.Powershell.DSC",
   "type": "extensions",
   "location": "[resourceGroup().location]",
   "apiVersion": "2016-03-30",
   "dependsOn": [
      "[resourceId('Microsoft.Compute/virtualMachines', parameters('WebVMName'))]"
   ],
   "tags": {
      "displayName": "WebDSC"
   },
   "properties": {
      "publisher": "Microsoft.Powershell",
      "type": "DSC",
      "typeHandlerVersion": "2.76",
      "autoUpgradeMinorVersion": false, 
   "settings": {
     "configuration": {
        "url": "[parameters('DSCUri'))]",
        "script": "ContosoWeb.ps1",
        "function": "Main"
      },
      "configurationArguments": {
        "nodeName": "[parameters('WebVMName')]"
      }
    },
   "protectedSettings": {
     "configurationUrlSasToken": "[parameters('SasToken')]"
    }
  }
}

The previous examples apply the PowerShell DSC configuration only when the extension is executed. If the configuration of the virtual machine changes after the extension is applied, the configuration can drift from the state defined in the DSC configuration. The Azure Automation DSC service allows you to manage all your DSC configurations, resources, and target nodes from the Azure portal or from PowerShell. It also provides a built-in pull server, so your virtual machines will automatically check on a scheduled basis for new configuration changes, or to compare the current configuration against the desired state and update accordingly.

More Info Azure Automation State Configuration

For more information on how to automatically apply PowerShell DSC configurations to your virtual machines see:
https://docs.microsoft.com/azure/automation/automation-dsc-overview.

Using the custom script extension

The Azure custom script extension is supported on Windows and Linux-based virtual machines and is ideal for bootstrapping a virtual machine to an initial configuration. To use the Azure custom script extension your script must be accessible via a URI such as an Azure storage account, and either accessed anonymously or passed with a shared access signature (SAS URL). The custom script extension takes as parameters the URI and the command to execute including any parameters to pass to the script. You can execute the script at any time the virtual machine is running.

Using the custom script extension (Azure portal)

To add the custom script extension to an existing virtual machine, open the virtual machine in the portal, click the Extensions link on the left, and choose the Custom Script Extension option. The script file is specified as well as any arguments passed to the script. Figure 2-18 shows how to enable this extension using the Azure portal.

A screen shot shows specifying the script file and arguments to pass to the custom script extension.

Figure 3-62 Specifying the custom script extension configuration

Using the custom script extension (PowerShell)

Both the Azure PowerShell cmdlets and the Azure CLI tools can be used to execute scripts using the custom script extension. Starting with PowerShell, the following script deploys the Active Directory Domain Services role. It accepts two parameters: one is for the domain name and the other is for the administrator password.

#deployad.ps1
param(
   $domain,
   $password
)
$smPassword = (ConvertTo-SecureString $password -AsPlainText -Force)
Install-WindowsFeature -Name "AD-Domain-Services" `
               -IncludeManagementTools `
               -IncludeAllSubFeature
Install-ADDSForest -DomainName $domain `
            -DomainMode Win2012 `
            -ForestMode Win2012 `
            -Force `
            -SafeModeAdministratorPassword $smPassword

You can use the Set-AzVMCustomScriptExtension cmdlet to run this script on an Azure virtual machine. This scenario can be used for installing roles or any other type of iterative script you want to run on the virtual machine.

$rgName        = "ExamRefRG"
$vmName        = "ExamRefVM"
$scriptName    = "deploy-ad.ps1"
$domain    = "contoso.com"
$extensionName = "installAD"
$location = "WestUS"
$scriptUri = "https://raw.githubusercontent.com/opsgility/lab-support
-public/master/script-extensions/deploy-ad.ps1" $scriptArgument =
"contoso.com $password"
Set-AzVMCustomScriptExtension -ResourceGroupName $rgName `
                 -VMName $vmName `
                 -FileUri $scriptUri `
                 -Argument "$domain $password" `
                 -Run $scriptName `
                 -Name $extensionName `
                 -Location $location

The FileUri parameter of the Set-AzVMCustomScriptExtension cmdlet, accepts the URI to the script, and the Run parameter tells the cmdlet the name of the script to run on the virtual machine. The script can also be specified using the StorageAccountName, StorageAcountKey, ContainerName, and FileName parameters that qualify its location in an Azure storage account.

Using the custom script extension (CLI)

You can also use the custom script extension for Linux-based virtual machines. The following example demonstrates a simple bash script that installs Apache and PHP. The script would need to be uploaded to an accessible HTTP location such as an Azure storage account or a GitHub repository for the custom script extension to access it and apply it to the virtual machine.

#!/bin/bash
#install-apache.sh
apt-get update
apt-get -y install apache2 php7.0 libapache2-mod-php7.0
apt-get -y install php-mysql
sudo a2enmod php7.0
apachectl restart

The following code example shows how this script can be applied to an Azure Virtual Machine named LinuxVM in the ExamRefRG resource group.

rgName="ExamRefRG"
vmName="LinuxVM"
extensionName="InstallApache"
az vm extension set 
   --resource-group $rgName 
   --vm-name $vmName --name customScript 
   --publisher Microsoft.Azure.Extensions 
   --protected-settings ./cseconfig.json

The az vm extension set command can take the script to execute as a .json based configuration file as the previous example demonstrates. The contents of this .json file are shown for reference:

{ 
  "fileUris": [ "https://raw.githubusercontent.com/opsgility/lab-support-public/master/
script-extensions/install-apache.sh" ],
  "commandToExecute": "./install-apache.sh"
}

Images Exam Tip

There are many other ways of configuring and executing the custom script extension using the Azure CLI tools. The following article has several relevant examples that might be used in an exam, which you can find at: https://docs.microsoft.com/azure/virtual-machines/linux/extensions-customscript.

Like the PowerShell DSC extension, the custom script extension can be added to the resources section of an Azure Resource Manager template. The following example shows how to execute the same script using an ARM template instead of the CLI tools.

{
   "name": "apache",
   "type": "extensions",
   "location": "[resourceGroup().location]",
   "apiVersion": "2015-06-15",
   "dependsOn": [
      "[concat('Microsoft.Compute/virtualMachines/', parameters('scriptextensionNa
me'))]"
   ],
   "tags": {
      "displayName": "installApache"
   },
   "properties": {
      "publisher": "Microsoft.Azure.Extensions",
      "type": "CustomScript",
      "typeHandlerVersion": "2.0",
      "autoUpgradeMinorVersion": true,
   "settings": {
      "fileUris": [
         " https://examplestorageaccount.blob.core.windows.net/scripts/apache.sh "
      ],
      "commandToExecute": "sh apache.sh"
    }
  }
}

More Info Troubleshooting Using Virtual Machine Extension Logs

In the event your custom script extension fails to execute it’s a good idea to review the log files. On Windows the logs are located at: C:WindowsAzureLogsPluginsMicrosoft.Compute.CustomScriptExtension. On Linux the command output is located at:
/var/lib/waagent/Microsoft.OSTCExtensions.CustomScriptForLinux-<version>/download/1.

Skill 3.4: Manage VM Backups

Chapter 2, "Implement and Manage Storage” covered the fundamentals of using the Azure Backup service, such as creating the recovery services vault, backing up and restoring data and creating and configuring backup policies. In this section, we’ll cover those topics more closely aligned to virtual machines.

Configure VM backup

Chapter 2 discussed using the MARS agent and protecting files and folders with Azure Backup. Azure Backup can also back up one or more virtual machines. This solution provides a way to restore an entire virtual machine, or individual files from the virtual machine, and it is quite easy to set up. To back up a VM in Azure with Azure Backup, navigate to the Recovery Service vault and under Getting Started, click Backup. Select Azure as the location where the workload is running, and virtual machine as the workload to backup and click Backup, as shown in Figure 3-63.

A screen shot shows the start of the wizard to back up virtual machines.

Figure 3-63 Configuring Azure Backup to protect virtual machines

The next item to configure is the Backup policy. Here you can create your own policy or choose the default policy. Next, choose the VMs to back up. Only VMs within the same region as the Recovery Services vault are available for backup. Figure 3-64 shows backup user interface with the default policy selected and three virtual machines selected.

A screen shot shows the Recovery Services vault properties where backup is configured, with Azure virtual machines selected.

Figure 3-64 Configuring Azure Backup to backup virtual machines and using the default policy

After the VMs are selected, click the Enable Backup button.

Note Azure VM Protection and Vault Storage Redundancy Type

When protecting IaaS VMs by using Azure Backup, only VMs in the same region as the vault are available for backup. Because of this, it is a best practice to choose Geo-Redundant storage or Read Access Geo-Redundant storage to be associated with the vault. This ensures that, in the case of a regional outage affecting VM access, there is a replicated copy of backups in another region that can be used to restore from.

When you click the Enable Backup button, behind the scenes the VMSnapshot (for Windows) or VMSnapshotLinux (for Linux) extension is automatically deployed by the Azure fabric controller to the VMs. This allows for snapshot-based backups to occur, meaning that first a snapshot of the VM is taken, and then this snapshot is streamed to the Azure storage associated with the Recovery Services vault. The initial backup is not taken until the day/time configured in the backup policy, however an ad-hock backup can be initiated at any time. To do so, navigate to the Protected Items section of the vault properties, and click Backup items. Then, click Azure Virtual Machine under Backup Management type. The VMs that are enabled for backup are listed here. To begin an ad-hock backup, right-click on a VM and select Backup now, as shown in Figure 3-65.

A screen shot shows, within the backup items dialog box in the recovery services vault, to right-click on a configured VM and select Backup now.

Figure 3-65 Starting an ad-hock backup

Backup support for Azure Files and SQL Server in an Azure VM

Azure Backup also directly supports the ability to backup and restore data from Azure Files and SQL Server in an Azure virtual machine. These two features are currently in preview, but it is still a good idea to have a basic understanding of the capabilities as they may eventually appear on the exam.

More Info Azure Files and SQL Server in an Azure VM

Learn about the current capabilities of Azure Backup support for Azure Files here:
https://docs.microsoft.com/azure/backup/backup-azure-files and SQL Server in an Azure VM here: https://docs.microsoft.com/azure/virtual-machines/windows/sql/virtual-machines-windows-sql-backup-recovery.

When to use Azure Backup Server

Azure Backup Server is a stand-alone service that you install on a Windows Server operating system that stores the backed-up data in a Microsoft Azure Recovery Vault. Azure Backup Server inherits much of the workload backup functionality from Data Protection Manager (DPM). Though Azure Backup Server shares much of the same functionality as DPM, Azure Backup Server does not back up to tape and it does not integrate with System Center.

You should consider using Azure Backup server when you have a requirement to back up the following supported workloads:

  • Windows Client

  • Windows Server

  • Linux Servers

  • VMWare VMs

  • Exchange

  • SharePoint

  • SQL Server

  • System State and Bare Metal Recovery

More Info Azure Backup Server Protection Matrix

The entire list of supported workloads and the versions supported for Azure Backup Server can be found here:
https://docs.microsoft.com/azure/backup/backup-mabs-protection-matrix.

Define backup policies

An Azure Backup policy defines how often backups occur and how long the backups are retained. The default policy accomplishes a daily backup at 06:00am and retains backups for 30 days and you can define custom Backup policies. In Figure 3-66 a custom Backup policy is configured that includes Daily, Weekly, Monthly, and Yearly backups, each with their own retention values.

A screen shot shows the Backup policy dialog box where a custom backup policy is configured with Daily, Weekly, Monthly, and Yearly backups and retentions configured.

Figure 3-66 Configuring a custom backup policy

Implement backup policies

To implement a backup policy, open the policy in the Azure portal and click the Associated items button on the menu shown in Figure 3-67.

A screen shot shows the associated items link for the backup policy.

Figure 3-67 The associated items link for the Azure policy

The associated items blade shown in Figure 3-68 shows all the resources currently associated with the policy.

A screen shot that shows the items currently associated with the backup policy.

Figure 3-68 The associated items for the backup policy

Clicking Add will launch the Backup Goal blade where you can add other virtual machines or file shares to be backed up using the goals defined in the policy.

Perform VM restore

After backing up a virtual machine using Azure Backup there are two methods to restore data.

Restoring a virtual machine

To restore a recovery point as a new virtual machine, open the Azure Backup vault and navigate to Backup Items, click Azure Virtual Machine, and then click the virtual machine you want to restore from the list. The next blade will list all the restore points available for restore as shown in Figure 3-69.

A screen shot that shows the available restore points for a virtual machine.

Figure 3-69 Available restore points for a virtual machine.

Select the restore point you are interested in and click the Restore VM link at the top of the page. From there, you can then restore to a new virtual machine by selecting Create New, or you can restore over an existing virtual machine by selecting Replace existing.

Figure 3-70 shows the restore VM blade with the option of Create new selected. Here you can specify the virtual machine name, resource group, virtual network, subnet and storage account.

A screen shot that shows the blade to restore as a new virtual machine.

Figure 3-70 Restore to a new virtual machine

Restoring files from Azure VM backups

If you just need access to files from the virtual machine, choose the File recovery option at the top of the page shown in Figure 3-68 instead. From there, you can select the recovery point and then download a script that will mount the selected recovery point to another computer as local disks. The disks will remain mounted for 12 hours, so you can recover the needed data.

Images Exam Tip

To restore a virtual machine that has encrypted disks you also need to provide the Azure Backup service access to the key vault holding the keys. See the following for more information: https://docs.microsoft.com/azure/backup/backup-azure-vms-encryption.

More Info More details about restoring virtual machines and files

You can learn more about recovering virtual machines with the Azure Backup service here: https://docs.microsoft.com/azure/backup/backup-azure-arm-restore-vms, and here for file level recovery: https://docs.microsoft.com/azure/backup/backup-azure-restore-files-from-vm.

Thought experiment

In this thought experiment, apply what you have learned about this chapter. You can find answers to these questions in the next section.

You are the IT administrator for Contoso and you are tasked with migrating an existing web farm and database to Microsoft Azure. The web application is written in PHP and is deployed across 20 physical servers running RedHat for the operating system and Apache for the web server. The backend consists of two physical servers running MySQL in an active/passive configuration.

The solution must provide the ability to scale to at least as many web servers as the existing solution and ideally the number of web server instances should automatically adjust based on the demand. All the servers must be reachable on the same network, so the administrator can easily connect to them using SSH from a jump box to administer the VMs.

Answer the following questions for your manager:

  1. Which compute option would be ideal for the web servers?

  2. How should the servers be configured for high availability?

  3. What would be the recommended storage configuration for the web servers? What about the database servers?

  4. What feature could be used to ensure that traffic to the VMs only goes to the appropriate services (Apache, MySQL, and SSH)?

Thought experiment answers

This section contains the solution to the thought experiment for the chapter.

  1. The web servers would be best served by deploying them into a virtual machine scale set (VMSS). Autoscale should be configured on the VMSS to address the requirement of automatically scaling up/down the number of instances based on the demand (CPU) used on the web servers.

  2. The web servers should be deployed into their own availability set or availability zone if it is available within the region. The database tier should also be deployed into its own availability set or availability zone.

  3. The web servers will likely not be I/O intensive so Standard SSD should be appropriate. The database servers will likely be I/O intensive so Premium SSD is the recommended approach. To minimize management overhead and to ensure that storage capacity planning is done correctly managed disks should be used in both cases.

  4. Use Network Security Groups (NSGs) to ensure that only traffic destined for allowed services can communicate to the VMs.

Chapter summary

This chapter focused heavily on creating and configuring virtual machines in Azure as well as automated deployments using Azure Resource Manager templates and even the command line tools. The chapter wrapped up focusing on backing up and restoring virtual machine data using the Azure Backup service. Let’s review some of the key takeaways.

  • Each compute family is optimized for either general or specific workloads. You should optimize your VM by choosing the most appropriate size.

  • You can create VMs from the portal, PowerShell, the CLI tools, and Azure Resource Manager templates. You should understand when to use which tool and how to configure the virtual machine resource during provisioning and after provisioning. For example, availability sets can only be set at provisioning time, but data disks can be added at any time.

  • You can connect to Azure VMs using a public IP address or a private IP address with RDP, SSH, or even PowerShell. To connect to a VM using a private IP you must also enable connectivity such as site-to-site, point-to-site, or ExpressRoute.

  • The Custom Script Extension is commonly used to execute scripts on Windows or Linux-based VMs. The PowerShell DSC extension is used to apply desired state configurations to Windows-based VMs.

  • A common method of troubleshooting virtual machines with RDP/SSH connectivity or unexplained application issues is to redeploy the virtual machine. Redeploy moves the virtual machine to a different Azure node.

  • VM storage comes in Standard HDD, Standard SSD, Premium SSD, with Ultimate SSD in preview. Understanding which tier to choose for capacity and performance planning is important.

  • There are unmanaged and managed disks and images. The key difference between the two is with unmanaged disks or images it is up to you to manage the storage account. With managed disks, Azure takes care of this for you, so it greatly simplifies managing images and disks.

  • The Azure Diagnostics agent can be enabled on Windows and Linux virtual machines to capture diagnostic, performance, logs and boot diagnostic data.

  • You can configure alerts based on metric alerts (captured from Azure Diagnostics) to Activity Log alerts that can notify by email, voice, web hook, SMS, Logic Apps, or even an Azure Automation Runbook.

  • Azure Availability Zones provide high availability at the data center level. Azure Availability Sets provide high availability within a data center.

  • Managed disks provide additional availability over unmanaged disks by aligning with availability sets and providing storage in redundant storage units.

  • Virtual Machine Scale Sets (VMSS), can scale up to 1000 instances. You need to ensure that you create the VMSS configured for large scale sets if you intend to go above 100 instances. There are several other limits to consider too. Using a custom image, you can only create up to 300 instances. To scale above 100 instances, you must use the Standard SKU of the Azure Load Balancer or the Azure App Gateway.

  • The Azure Backup service can backup and restore and entire virtual machine and you can also use it for just file recovery to restore files from a recovery point without recreating the entire virtual machine.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset