Understanding Azure Availability Sets

In a previous Ask the Admin, Automate Domain Member Server Deployment in Microsoft Azure, I updated my PowerShell script for deploying domain controllers in Azure VMs by joining the new VM to an Affinity Group, something that’s beneficial for performance and also helps to keep costs to a minimum. For more information on storage performance and Affinity Groups, see Optimizing Azure Storage for Windows Server Virtual Machines on the Petri IT Knowledgebase.

Today I’m going to explain when you should use Availability Sets and how they differ from Affinity Groups. While Affinity Groups are designed to group resources together in a datacenter, Availability Sets do kind of the opposite, making sure that VMs are not grouped in the same fault or update domain. Just to add to the confusion, Affinity Groups and Availability Sets are not mutually exclusive, as they can be used together or separately. But if you want to benefit from the 99.95% Service Level Agreement (SLA) offered by Azure, then you will need to use Availability Sets in your deployments.

Azure Fault and Update Domains

Microsoft periodically updates the underlying Azure fabric that’s used to host VMs to patch security vulnerabilities and improve reliability and performance. These updates, which Microsoft refers to as planned maintenance events, are often performed without any impact to guest VMs. Sometimes, however, guest VMs must be rebooted to complete an update. To reduce the impact on guest VMs, the Azure fabric is divided into Update Domains to ensure that not all guest VMs are rebooted at the same time.

Unplanned maintenance events are those which involve a hardware or physical failure in the fabric, such as a disk, power, or network card outage. Azure automatically fails over guest VMs to a working physical host in a different Fault Domain when an error condition is detected, again aimed at ensuring availability.

Availability Sets

The concept of Availability Sets may seem counterintuitive at first, but you should place two or more VMs in an Availability Set for each application tier. For example, you might place domain controllers in one Availability Set, data-tier SQL servers in a second, and IIS front-end servers in a third. Without this grouping, the Azure fabric has no way of distinguishing the application tiers for each VM, which could lead to a single point of failure in the hardware infrastructure causing an outage or a planned maintenance event rebooting all VMs in the same application tier simultaneously.

Fault Domain (FD) and Update Domain (UD) assignment in Azure Availability Sets (Image Credit: Microsoft)
Fault Domain (FD) and Update Domain (UD) assignment in Azure Availability Sets (Image Credit: Microsoft)

When adding VMs to an Availability Set, Azure automatically assigns each VM an Update Domain and a Fault Domain. By default Availability Sets have two Fault Domains, each sharing a common power source and network switch, and VMs are automatically separated across the Fault Domains. But the number of Fault Domains in an Availability Set isn’t exact, and the only guarantee is that not all the VMs in the set will fail together.

Availability Sets are assigned five Update Domains, and VMs are grouped into these Updates Domains automatically. When a sixth VM is added to an Availability Set, it’s assigned to the first Update Domain, and the seventh VM to the second Update Domain etc. So the first and the sixth VMs added to an Availability Set could be rebooted at the same time in the instance of a planned maintenance event. Only one Update Domain is ever rebooted at a time, but the reboot order isn’t necessarily sequential, so the fifth Update Domain could be rebooted before the first.

Note that I mentioned two or more VMs in an Availability Set. Single instances placed in an Availability Set are not subject to Azure’s SLA, and you won’t receive warnings of planned maintenance events, so Availability Groups should only be used when there’s a group of two or more application tier VMs.

Add a VM to an Availability Set using PowerShell

Unlike Affinity Groups, VMs can be added to Availability Sets either during the provisioning stage or after. Additionally, you don’t need to explicitly create availability sets before using the commands shown below. For more information on using PowerShell to manage Azure, see Setup Windows Azure PowerShell Management on Petri.

Adding an existing Azure VM to an Availability Set (Image Credit: Russell Smith)
Adding an existing Azure VM to an Availability Set (Image Credit: Russell Smith)

To add a VM to an Availability Set when provisioning, use the –AvailabilitySetName parameter of the New-AzureVMConfig cmdlet as show below, replacing the values in –Name, -InstanceSize and –ImageName as appropriate:

​$images = Get-AzureVMImage | where { $_.ImageFamily -eq $osName } | Sort-Object -Descending -Property PublishedDate

$vm = New-AzureVMConfig -Name contosodc1 -InstanceSize medium -ImageName $images[0].ImageName -AvailabilitySetName contosodcs

Alternatively, you can add a VM to an Availability Set after deployment using the Set-AzureAvailabilitySet cmdlet as shown here. Bear in mind that the Update-AzureVM cmdlet will force a reboot.

​Get-AzureVM -ServiceName contosodc1 -Name contosodc1 | Set-AzureAvailabilitySet -AvailabilitySetName contosodcs | Update-AzureVM

To list all the VMs in your Azure subscription, along with the information about their Availability Set membership, use the command below:

​(Get-AzureService).servicename | foreach {Get-AzureVM -ServiceName $_} | select Name, AvailabilitySetName, InstanceUpgradeDomain, InstanceFaultDomain | ft -AutoSize

Or use this command to show information about deployments in a named cloud service, in this case contosodc11:

​Get-AzureService -ServiceName contosodc11 | Get-AzureVM | Select Name, AvailabilitySetName, InstanceUpgradeDomain, InstanceFaultDomain | ft -AutoSize