Minimum Viable Templates: Put a VM in an Availability Zone

This post is part of a series of posts showing how to create a “minimum viable ARM template” and how to modify it to suit various scenarios. To see the full list of posts in this series, see this page: https://negatblog.wordpress.com/minimum-viable-arm-templates/.

Availability Zones allow us to spread our resources across different physical locations within a region, enabling high availability while still keeping resources within the same region (for purposes of keeping latency low, etc.). Let’s see how to modify our “minimum viable VM” template to put the VM in an availability zone. We begin on branch “minimum-viable-vm” (https://github.com/gatneil/MinimumViableArmTemplate/blob/minimum-viable-vm/azuredeploy.json) and end on branch “vm-in-a-zone” (https://github.com/gatneil/MinimumViableArmTemplate/blob/vm-in-a-zone/azuredeploy.json). The diff is below.

In order to place a resource in an availability zone, we must specify the “zones” list as below. Some resources (such as Virtual Machine Scale Sets) can accept multiple zones, but virtual machines can only accept one. Even though a VM can only accept one zone, the “zones” list is still a list. The list is a list of numbers, usually 1 through 3. Each represents a different zone, so place resources that should be near each other in the same zone, and place resources that should be far from each other (but still within the same region) in different zones. If a VM in a zone has a public IP address (as is the case in our template), the public IP address must be in the same zone as the VM (which is why we specify “zones”: [1] for the public IP address as well as the VM). Note that only certain resources support zones, and only in certain regions. For more details on availability zones and what resources/regions support them, see this document: https://docs.microsoft.com/azure/availability-zones/az-overview:

...
     {
       "type": "Microsoft.Network/publicIpAddresses",
       "apiVersion": "2020-06-01",
       "name": "myPip",

-      "location": "[resourceGroup().location]"
+      "location": "[resourceGroup().location]",
+      "zones": [
+        1
+      ]

     },

...

     {
       "type": "Microsoft.Compute/virtualMachines",
       "apiVersion": "2020-06-01",
       "name": "myVM",
       "location": "[resourceGroup().location]",
       "dependsOn": [
         "[resourceId('Microsoft.Network/networkInterfaces', 'myNic')]"
       ],

+      "zones": [
+        1
+      ],

       "properties": {
         "hardwareProfile": {
           "vmSize": "Standard_D2_v4"
         },
         "storageProfile": {
           "imageReference": {
             "publisher": "Canonical",
             "offer": "UbuntuServer",
             "sku": "18.04-LTS",
             "version": "latest"
           }
         },
         "networkProfile": {
           "networkInterfaces": [
             {
               "id": "[resourceId('Microsoft.Network/networkInterfaces', 'myNic')]"
             }
           ]
         },
         "osProfile": {
           "computerName": "myVM",
           "adminUsername": "[parameters('adminUsername')]",
           "adminPassword": "[parameters('adminPassword')]"
         }
       }
     }
...

Leave a comment