Modify a virtual machine scale set

Throughout the lifecycle of your applications, you may need to modify or update your virtual machine scale set. These updates may include how to update the configuration of the scale set, or change the application configuration. This article describes how to modify an existing scale set with the REST APIs, Azure PowerShell, or Azure CLI 2.0.

Fundamental concepts

The scale set model

A scale set has a "scale set model" that captures the desired state of the scale set as a whole. To query the model for a scale set, you can use the

  • REST API with compute/virtualmachinescalesets/get as follows:

    GET https://management.azure.com/subscriptions/{subscriptionId}/resourceGroups/myResourceGroup/providers/Microsoft.Compute/virtualMachineScaleSets/myScaleSet?api-version={apiVersion}
    
  • Azure PowerShell with Get-AzureRmVmss:

    Get-AzureRmVmss -ResourceGroupName "myResourceGroup" -VMScaleSetName "myScaleSet"
    
  • Azure CLI 2.0 with az vmss show:

    az vmss show --resource-group myResourceGroup --name myScaleSet
    
  • You can also use resources.azure.com or the language-specific Azure SDKs.

The exact presentation of the output depends on the options you provide to the command. The following example shows condensed sample output from the Azure CLI 2.0:

az vmss show --resource-group myResourceGroup --name myScaleSet
{
  "location": "westus",
  "overprovision": true,
  "plan": null,
  "singlePlacementGroup": true,
  "sku": {
    "additionalProperties": {},
    "capacity": 1,
    "name": "Standard_D2_v2",
    "tier": "Standard"
  },
}

These properties apply to the scale set as a whole.

The scale set instance view

A scale set also has a "scale set instance view" that captures the current runtime state of the scale set as a whole. To query the instance view for a scale set, you can use:

  • REST API with compute/virtualmachinescalesets/getinstanceview as follows:

    GET https://management.azure.com/subscriptions/{subscriptionId}/resourceGroups/myResourceGroup/providers/Microsoft.Compute/virtualMachineScaleSets/myScaleSet/instanceView?api-version={apiVersion}
    
  • Azure PowerShell with Get-AzureRmVmss:

    Get-AzureRmVmss -ResourceGroupName "myResourceGroup" -VMScaleSetName "myScaleSet" -InstanceView
    
  • Azure CLI 2.0 with az vmss get-instance-view:

    az vmss get-instance-view --resource-group myResourceGroup --name myScaleSet
    
  • You can also use resources.azure.com or the language-specific Azure SDKs

The exact presentation of the output depends on the options you provide to the command. The following example shows condensed sample output from the Azure CLI 2.0:

$ az vmss get-instance-view --resource-group myResourceGroup --name myScaleSet
{
  "statuses": [
    {
      "additionalProperties": {},
      "code": "ProvisioningState/succeeded",
      "displayStatus": "Provisioning succeeded",
      "level": "Info",
      "message": null,
      "time": "{time}"
    }
  ],
  "virtualMachine": {
    "additionalProperties": {},
    "statusesSummary": [
      {
        "additionalProperties": {},
        "code": "ProvisioningState/succeeded",
        "count": 1
      }
    ]
  }
}

These properties provide a summary of the current runtime state of the VMs in the scale set, such as the status of extensions applied to the scale set.

The scale set VM model view

Similar to how a scale set has a model view, each VM in the scale set has its own model view. To query the model view for a scale set, you can use:

  • REST API with compute/virtualmachinescalesetvms/get as follows:

    GET https://management.azure.com/subscriptions/{subscriptionId}/resourceGroups/myResourceGroup/providers/Microsoft.Compute/virtualMachineScaleSets/myScaleSet/virtualmachines/instanceId?api-version={apiVersion}
    
  • Azure PowerShell with Get-AzureRmVmssVm:

    Get-AzureRmVmssVm -ResourceGroupName "myResourceGroup" -VMScaleSetName "myScaleSet" -InstanceId instanceId
    
  • Azure CLI 2.0 with az vmss show:

    az vmss show --resource-group myResourceGroup --name myScaleSet --instance-id instanceId
    
  • You can also use resources.azure.com or the Azure SDKs.

The exact presentation of the output depends on the options you provide to the command. The following example shows condensed sample output from the Azure CLI 2.0:

$ az vmss show --resource-group myResourceGroup --name myScaleSet
{
  "location": "westus",
  "name": "{name}",
  "sku": {
    "name": "Standard_D2_v2",
    "tier": "Standard"
  },
}

These properties describe the configuration of the VM itself, not the configuration of the scale set as a whole. For example, the scale set model has overprovision as a property, while the model for a VM in a scale set does not. This difference is because overprovisioning is a property for the scale set as a whole, not individual VMs in the scale set (for more information about overprovisioning, see Design considerations for scale sets).

The scale set VM instance view

Similar to how a scale set has an instance view, each VM in the scale set has its own instance view. To query the instance view for a scale set, you can use:

  • REST API with compute/virtualmachinescalesetvms/getinstanceview as follows:

    GET https://management.azure.com/subscriptions/{subscriptionId}/resourceGroups/myResourceGroup/providers/Microsoft.Compute/virtualMachineScaleSets/myScaleSet/virtualmachines/instanceId/instanceView?api-version={apiVersion}
    
  • Azure PowerShell with Get-AzureRmVmssVm:

    Get-AzureRmVmssVm -ResourceGroupName "myResourceGroup" -VMScaleSetName "myScaleSet" -InstanceId instanceId -InstanceView
    
  • Azure CLI 2.0 with az vmss get-instance-view

    az vmss get-instance-view --resource-group myResourceGroup --name myScaleSet --instance-id instanceId
    
  • You can also use resources.azure.com or the Azure SDKs

The exact presentation of the output depends on the options you provide to the command. The following example shows condensed sample output from the Azure CLI 2.0:

$ az vmss get-instance-view --resource-group myResourceGroup --name myScaleSet --instance-id instanceId
{
  "additionalProperties": {
    "osName": "ubuntu",
    "osVersion": "16.04"
  },
  "disks": [
    {
      "name": "{name}",
      "statuses": [
        {
          "additionalProperties": {},
          "code": "ProvisioningState/succeeded",
          "displayStatus": "Provisioning succeeded",
          "time": "{time}"
        }
      ]
    }
  ],
  "statuses": [
    {
      "additionalProperties": {},
      "code": "ProvisioningState/succeeded",
      "displayStatus": "Provisioning succeeded",
      "time": "{time}"
    },
    {
      "additionalProperties": {},
      "code": "PowerState/running",
      "displayStatus": "VM running"
    }
  ],
  "vmAgent": {
    "statuses": [
      {
        "additionalProperties": {},
        "code": "ProvisioningState/succeeded",
        "displayStatus": "Ready",
        "level": "Info",
        "message": "Guest Agent is running",
        "time": "{time}"
      }
    ],
    "vmAgentVersion": "{version}"
  },
}

These properties describe the current runtime state of the VM itself, that includes any extensions applied to the scale set.

How to update global scale set properties

To update a global scale set property, you must update the property in the scale set model. You can do this update via:

  • REST API with compute/virtualmachinescalesets/createorupdate as follows:

    PUT https://management.azure.com/subscriptions/{subscriptionId}/resourceGroups/myResourceGroup/providers/Microsoft.Compute/virtualMachineScaleSets/myScaleSet?api-version={apiVersion}
    
  • You can deploy a Resource Manager template with the properties from the REST API to update global scale set properties.

  • Azure PowerShell with Update-AzureRmVmss:

    Update-AzureRmVmss -ResourceGroupName "myResourceGroup" -VMScaleSetName "myScaleSet" -VirtualMachineScaleSet {scaleSetConfigPowershellObject}
    
  • Azure CLI 2.0 with az vmss update:

    • To modify a property:

      az vmss update --set {propertyPath}={value}
      
    • To add an object to a list property in a scale set:

      az vmss update --add {propertyPath} {JSONObjectToAdd}
      
    • To remove an object from a list property in a scale set:

      az vmss update --remove {propertyPath} {indexToRemove}
      
    • If you previously deployed the scale set with the az vmss create command, you can run the az vmss create command again to update the scale set. Make sure that all properties in the az vmss create command are the same as before, except for the properties that you wish to modify.

  • You can also use resources.azure.com or the Azure SDKs.

Once the scale set model is updated, the new configuration applies to any new VMs created in the scale set. However, the models for the existing VMs in the scale set must still be brought up-to-date with the latest overall scale set model. In the model for each VM is a boolean property called latestModelApplied that indicates whether or not the VM is up-to-date with the latest overall scale set model (true means the VM is up-to-date with the latest model).

How to bring VMs up-to-date with the latest scale set model

Scale sets have an "upgrade policy" that determine how VMs are brought up-to-date with the latest scale set model. The three modes for the upgrade policy are:

  • Automatic - In this mode, the scale set makes no guarantees about the order of VMs being brought down. The scale set may take down all VMs at the same time.
  • Rolling - In this mode, the scale set rolls out the update in batches with an optional pause time between batches.
  • Manual - In this mode, when you update the scale set model, nothing happens to existing VMs.

To update existing VMs, you must do a "manual upgrade" of each existing VM. You can do this manual upgrade with:

  • REST API with compute/virtualmachinescalesets/updateinstances as follows:

    POST https://management.azure.com/subscriptions/{subscriptionId}/resourceGroups/myResourceGroup/providers/Microsoft.Compute/virtualMachineScaleSets/myScaleSet/manualupgrade?api-version={apiVersion}
    
  • Azure PowerShell with Update-AzureRmVmssInstance:

    Update-AzureRmVmssInstance -ResourceGroupName "myResourceGroup" -VMScaleSetName "myScaleSet" -InstanceId instanceId
    
  • Azure CLI 2.0 with az vmss update-instances

    az vmss update-instances --resource-group myResourceGroup --name myScaleSet --instance-ids {instanceIds}
    
  • You can also use the language-specific Azure SDKs.

Note

Service Fabric clusters can only use Automatic mode, but the update is handled differently. For more information, see Service Fabric application upgrades.

There is one type of modification to global scale set properties that does not follow the upgrade policy. Changes to the scale set OS Profile (such as admin username and password) can only be changed in API version 2017-12-01 or later. These changes only apply to VMs created after the change in the scale set model. To bring existing VMs up-to-date, you must do a "reimage" of each existing VM. You can do this reimage via:

  • REST API with compute/virtualmachinescalesets/reimage as follows:

    POST https://management.azure.com/subscriptions/{subscriptionId}/resourceGroups/myResourceGroup/providers/Microsoft.Compute/virtualMachineScaleSets/myScaleSet/reimage?api-version={apiVersion}
    
  • Azure PowerShell with Set-AzureRmVmssVm:

    Set-AzureRmVmssVM -ResourceGroupName "myResourceGroup" -VMScaleSetName "myScaleSet" -InstanceId instanceId -Reimage
    
  • Azure CLI 2.0 with az vmss reimage:

    az vmss reimage --resource-group myResourceGroup --name myScaleSet --instance-id instanceId
    
  • You can also use the language-specific Azure SDKs.

Properties with restrictions on modification

Create-time properties

Some properties can only be set when you create the scale set. These properties include:

  • Availability Zones
  • Image reference publisher
  • Image reference offer
  • Managed OS disk storage account type

Properties that can only be changed based on the current value

Some properties may be changed, with exceptions depending on the current value. These properties include:

  • singlePlacementGroup - If singlePlacementGroup is true, it may be modified to false. However, if singlePlacementGroup is false, it may not be modified to true.
  • subnet - The subnet of a scale set may be modified as long as the original subnet and the new subnet are in the same virtual network.

Properties that require deallocation to change

Some properties may only be changed to certain values if the VMs in the scale set are deallocated. These properties include:

  • SKU name- If the new VM SKU is not supported on the hardware the scale set is currently on, you need to deallocate the VMs in the scale set before you modify the SKU name. For more information, see how to resize an Azure VM.

VM-specific updates

Certain modifications may be applied to specific VMs instead of the global scale set properties. Currently, the only VM-specific update that is supported is to attach/detach data disks to/from VMs in the scale set. This feature is in preview. For more information, see the preview documentation.

Scenarios

Application updates

If an application is deployed to a scale set through extensions, an update to the extension configuration causes the application to update in accordance with the upgrade policy. For instance, if you have a new version of a script to run in a Custom Script Extension, you could update the fileUris property to point to the new script. In some cases, you may wish to force an update even though the extension configuration is unchanged (for example, you updated the script without a change to the URI of the script). In these cases, you can modify the forceUpdateTag to force an update. The Azure platform does not interpret this property. If you change the value, there is no effect on how the extension runs. A change simply forces the extension to rerun. For more information on the forceUpdateTag, see the REST API documentation for extensions. Note that the forceUpdateTag can be used with all extensions, not just the custom script extension.

It's also common for applications to be deployed through a custom image. This scenario is covered in the following section.

OS Updates

If you use Azure platform images, you can update the image by modifying the imageReference (more information, see the REST API documentation).

Note

With platform images, it is common to specify "latest" for the image reference version. When you create, scale out, and reimage, VMs are created with the latest available version. However, it does not mean that the OS image is automatically updated over time as new image versions are released. A separate feature is currently in preview that provides automatic OS upgrades. For more information, see the Automatic OS Upgrades documentation.

If you use custom images, you can update the image by updating the imageReference ID (more information, see the REST API documentation).

Examples

Update the OS image for your scale set

You may have a scale set that runs an old version of Ubuntu LTS 16.04. You want to update to a newer version of Ubuntu LTS 16.04, such as version 16.04.201801090. The image reference version property is not part of a list, so you can directly modify these properties with one of the following commands:

  • Azure PowerShell with Update-AzureRmVmss as follows:

    Update-AzureRmVmss -ResourceGroupName "myResourceGroup" -VMScaleSetName "myScaleSet" -ImageReferenceVersion 16.04.201801090
    
  • Azure CLI 2.0 with az vmss update:

    az vmss update --resource-group myResourceGroup --name myScaleSet --set virtualMachineProfile.storageProfile.imageReference.version=16.04.201801090
    

Update the load balancer for your scale set

Let's say you have a scale set with an Azure Load Balancer, and you want to replace the Azure Load Balancer with an Azure Application Gateway. The load balancer and Application Gateway properties for a scale set are part of a list, so you can use the commands to remove or add list elements instead of modifying the properties directly:

  • Azure Powershell:

    # Get the current model of the scale set and store it in a local PowerShell object named $vmss
    $vmss=Get-AzureRmVmss -ResourceGroupName "myResourceGroup" -Name "myScaleSet"
    
    # Create a local PowerShell object for the new desired IP configuration, which includes the referencerence to the application gateway
    $ipconf = New-AzureRmVmssIPConfig "myNic" -ApplicationGatewayBackendAddressPoolsId /subscriptions/{subscriptionId}/resourceGroups/myResourceGroup/providers/Microsoft.Network/applicationGateways/{applicationGatewayName}/backendAddressPools/{applicationGatewayBackendAddressPoolName} -SubnetId $vmss.VirtualMachineProfile.NetworkProfile.NetworkInterfaceConfigurations[0].IpConfigurations[0].Subnet.Id –Name $vmss.VirtualMachineProfile.NetworkProfile.NetworkInterfaceConfigurations[0].IpConfigurations[0].Name
    
    # Replace the existing IP configuration in the local PowerShell object (which contains the references to the current Azure Load Balancer) with the new IP configuration
    $vmss.VirtualMachineProfile.NetworkProfile.NetworkInterfaceConfigurations[0].IpConfigurations[0] = $ipconf
    
    # Update the model of the scale set with the new configuration in the local PowerShell object
    Update-AzureRmVmss -ResourceGroupName "myResourceGroup" -Name "myScaleSet" -virtualMachineScaleSet $vmss
    
  • Azure CLI 2.0:

    # Remove the load balancer backend pool from the scale set model
    az vmss update --resource-group myResourceGroup --name myScaleSet --remove virtualMachineProfile.networkProfile.networkInterfaceConfigurations[0].ipConfigurations[0].loadBalancerBackendAddressPools 0
    
    # Remove the load balancer backend pool from the scale set model; only necessary if you have NAT pools configured on the scale set
    az vmss update --resource-group myResourceGroup --name myScaleSet --remove virtualMachineProfile.networkProfile.networkInterfaceConfigurations[0].ipConfigurations[0].loadBalancerInboundNatPools 0
    
    # Add the application gateway backend pool to the scale set model
    az vmss update --resource-group myResourceGroup --name myScaleSet --add virtualMachineProfile.networkProfile.networkInterfaceConfigurations[0].ipConfigurations[0].ApplicationGatewayBackendAddressPools '{"id": "/subscriptions/{subscriptionId}/resourceGroups/myResourceGroup/providers/Microsoft.Network/applicationGateways/{applicationGatewayName}/backendAddressPools/{applicationGatewayBackendPoolName}"}'
    

Note

These commands assume there is only one IP configuration and load balancer on the scale set. If there are multiple, you may need to use a list index other than 0.

Next steps

You can also perform common management tasks on scale sets with the Azure CLI 2.0 or Azure PowerShell.