Azure compute resources that are used to create and manage groups of heterogeneous load-balanced virtual machines.
Hey Nelson, here’s a walkthrough you can use to build your lab solution (Portal, CLI/PowerShell, and ARM template examples) for each of the four challenge steps:
Create a Custom VM Image a. Azure Portal • Deploy a VM from Marketplace or existing image. • Generalize it: connect via RDP/SSH, run “sysprep /generalize /shutdown” (Windows) or “sudo waagent -deprovision+user -force; sudo shutdown -h now” (Linux). • In the Portal, go to the VM’s Overview > Capture > give it a name, resource group, and select “Automatically delete this virtual machine after creating the image.” b. Azure CLI
# Deallocate & generalize (Windows example)
az vm deallocate --resource-group RG --name MyVM
az vm generalize --resource-group RG --name MyVM
az image create --resource-group RG --name MyCustomImage \
--source MyVM
c. PowerShell
Stop-AzVM -ResourceGroupName RG -Name MyVM -Force
Set-AzVM -ResourceGroupName RG -Name MyVM -Generalized
New-AzImage -ResourceGroupName RG -ImageName MyCustomImage -SourceVirtualMachineId $vm.Id
d. ARM Template snippet
{
"type": "Microsoft.Compute/images",
"apiVersion": "2021-04-01",
"name": "[parameters('imageName')]",
"location": "[resourceGroup().location]",
"properties": {
"storageProfile": {
"osDisk": {
"osType": "Windows",
"osState": "Generalized",
"blobUri": null,
"managedDisk": {
"id": "[parameters('vmId')]"
}
}
}
}
}
- Create a Scale Set with Availability Zones a. Azure Portal • Navigate to “Create a resource” > “Compute” > “Virtual machine scale set.” • Under “Basics,” choose your RG, name, and custom image. • Under “Availability options,” pick “Availability zones” and select Zones 1, 2, 3. • Finish networking, health probes, and hit Create. b. Azure CLI
az vmss create \
--resource-group RG
--name MyScaleSet
--image MyCustomImage
--zones 1 2 3
--instance-count 2
--upgrade-policy-mode Automatic
c. PowerShell
powershell
$sku = New-AzVmssSku -Name Standard_DS1_v2 -Capacity 2 -Tier Standard
$vz = New-AzVmssVirtualMachineScaleSetPublicIPAddressConfiguration -Name pipConfig -DomainNameLabel mylabel
$ipconfig = New-AzVmssIpConfig -Name ipconfig1 -SubnetId $subnet.Id -PublicIpAddressConfiguration $vz
$vmss = New-AzVmssConfig -Location eastus -Sku $sku -Overprovision
$vmss.VirtualMachineProfile.NetworkProfile.NetworkInterfaceConfigurations.Add(
(New-AzVmssNetworkInterfaceConfiguration -Name nic1 -Primary `
-IpConfiguration $ipconfig -EnableIPForwarding))
$vmss.VirtualMachineProfile.StorageProfile.ImageReference.Id = $image.Id
$vmss.Zones = @("1","2","3")
New-AzVmss -ResourceGroupName RG -Name MyScaleSet -VirtualMachineScaleSet $vmss
d. ARM Template snippet
{
"type": "Microsoft.Compute/virtualMachineScaleSets",
"apiVersion": "2021-04-01",
"name": "[parameters('vmssName')]",
"location": "[resourceGroup().location]",
"zones": [ "1", "2", "3" ],
"sku": { "name": "Standard_DS1_v2", "capacity": 2 },
"properties": {
"upgradePolicy": { "mode": "Automatic" },
"virtualMachineProfile": {
"storageProfile": {
"imageReference": { "id": "[resourceId('Microsoft.Compute/images', parameters('imageName'))]" }
},
"networkProfile": {
"networkInterfaceConfigurations": [
{
"name": "nicConfig",
"properties": {
"primary": true,
"ipConfigurations": [
{
"name": "ipconfig1",
"properties": {
"subnet": { "id": "[parameters('subnetId')]" },
"publicIPAddressConfiguration": {
"name": "pipConfig",
"properties": { "domainNameLabel": "[parameters('dnsLabel')]" }
}
}
}
]
}
}
]
}
}
}
}
- Configure Autoscale a. Azure Portal • In your VMSS blade, go to “Scaling” > “Add a rule.” • Define a metric (e.g., CPU Percentage > 75%), scale out by +1, cool-down period 5 min. • Add a scale‐in rule (e.g., CPU < 25%, decrease by 1). b. Azure CLI
az monitor autoscale create \
--resource-group RG
--resource MyScaleSet
--resource-type Microsoft.Compute/virtualMachineScaleSets
--name autoscaleConfig
--min-count 1 --max-count 5 --count 2
az monitor autoscale rule create
--resource-group RG --autoscale-name autoscaleConfig
--condition "Percentage CPU > 75 avg 5m"
--scale out 1
az monitor autoscale rule create
--resource-group RG --autoscale-name autoscaleConfig
--condition "Percentage CPU < 25 avg 5m"
--scale in 1
c. PowerShell
powershell
$autoscale = Add-AzAutoscaleSetting -ResourceGroupName RG -TargetResourceId $vmss.Id `
-Name "MyVMSSAutoscale" -MinCapacity 1 -MaxCapacity 5 -DefaultCapacity 2
Add-AzAutoscaleRule -AutoscaleSetting $autoscale `
-MetricName "Percentage CPU" -Operator GreaterThan -Threshold 75 `
-TimeGrain 00:01:00 -TimeWindow 00:05:00 -Statistic Average `
-ScaleActionScaleType ChangeCount -ScaleActionValue 1 -ScaleActionCooldown 00:05:00
Add-AzAutoscaleRule -AutoscaleSetting $autoscale `
-MetricName "Percentage CPU" -Operator LessThan -Threshold 25 `
-TimeGrain 00:01:00 -TimeWindow 00:05:00 -Statistic Average `
-ScaleActionScaleType ChangeCount -ScaleActionValue -1 -ScaleActionCooldown 00:05:00
d. ARM Template snippet
{
"type": "Microsoft.Insights/autoscaleSettings",
"apiVersion": "2015-04-01",
"name": "autoscaleConfig",
"location": "[resourceGroup().location]",
"properties": {
"targetResourceUri": "[resourceId('Microsoft.Compute/virtualMachineScaleSets', parameters('vmssName'))]",
"enabled": true,
"profiles": [
{
"name": "AutoScaleProfile",
"capacity": { "minimum": "1", "maximum": "5", "default": "2" },
"rules": [
{
"metricTrigger": {
"metricName": "Percentage CPU",
"metricNamespace": "",
"operator": "GreaterThan",
"threshold": 75,
"timeGrain": "PT1M",
"statistic": "Average",
"timeWindow": "PT5M",
"timeAggregation": "Average"
},
"scaleAction": {
"direction": "Increase",
"type": "ChangeCount",
"value": "1",
"cooldown": "PT5M"
}
},
{
"metricTrigger": {
"metricName": "Percentage CPU",
"metricNamespace": "",
"operator": "LessThan",
"threshold": 25,
"timeGrain": "PT1M",
"statistic": "Average",
"timeWindow": "PT5M",
"timeAggregation": "Average"
},
"scaleAction": {
"direction": "Decrease",
"type": "ChangeCount",
"value": "1",
"cooldown": "PT5M"
}
}
]
}
]
}
}
- Deploy an Update with Custom Script Extension a. Azure Portal • In your VMSS blade > “Extensions” > “Add” > “Custom Script Extension.” • Provide the script URL (e.g., a blob SAS URL) and any arguments. • Save to rollout the update across all instances. b. Azure CLI
az vmss extension set \ --vmss-name MyScaleSet \ --name CustomScript \ --publisher Microsoft.Azure.Extensions \ --version 2.1 \ --settings '{"fileUris":["https://mystorage.blob.core.windows.net/scripts/update.sh"],"commandToExecute":"bash update.sh"}'
Set-AzVmssExtension -ResourceGroupName RG -VMScaleSetName MyScaleSet -Name CustomScript -Publisher "Microsoft.Azure.Extensions" -Type "CustomScript" -TypeHandlerVersion "2.1"
-SettingString '{"fileUris":["https://.../update.sh"],"commandToExecute":"bash update.sh"}'
d. ARM Template snippet
```json
{
"type": "Microsoft.Compute/virtualMachineScaleSets/extensions",
"apiVersion": "2021-04-01",
"name": "[concat(parameters('vmssName'), '/CustomScript')]",
"properties": {
"publisher": "Microsoft.Azure.Extensions",
"type": "CustomScript",
"typeHandlerVersion": "2.1",
"settings": {
"fileUris": ["https://mystorage.blob.core.windows.net/scripts/update.sh"],
"commandToExecute": "bash update.sh"
}
}
}
References
• VMSS overview & zones: https://docs.microsoft.com/azure/virtual-machine-scale-sets/overview
• VMSS FAQ & troubleshooting: https://docs.microsoft.com/azure/virtual-machine-scale-sets/virtual-machine-scale-sets-faq
• Autoscale best practices: https://docs.microsoft.com/azure/monitoring-and-diagnostics/insights-autoscale-best-practices
• Custom Script Extension for Windows/Linux: https://docs.microsoft.com/azure/virtual-machines/extensions/custom-script-windows
• ARM template reference: https://docs.microsoft.com/azure/templates/microsoft.compute/2021-04-01/virtualmachinescalesets