Microsoft Azure offers an interface that will allow you to build a default autoscale, a load balancer, and lots of other resources. But if you need customization, the interface isn’t enough—The creation of a JSON template is required.
In my case, I needed to customize an autoscale with these requirements:
- Create a load balancer that works with HTTPS.
- Use my VHD to launch new VMs.
- Add metrics of memory utilization to scale the VMs. By default, the autoscale has only CPU metrics.
Creating the VHD
The first thing needed is to generate the VHD from the VM that we want to use as the base to autoscale. In this example, I used a Linux VM with Ubuntu Server, but the OS is not important just to create VHD. To generate the VHD, you can follow the instructions in this post: Capture a Linux virtual machine running on Azure.
Theses steps will generate a JSON that contains the path of your VHD. Find it inside to “storageProfile” > “image” > “uri”.
"storageProfile": { "osDisk": { "osType": "Linux", "name": "vhd-osDisk.10aaf77a-601c-48f3-ac31-c181b63676c9.vhd", "createOption": "FromImage", "image": { "uri": "https://storageaccount.blob.core.windows.net/system/Microsoft.Compute/Images/vhds/vhd-osDisk.10aaf77a.vhd" }, "vhd": { "uri": "https://storageaccount.blob.core.windows.net/vmcontainer440e0fac/osDisk.440e0fac.vhd" }, "caching": "ReadWrite" } }
Creating the JSON template
There are amazing, helpful templates available in Azure Quickstart Templates. To build my template, I looked into every VMSS (Virtual Machine Scale Set) template and configured it to work as I wanted. That was the most boring part…
This is the final version of the template. Now let’s see how to customize it.
Parameters
The template has some parameters that will be asked in the moment of deploy:
- vmSku: Size of VMs used in the autoscale. I chose Standard_F1s, but there are many other options.
- vmssName: Name of VMSS resource—This needs to be short (about 6 characters) because it will be used as a prefix in other resources.
- instanceCount: Amount of VMs used in autoscale. A good option is to use 15 as the maximum.
- adminUsername: This needs to be the same user that you had in the original VM used to generate the VHD.
- adminPassword: Same here. Use the exact password from the original VM.
1. Load Balancer
To enable HTTP and HTTPS, it’s necessary to add two inboundNatPools and set the initial and final ports. The initial port needs to be 80 and 443, and the final has to be the initial port, plus the amount of VMs in the autoscale.
{ "type": "Microsoft.Network/loadBalancers", ... "inboundNatPools": [{ "name": "[variables('natPoolName')]", "properties": { "frontendIPConfiguration": { "id": "[variables('frontEndIPConfigID')]" }, "protocol": "tcp", "frontendPortRangeStart": "[variables('natStartPort')]", "frontendPortRangeEnd": "[variables('natEndPort')]", "backendPort": "[variables('natBackendPort')]" } }, { "name": "natpool2", "properties": { "frontendIPConfiguration": { "id": "[variables('frontEndIPConfigID')]" }, "protocol": "tcp", "frontendPortRangeStart": "80", "frontendPortRangeEnd": "95", "backendPort": "80" } }, { "name": "natpool3", "properties": { "frontendIPConfiguration": { "id": "[variables('frontEndIPConfigID')]" }, "protocol": "tcp", "frontendPortRangeStart": "443", "frontendPortRangeEnd": "458", "backendPort": "443" } } }
2. VHD
Here, the only important step is change the URL to your URI of the VHD, obtained when the VHD was created.
{ "type": "Microsoft.Compute/virtualMachineScaleSets", ... "virtualMachineProfile": { "storageProfile": { "osDisk": { "name": "vmssosdisk", "caching": "ReadOnly", "createOption": "FromImage", "image": { "uri": "https://storageaccount.blob.core.windows.net/system/Microsoft.Compute/Images/vhds/vhd-osDisk.10aaf77a.vhd" }, "osType": "Linux" } } ... }
3. Metrics
The memory metrics are set to increase the amount of VMs when the percent of used memory reaches 60, and decrease when it reaches 30. Also, in the timeWindow, you can set the time that autoscale will wait to increase and decrease.
{ "type": "Microsoft.Insights/autoscaleSettings", ... "rules": [ { "metricTrigger": { "metricName": "\\Memory\\PercentUsedMemory", "metricNamespace": "", "metricResourceUri": "[concat('/subscriptions/',subscription().subscriptionId, '/resourceGroups/', resourceGroup().name, '/providers/Microsoft.Compute/virtualMachineScaleSets/', parameters('vmSSName'))]", "timeGrain": "PT1M", "statistic": "Average", "timeWindow": "PT5M", "timeAggregation": "Average", "operator": "GreaterThan", "threshold": 60 }, "scaleAction": { "direction": "Increase", "type": "ChangeCount", "value": "1", "cooldown": "PT1M" } }, { "metricTrigger": { "metricName": "\\Memory\\PercentUsedMemory", "metricNamespace": "", "metricResourceUri": "[concat('/subscriptions/',subscription().subscriptionId, '/resourceGroups/', resourceGroup().name, '/providers/Microsoft.Compute/virtualMachineScaleSets/', parameters('vmSSName'))]", "timeGrain": "PT1M", "statistic": "Average", "timeWindow": "PT10M", "timeAggregation": "Average", "operator": "LessThan", "threshold": 30 }, "scaleAction": { "direction": "Decrease", "type": "ChangeCount", "value": "1", "cooldown": "PT1M" } }] }
That’s it! Now you just need to save your template and deploy!
Good luck 😉