Keeping an application running is the most important job for an IT professional. People depend on reliability and availability to do their work or consume your service. To achieve maximum uptime with your virtual machines, take a look at Azure availability sets!
In this tutorial, you’ll learn about Azure availability sets and the benefits of using availability sets with your virtual machines. You’ll also learn how to deploy availability sets using PowerShell, Azure CLI, and Terraform. So if you’re ready, let’s get down to it!
What is an Azure Availability Set?
Azure availability sets organize your virtual machines (VMs) into logical groupings. These groupings allow Azure to understand how you have built your application hosted on the virtual machines. Azure can then provide better virtual machine management, redundancy, and availability.
If you prefer to deploy a highly available application, Microsoft recommends placing two or more virtual machines into an availability set. By placing two more VMs in an availability set, you achieve Azure’s 99.95% uptime service-level agreement (SLA). Lucky for you, availability sets are free to use! You only pay for the virtual machines being created.
Saving VMs from Host Reboots with Update Domains
Azure virtual machines are no different than on-premises virtual machines in that virtual machines exist on a single physical host server. An update domain represents the physical host server and virtual machines that Azure can reboot simultaneously.
Think about an application hosted on three virtual machines. Those three virtual machines should not be hosted on the same host server. If that host server experienced a failure, all three virtual machines go offline, and the application is no longer available. An update domain solves this problem.
When you associate VMs with an availability set, Azure will automatically place VMs into separate update domains. As an availability set places VMs into separate domains, it prevents multiple virtual machines from going offline. Update domains also keep virtual machines up when Azure performs maintenance or the host experiences a failure.
During planned maintenance, Azure can reboot update domains in any order. However, Azure guarantees it will only reboot one update domain at a time. Azure gives a rebooted update domain 30 minutes to recover before moving to the next update domain during maintenance.
Availability sets can have up to 20 update domains. The diagram below illustrates how Azure places three virtual machines (VM1, VM2, and VM3) into three update domains across two server racks.
Avoiding VM Outages with Fault Domains
When a server rack loses power that your VM is hosted on, causing physical problems, VM will typically go offline; fault domains prevent that. A fault domain is a group of virtual machines that share these common hardware components. In Azure’s case, a fault domain is a single rack installed with multiple servers.
Azure places virtual machines across up to three fault domains in an availability set. If you review the update domain diagram from the previous section, VM2 and VM3 are hosted in Server Rack 2. VM3 should be in a different fault domain for true application high availability, as you see below.
By placing each virtual machine into a different server rack (or fault domain), Azure limits the impact of hardware failures on the host servers and their virtual machines.
Azure also pairs virtual machines with disk fault domains to ensure that virtual machines have managed disks attached to the same fault domains.
In an upcoming tutorial, you build an availability set, and a screenshot from the Azure Portal of the availability set is below. The availability set you build has three fault domains, three update domains, and three virtual machines. Azure automatically places each virtual machine across the three update domains and fault domains (0, 1, and 2).
Availability Set Best Practices
To take full advantage of availability sets, below are a few best practices.
- Create the availability set before creating virtual machines. Plan out the required fault domains and update domains to support the virtual machine workload.
- Specify the availability set when creating a virtual machine. Azure cannot add an existing virtual machine to an availability set after Azure has provisioned the virtual machine. If you need to add a current virtual machine to an availability set, you redeploy the virtual machine.
- Group virtual machines with similar functions into separate availability sets. For example, if you have a three-tier application, place the virtual machines for each tier into their own availability set.
- Use managed disks for virtual machines. Virtual machines in an availability set have better reliability with managed disks. The managed disks are isolated from each other to protect against single points of failure.
Tutorial: Creating and Deploying Virtual Machines in an Availability Set
With the concepts of the availability set covered, it is time to create an availability set and deploy virtual machines to the availability set! This tutorial covers multiple deployment methods, so feel free to pick your favorite. Throughout the tutorial, all resources are deployed to a resource group named avsetdemo-rg located in Azure region WestUS2.
This tutorial simulates deploying a three-tier application with a web front-end tier, a middle application tier, and a database back-end tier. Let’s dive in!
Azure CLI
Throughout this tutorial, you’ll be running commands in a command-line environment, so let’s start with Azure CLI. You’ll be creating an availability set in Azure CLI to host the web tier of virtual machines. Virtual machines with the same function should be placed in the same availability set.
Below, you’ll create three virtual machines with a PowerShell loop and place each virtual machine into the availability set.
Prerequisites
To follow along in this tutorial, please be sure you have the following items in place:
- Azure CLI v2.0.30 or higher. This tutorial uses v2.25.0
- Windows PowerShell v5.1 (installed by default on Windows 10) or PowerShell v7.0 or higher. This tutorial uses PowerShell v7.1.3.
Now that you have Azure CLI and PowerShell ready, follow the steps below and start creating an availability set!
1. Open your PowerShell console.
2. Log into your Azure environment using the az login
command.
3. Start by creating the availability first before creating VMs. The availability set must first exist before you can add VMs to it.
Create an availability set with the az vm availability-set create
command. Specify the resource-group
(avsetdemo-rg
), the availability set name
(avset-web
), and the platform-fault-domain-count
and platform-update-domain-count
counts (3 each).
When the command completes, you’ll have an availability set with three fault domains and three update domains ready to add some VMs too!
az vm availability-set create --resource-group avsetdemo-rg
--name avset-web --platform-fault-domain-count 3
--platform-update-domain-count 3
4. Define a variable ($webVMs
) containing a list of web front-end server names ('web01','web02','web03'
). You use these names in the next step when creating the virtual machines.
$webVMs = @('web01','web02','web03')
5. Now, loop (foreach
) through each name in $webVMs
to create multiple virtual machines. Provision the virtual machines using the az vm create
command. You can only add VMs to an availability set when you create the VMs, not after, so be sure to add them now!
The example below specifies the virtual machine name
using the current value in $vm
and creates the virtual machine in the resource-group
avsetdemo-rg
. Configure the virtual machine to join the availabilty-set
using the avset-web
name.
The remaining virtual machine properties include the size
(Standard_DS1_v2) and operating system image
(UbuntuLTS
). The virtual machine vnet-name
is vnet-app
, and the network subnet
is snet-web
. Finally, set the admin-username
to cloudadmin
, and use generate-ssh-keys
to create SSH keys for logging in.
foreach ($vm in $webVMs) {
az vm create --name $vm
--resource-group avsetdemo-rg --availability-set avset-web
--size Standard_DS1_v2 --image UbuntuLTS
--vnet-name vnet-app --subnet snet-web
--admin-username cloudadmin `
--generate-ssh-keys
}
Azure PowerShell
Creating an availability set using Azure PowerShell is similar to how you’ve done in it Azure CLI. However, Azure PowerShell requires an extra step of creating an administrator username and password. After you created an availability set, you’ll then create three virtual machines for the app tier with a PowerShell loop and place each virtual machine into the availability set.
Prerequisites
To follow along in this tutorial, please be sure you have the following items in place:
- Azure PowerShell module. This tutorial uses v6.0.0
- Windows PowerShell v5.1 (installed by default on Windows 10) or PowerShell v7.0 or higher. This tutorial uses PowerShell v7.1.3.
Now that you have Azure PowerShell Module and PowerShell console ready, follow the steps below and start creating an availability set!
1. Open a PowerShell console.
2. Log into your Azure environment using the Connect-AzAccount
command.
3. Start by creating the availability first before creating VMs. The availability set must first exist before you can add VMs to it.
Create an availability set by running the New-AzAvailabilitySet
command with a Name
of avset-app
. The command below specifies a ResourceGroupName
(avsetdemo-rg
) in the Location
of WestUS2
.
Configure the availability set for managed disks by setting the Sku
parameter to aligned
. Virtual machines in an availability set have better reliability with managed disks. Finally, set the PlatformFaultDomainCount
and PlatformUpdateDomainCount
to 3
counts each.
When New-AzAvailabilitySet
command completes, you’ll have a new availability set created called avset-app
in the avsetdemo-rg
resource group using managed disks with three fault and update domains.
New-AzAvailabilitySet -Name "avset-app"
-ResourceGroupName "avsetdemo-rg" -Location "WestUS2"
-Sku aligned -PlatformFaultDomainCount 3
-PlatformUpdateDomainCount 3
4. Define a variable named $appVMs
containing a list of the application server names ('app01', 'app02', 'app03'
. You use these names in the next step when creating the virtual machines.
$appVMs = @('app01','app02','app03')
5. Create a PowerShell credential object by running the Get-Credential
, then save these credentials to a variable named $creds
. When prompted, enter a username and password. You will use this credential object later when setting the virtual machine administrator username and password.
$creds = Get-Credential
6. Now, loop (foreach
) through each VM name defined in the $appVMs
array and run New-AzVM
for each name. The examples below creates multiple virtual machines and provisions the virtual machines using the New-AzVM
command. You can only add VMs to an availability set when you create the VMs, not after, so be sure to add them now!
The New-AzVM
command specifies the virtual machine Name
with the current value in $vm
and creates the virtual machine in the resource group named avsetdemo-rg
. Then configures the virtual machine to join the availability set named avset-app
.
The remaining virtual machine properties include the Size
(Standard_DS1_v2
) and operating system Image
(UbuntuLTS
). The virtual machine’s VirtualNetworkName
is vnet-app
, and the network SubnetName
is snet-app
. Finally, use the $creds
credential object created earlier to set the virtual machine Credential
login.
foreach ($vm in $appVMs) {
New-AzVm -Name $vm
-ResourceGroupName 'avsetdemo-rg'
-Location "WestUS2" -AvailabilitySetName "avset-app"
-Size "Standard_DS1_v2" -VirtualNetworkName "vnet-app"
-SubnetName "snet-app" -Image UbuntuLTS
-Credential $creds
}
Terraform
Creating an availability set and virtual machines using Terraform is a bit different from Azure CLI and Azure PowerShell. With Terraform, you do not run individual commands to build the resource components. Instead, you define the resource properties and Terraform provisions the infrastructure for you.
This tutorial assumes you already have some Terraform knowledge including using resource providers and how to define resources. If you need an introduction to Terraform, check out Getting Started with Terraform on Windows: Install, Setup and Demo.
Prerequisites
To follow along in this tutorial, please be sure you have the following items in place:
- The latest version of the Terraform binary.
- Windows PowerShell v5.1 (installed by default on Windows 10) or PowerShell v7.0 or higher. This tutorial uses PowerShell v7.1.3.
Now that you have Terraform binary and PowerShell console ready, follow the steps below and start creating an availability set!
1. Log into your Azure environment as you did in the Azure CLI section using the az login
command.
2. Create a Terraform configuration file named main.tf. Open this file in your favorite code editor.
3. Next, in the main.tf configuration file, create an azurerm_availability_set
resource definition.
The resource definition includes the availability set name
(avset-db
), configures the platform_fault_domain_count
and platform_update_domain_count
properties to 3
each. Set the managed
property to true
to configure the availability set for managed disks.
The example below includes creating the resource group named avsetdemo-rg
in the location
westus2
. When creating the availability set, you reference where to place the availability group using dependencies. You see this in the resource_group_name
(azurerm_resource_group.rg.name
) and location
(azurerm_resource_group.rg.location
).
resource "azurerm_resource_group" "rg" {
name = "avsetdemo-rg"
location = "westus2"
}
resource "azurerm_availability_set" "avset-db" {
name = "avset-db"
resource_group_name = azurerm_resource_group.rg.name
location = azurerm_resource_group.rg.location
platform_fault_domain_count = 3
platform_update_domain_count = 3
managed = true
}
4. When you define the virtual machine resource, apply the availability_set_id
argument to specify the avset-db
availability set. The value references the Terraform resource using the resource type (azurerm_availability_set
), symbolic name (avset-db
), and property id
. Take a look at the example of a virtual machine argument below.
resource "azurerm_linux_virtual_machine" "vm" {
availability_set_id = azurerm_availability_set.avset-db.id
# Remaining properties …
}
You can find a sample Terraform configuration that demonstrates deploying availability sets and virtual machines located in the ATA GitHub repository.
Unlike the other methods in this tutorial, the configuration file from the ATA GitHub repository creates the virtual network and subnet. This configuration is necessary to use resource references and dependencies when creating the network interface and virtual machines.
5. Finally, deploy the Terraform configuration by switching back to your PowerShell console. Begin the deployment by initializing the required providers (terraform init
), creating a deployment plan (terraform plan -out deploy.tfplan
). Then apply the planned configuration (terraform apply deploy.tfplan
).
Once you review the deployed resources, perform a destroy operation (terraform destroy
) to remove the environment.
# Initialize the deployment
terraform init
# Create a deployment plan named deploy.tfplan
terraform plan -out deploy.tfplan
# Deploy the resources using the deploy.tfplan file
terraform apply deploy.tfplan
# Remove the resources
terraform destroy
Conclusion
In this tutorial, you learned about the benefits of Azure availability sets for your virtual machines in maximizing uptime and availability. You then created availability sets using three different methods: the Azure CLI, Azure PowerShell, and Terraform.
With this new knowledge and deployment skills, be sure to include availability sets into your next Azure virtual machine deployment!