Customize Virtual Machine Scale Sets

Virtual Machine Scale Sets (VMSS) provide a way to manage a group of identical VMs. This guide shows how to customize VMSS configurations, including extensions, custom script provisioning, and network settings.

1. Adding Custom Script Extensions

Use the Microsoft.Azure.Extensions.CustomScript extension to run scripts on each instance during provisioning.

{
  "type": "Microsoft.Compute/virtualMachineScaleSets",
  "apiVersion": "2024-04-01",
  "name": "myScaleSet",
  "location": "eastus",
  "properties": {
    "upgradePolicy": { "mode": "Automatic" },
    "virtualMachineProfile": {
      "extensionProfile": {
        "extensions": [
          {
            "name": "customScript",
            "properties": {
              "publisher": "Microsoft.Azure.Extensions",
              "type": "CustomScript",
              "typeHandlerVersion": "2.1",
              "autoUpgradeMinorVersion": true,
              "settings": {
                "fileUris": ["https://myaccount.blob.core.windows.net/scripts/install.sh"],
                "commandToExecute": "sh install.sh"
              }
            }
          }
        ]
      }
    }
  }
}

2. Configuring Custom Data (cloud‑init)

You can supply cloud‑init data to customize the OS at first boot.

#cloud-config
package_update: true
packages:
  - nginx
runcmd:
  - systemctl enable nginx
  - systemctl start nginx

3. Overriding Network Settings per Instance

Define multiple network configurations and assign them based on VM instance IDs.

{
  "properties": {
    "networkProfile": {
      "networkInterfaceConfigurations": [
        {
          "name": "nicConfig",
          "properties": {
            "primary": true,
            "ipConfigurations": [
              {
                "name": "ipConfig",
                "properties": {
                  "subnet": { "id": "/subscriptions/xxxx/resourceGroups/rg/providers/Microsoft.Network/virtualNetworks/vnet/subnets/subnet1" },
                  "primary": true,
                  "privateIPAddressVersion": "IPv4"
                }
              }
            ]
          }
        }
      ]
    }
  }
}

4. Using Custom Images

Reference a custom image captured from a VM.

{
  "virtualMachineProfile": {
    "storageProfile": {
      "imageReference": {
        "id": "/subscriptions/xxxx/resourceGroups/rg/providers/Microsoft.Compute/images/customImage"
      }
    }
  }
}

5. Advanced Scaling Rules

Combine CPU metrics with queue length to trigger scaling.

{
  "profiles": [
    {
      "name": "autoScale",
      "capacity": { "minimum": "2", "maximum": "10", "default": "3" },
      "rules": [
        {
          "metricTrigger": {
            "metricName": "Percentage CPU",
            "metricNamespace": "",
            "metricResourceUri": "/subscriptions/xxxx/resourceGroups/rg/providers/Microsoft.Compute/virtualMachineScaleSets/myScaleSet",
            "timeGrain": "PT1M",
            "statistic": "Average",
            "timeWindow": "PT5M",
            "timeAggregation": "Average",
            "operator": "GreaterThan",
            "threshold": 70
          },
          "scaleAction": {
            "direction": "Increase",
            "type": "ChangeCount",
            "value": "1",
            "cooldown": "PT5M"
          }
        },
        {
          "metricTrigger": {
            "metricName": "QueueLength",
            "metricNamespace": "Microsoft.Storage/storageAccounts/queueServices",
            "metricResourceUri": "/subscriptions/xxxx/resourceGroups/rg/providers/Microsoft.Storage/storageAccounts/mystorage/queues/myqueue",
            "timeGrain": "PT1M",
            "statistic": "Average",
            "timeWindow": "PT5M",
            "timeAggregation": "Average",
            "operator": "GreaterThan",
            "threshold": 100
          },
          "scaleAction": {
            "direction": "Increase",
            "type": "PercentChangeCount",
            "value": "20",
            "cooldown": "PT5M"
          }
        }
      ]
    }
  ]
}

Next Steps