VMSS Zonal Expansion: Add Availability Zones Without Rebuilding

Azure's VMSS zonal expansion lets you add availability zones to a live scale set instead of rebuilding it. Here's how it works, the validation gotchas, and what it doesn't fix.

For years, if you built a Virtual Machine Scale Set (VMSS) as regional instead of zone-redundant, that choice was permanent. Zone assignment got locked in at creation. If you changed your mind six months later, your only option was deleting the scale set and rebuilding it zonal from scratch. New instances, a cutover window, and hoping nothing upstream cared about the resource ID. Azure closed that gap in November 2024 with zonal expansion: you can now add availability zones to an existing scale set in place.

What already worked

Spreading a scale set across zones isn’t new. You could set "zones": ["1","2","3"] at creation time years before this, and the scale set would spread instances across all three:

az vmss create \
    --resource-group myResourceGroup \
    --name myScaleSet \
    --image Ubuntu2204 \
    --zones 1 2 3

That gets you the 99.99% SLA instead of the 99.95% regional SLA. Real difference: 99.95% allows about 4 hours 22 minutes of downtime a year. 99.99% allows about 52 minutes. If you called that out at design time, you were fine.

The problem was every scale set that shipped regional, on purpose or by default, before someone thought to add zones. Small teams standing up their first VMSS often don’t set zones at all. Nobody revisits it until an outage makes the SLA gap visible, and by then the scale set is running production workloads you don’t want to blow away and recreate.

What’s actually new

You can now update the zones property on a live scale set without deleting it:

az vmss update --set zones=["1","2","3"] -n myScaleSet -g myResourceGroup

This requires API version 2023-03-01 or newer. The update itself doesn’t touch your running instances. It just changes where new instances land.

The part that trips people up

Changing the zones property doesn’t move anything. Your existing regional instances stay exactly where they are, still unpinned to a zone. To actually get zone-redundant, you have to scale out (new instances get created zonal, spread across the zones you added) and then scale in (Azure prioritizes removing the original regional instances first, then follows your normal scale-in policy).

So this is a three-step process, not a flag flip:

  1. Update the zones parameter.
  2. Scale out to create zonal instances.
  3. Scale in to shed the regional ones.

No data from the original instances gets migrated for you. If your workload holds local state, you’re responsible for getting that state onto the new zonal instances before you scale the old ones away. This is fine for stateless web and app tiers. It’s a real gap for anything else.

Before you touch the zones parameter

Azure validates a few things and will reject the update if they’re not in place:

  • Quota. You need enough VM quota in the region to run instances across all the zones you’re adding, not just the zone count you have today.
  • SKU and disk availability per zone. Not every VM size or disk type is available in every zone in every region. Check with the Resource SKUs API before you commit, not after the update fails mid-rollout.
  • Fault domain count. platformFaultDomainCount must be 1 or 5. Fixed spreading at 2 or 3, common on older regional scale sets, isn’t supported once you go zonal.
  • No capacity reservations during the transition. You can add a capacity reservation group back once the scale set is fully zonal with no regional instances left.
  • No Azure Dedicated Host. Not supported for this path.
  • No Service Fabric or AKS-managed scale sets. This is for scale sets you manage directly.

It’s a one-way door

You can add zones. You can’t remove them, and you can’t go back to regional once the scale set has any zonal instances. If you’re not sure you want zone redundancy yet, don’t flip this switch to “see what happens.” Decide first, then expand.

Where this actually helps

Every VMSS that went regional by default years ago, and every team that didn’t have region-zone support when they first deployed, now has an in-place path to 99.99% instead of a rebuild project. For stateless tiers behind a load balancer, that’s a low-friction change: update the property, scale out, scale in, done.

For anything stateful, the choreography is still on you. Zonal expansion changes where new instances land. It doesn’t replicate your data, doesn’t coordinate your application-level failover, and doesn’t help at all if you’re running Service Fabric or an AKS node pool through the scale set API. Know which bucket your workload is in before you plan the change as a quick win.

Subscribe for more of these.

#azure#virtual-machine-scale-sets#availability-zones#high-availability#azure-architecture