It is easy to create an Azure VM scale set in the Azure portal, and there is an option to create it with basic CPU based autoscale settings. But suppose you created a scale set without any autoscale settings and now you want to add some autoscale rules. How do you do that?
This article shows 3 different ways to add autoscale settings to an existing scale set:
- Add autoscale rules using Azure PowerShell
- Create an Azure template to add scaling rules
- Call the REST API or a managed SDK
In these examples, the scale metric used is “Percentage CPU”. You can find a list of valid metrics to scale on here: https://azure.microsoft.com/en-us/documentation/articles/monitoring-supported-metrics/ under the heading Microsoft.Compute/virtualMachineScaleSets.
1. Add autoscale rules using PowerShell
There are three main Azure PowerShell commands required to set up autoscale. First create some rules with New-AzureRmAutoscaleRule, then create a profile with New-AzureRmAutoscaleProfile, and finally add a setting with Add-AzureRmAutoscaleSetting. There are more commands available to do things like set up notification addresses and webhooks but the script below shows a basic setup to scale horizontally based on CPU usage. Scaling out when average CPU is greater than 60% and scaling in when average CPU is less than 30%:
$subid = "yoursubscriptionid" $rgname = "yourresourcegroup" $vmssname = "yourscalesetname" $location = "yourlocation" # e.g. southcentralus $rule1 = New-AzureRmAutoscaleRule -MetricName "Percentage CPU" -MetricResourceId /subscriptions/$subid/resourceGroups/$rgname/providers/Microsoft.Compute/virtualMachineScaleSets/$vmssname -Operator GreaterThan -MetricStatistic Average -Threshold 60 -TimeGrain 00:01:00 -TimeWindow 00:05:00 -ScaleActionCooldown 00:05:00 -ScaleActionDirection Increase -ScaleActionValue 1 $rule2 = New-AzureRmAutoscaleRule -MetricName "Percentage CPU" -MetricResourceId /subscriptions/$subid/resourceGroups/$rgname/providers/Microsoft.Compute/virtualMachineScaleSets/$vmssname -Operator LessThan -MetricStatistic Average -Threshold 30 -TimeGrain 00:01:00 -TimeWindow 00:05:00 -ScaleActionCooldown 00:05:00 -ScaleActionDirection Decrease -ScaleActionValue 1 $profile1 = New-AzureRmAutoscaleProfile -DefaultCapacity 2 -MaximumCapacity 10 -MinimumCapacity 2 -Rules $rule1,$rule2 -Name "autoprofile1" Add-AzureRmAutoscaleSetting -Location $location -Name "autosetting1" -ResourceGroup $rgname -TargetResourceId /subscriptions/$subid/resourceGroups/$rgname/providers/Microsoft.Compute/virtualMachineScaleSets/$vmssname -AutoscaleProfiles $profile1
After running this script you can look at the VM scale set properties in the Azure portal and it will show that Autoscale is set to On. Autoscale will start kicking in, and if your scale set isn’t doing any work your VMs will start getting deleted based on the rules above.
There are a couple of important things to point out about this script.
Firstly the MetricName “Percentage CPU”. This is a host metric name. I.e. the autoscale service is getting the information from the hypervisor host rather than from any agent running in the VM. This is recommended because the host metric pipeline (aka the MDM pipeline) is faster and more reliable than the older method of getting autoscale metrics based on running a diagnostic agent inside the VM. See Autoscaling VM scale sets with host metrics for more information.
Secondly make sure you’re using the latest version of Azure PowerShell, which at the time of writing is 3.6.0. Check here: https://github.com/Azure/azure-powershell/releases/ – various parameters get added or deprecated as versions progress. If you get errors or warnings when running scripts a good initial troubleshooting step is to upgrade to the latest Azure PowerShell.
2. Create an Azure template to add scaling rules
An alternative way of adding autoscale settings to a scale set is by deploying a specialized template. Look at an Azure Resource Manager template like this one: https://github.com/Azure/azure-quickstart-templates/blob/master/201-vmss-bottle-autoscale/azuredeploy.json – it’s used to create a VM scale set, install a Python Bottle webserver on each VM, and autoscale based on CPU usage. You can isolate the autoscale component and deploy it as its own template if you wish. I.e. the part that starts with:
The important values in the autoscaleSettings which reference back to the scale set are: “targetResourceUri”, and “metricResourceUri”. Here’s an example template which isolates the autoscale settings and can be deployed against an existing scale set: https://github.com/gbowerman/azure-myriad/tree/master/autoscale – this template could be further improved by parameterizing the autoscale metric names and thresholds.
3. Call the REST API or managed SDK directly
When you add autoscale settings using PowerShell, behind the scenes it is calling the Azure REST API. You can see the calls it makes by passing the –debug parameter. Here is an example of a Python program which adds autoscale settings using the REST API: https://github.com/gbowerman/vmsstools/blob/master/cpuload/addautoscalerules.py
It uses the azurerm library which is basically a set of REST wrappers. Note that in order to use this library you need a Service Principal (described in steps 1-4 here: https://msftstack.wordpress.com/2016/01/03/how-to-call-the-azure-resource-manager-rest-api-from-c/ ).
All the official Azure SDKs (Python, Java etc.) have function calls to create autoscale rules and settings.
4. What about the Azure portal?
Ideally you should be able to edit autoscale settings for an existing scale set directly in the portal. That’s on the portal roadmap, but not in place yet (at the time of writing).