Skip to main content
emnode
Site Reliability

Run scale sets as zone-redundant for fault tolerance

One capability across every Virtual Machine Scale Set in the estate: make sure the instances are spread across multiple availability zones, so a single instance failure or a whole-zone outage is absorbed automatically instead of taking the workload down.

14 min·10 sections·AZURE

Last reviewed

Zone-redundant scale sets: the basics

What does a single-zone scale set actually expose you to?

A Virtual Machine Scale Set is the unit Azure uses to run a fleet of identical VMs behind a load balancer and scale them up and down. The question that decides whether that fleet survives a bad day is where its instances physically sit. A scale set pinned to one availability zone runs every instance in the same group of datacentres. Add as many instances as you like: if that zone has a power, cooling or network event, the whole scale set goes with it, because there was never anywhere else for the work to run. A zone-redundant scale set instead spreads its instances across two or three availability zones, which are physically separate datacentre groups in the same region, so the loss of any one zone leaves the others serving.

Azure Advisor surfaces this as a reliability recommendation: protect a scale set from datacentre-level failures by deploying it across availability zones. The modern shape is a Flexible orchestration scale set with its 'zones' set to two or three zones, which Microsoft documents as the configuration that lifts the workload onto the 99.99% VM uptime SLA. The recommendation reads as a single line per scale set, but the underlying decision is the same one every time: is this fleet resilient to losing a datacentre, or is it one zone event away from an outage?

Most single-zone scale sets are not a deliberate choice. A set created from a quickstart that named one zone, a module that never passed a zones value, an older Uniform scale set that pre-dates the team's zone-aware defaults. The work is to find every scale set whose instances are not spread across zones, decide which genuinely need to be (almost all production ones), and rebuild or reconfigure them to run zone-redundant so a single zone outage no longer means downtime.

In this lesson you will learn how a Virtual Machine Scale Set expresses where its instances run, how to find every scale set in a subscription that is pinned to a single zone, and how to make them zone-redundant without dropping live traffic. You will see the exact Azure Advisor reliability recommendation behind it, the az CLI to inventory and remediate, and the Bicep that bakes zone redundancy into the template so the next deployment is resilient by default.

Fun fact

The zone that took the weekend with it

Availability zones exist because datacentres fail in physical, local ways: a cooling failure on a hot day, a power event, a flooded utility room. Azure has had region incidents where a single zone lost capacity for hours while the other zones in the same region kept serving normally. For workloads spread across zones, those incidents were a graceful capacity dip. For workloads pinned to the affected zone, they were a full outage that lasted as long as the recovery did. The instances were identical in both cases. The only difference was whether someone had set the scale set to run in more than one zone.

Finding single-zone scale sets across a subscription

Priya is the reliability lead at a scale-up whose checkout traffic has outgrown its original architecture. Azure Advisor is flagging several scale sets for availability-zone deployment, and a recent regional blip that briefly degraded one zone has made the topic urgent.

Rather than work the recommendations one at a time, Priya starts by listing which scale sets are pinned to a single zone and which are already spread, so the production fleets that must survive a zone outage can be separated from the low-stakes ones before anything is rebuilt.

List every scale set and how many availability zones it spans. A count of one (or none) is a scale set that a single zone outage can take down.

$ az vmss list --query "[].{name:name, rg:resourceGroup, zones:length(zones || [])}" -o table
Name Rg Zones
---------------- ---------------- -------
checkout-api-vmss prod-rg 1
web-frontend-vmss prod-rg 3
batch-worker-vmss batch-rg 0
# checkout-api runs revenue traffic in ONE zone. Make it zone-redundant first.

A revenue-bearing scale set pinned to a single zone is the highest-value target in this group. A zone count of one or zero means a single datacentre failure can take the whole fleet down.

How a scale set decides which zones its instances run indeep dive

Zone placement is set on the scale set itself, through its 'zones' property: an array of zone numbers such as ['1'] for a single zone or ['1','2','3'] for three. A scale set with one zone, or with no zones at all, is regional and can land every instance in the same datacentre group. A scale set with two or three zones spreads its instances across them, and Azure keeps them zone-balanced, meaning each chosen zone holds the same number of instances plus or minus one. The number of instances does not change the exposure: ten instances in one zone still all share that zone's fate.

The modern, recommended shape is a Flexible orchestration scale set created with its zones set across the region's availability zones. Within each zone, instances are also spread across fault domains, which are independent racks of power and network, so the set tolerates both a single-instance failure and a whole-zone failure. Microsoft documents that spreading two or more VM instances across two or more availability zones is what qualifies a workload for the 99.99% VM uptime SLA; a single-instance or single-zone deployment sits below that.

The 'zones' property is fixed at create time for a scale set, which is the catch that makes this a rebuild rather than a flip of a switch. You cannot move a running single-zone scale set into multiple zones by editing one field; you stand up a zone-redundant replacement and shift traffic to it behind the load balancer. The strongest position pairs the rebuilt scale sets with a template and policy default, so that zone redundancy is baked into how new scale sets are created rather than something each one has to be reconfigured into after the fact.

What is the impact of leaving scale sets single-zone?

The direct impact is downtime concentration. Every instance in a single-zone scale set shares one datacentre group's fate, so a zone power, cooling or network event takes the entire fleet down at once, no matter how many instances it holds. Autoscaling does not save you, because there is no healthy zone for it to scale into. Recovery is gated on Azure restoring that zone, which can take hours, and the workload is hard-down for the duration.

The second-order impact is correlated failure. If several workloads are all pinned to the same zone, a single zone incident takes them all down together, turning what should have been a contained dip into an estate-wide outage. Spreading scale sets across zones breaks that correlation: the loss of one zone becomes a reduction in capacity that the remaining zones and autoscaling absorb, not a full stop.

On the resilience side, every serious availability target, an internal SLA to your own customers, a 99.99% uptime commitment, a regulator's operational-resilience expectation, assumes that a single datacentre failure is survivable. A production scale set running in one zone quietly breaks that assumption. Zone-redundant scale sets are the cheapest and most direct way to make a single zone outage a non-event, and to be able to show that the architecture, not luck, is what keeps the workload up.

How do you make scale sets zone-redundant safely?

Work the capability as one loop rather than chasing individual recommendations. The order matters: identify which scale sets actually carry production load before you rebuild anything, so you spend the effort where an outage would hurt and you never drop live traffic during the migration.

1. Inventory every scale set by zone span

List each scale set and how many availability zones it spans. A count of one, or zero for a regional set, is a scale set a single zone outage can take down. Treat this inventory as the source of truth, not the Advisor recommendation count, and note the orchestration mode while you are there, since older Uniform sets are the usual candidates for rebuilding as Flexible.

2. Order by the cost of the outage, not the count

Map each single-zone scale set to the workload behind it and what stops when it stops. A revenue-bearing API or a customer-facing frontend is a rebuild to do first; an internal batch or reporting worker where an hour of downtime is tolerable can wait. Prioritise by expected downtime cost so the highest-stakes fleets become zone-redundant first.

3. Rebuild zone-redundant and shift traffic

Because the zones property is fixed at create time, you stand up a Flexible scale set spread across the region's zones, attach it to the same load balancer backend, drain and shift traffic to it, then retire the single-zone set. Make sure the load balancer frontend and any public IP are themselves zone-redundant, otherwise the front door becomes the new single point of failure.

4. Make zone redundancy the default in templates

Bake the zones across availability zones into your Bicep or module so every new scale set is zone-redundant by default, and add an Azure Policy audit so a single-zone production set is flagged the moment it appears. That turns zone redundancy from something each scale set has to be reconfigured into, into the shape new ones are born in.

// Zone-redundant Virtual Machine Scale Set (Flexible orchestration)
// spread across three availability zones, so a single zone outage
// is absorbed by the remaining zones instead of taking the fleet down.
param location string = resourceGroup().location
param vmssName string = 'checkout-api-vmss'
param adminUsername string

resource vmss 'Microsoft.Compute/virtualMachineScaleSets@2024-07-01' = {
  name: vmssName
  location: location
  // Spreading instances across these zones is what lifts the
  // workload onto the 99.99% VM uptime SLA.
  zones: [
    '1'
    '2'
    '3'
  ]
  sku: {
    name: 'Standard_D2s_v5'
    capacity: 6
  }
  properties: {
    orchestrationMode: 'Flexible'
    // 1 fault domain per zone is the documented default for a
    // zone-spanning Flexible set; instances still spread across
    // fault domains on a best-effort basis within each zone.
    platformFaultDomainCount: 1
    // ... virtualMachineProfile (image, NIC, load balancer backend) ...
  }
}

# Equivalent one-off rebuild with the az CLI:
# az vmss create \
#   --resource-group prod-rg \
#   --name checkout-api-vmss \
#   --orchestration-mode Flexible \
#   --zones 1 2 3 \
#   --platform-fault-domain-count 1 \
#   --instance-count 6 \
#   --image Ubuntu2204 \
#   --admin-username azureuser \
#   --generate-ssh-keys

Quick quiz

Question 1 of 5

Azure Advisor flags several scale sets to deploy across availability zones. What is the most efficient way to think about them?

You can now treat zone redundancy as one capability rather than a scatter of reliability recommendations: inventory every scale set by how many zones it spans, order the single-zone ones by the cost of their outage, rebuild the revenue-bearing fleets as Flexible scale sets across multiple zones behind a zone-redundant front door, and bake zone redundancy into your templates so new scale sets are resilient by default. A single zone outage becomes a graceful capacity dip instead of a full stop.

Back to the library