Microsoft Azure offers some cheap low spec virtual machines. But as we all know, the prices can go up pretty quickly as the specs go up. But we need large VMs to support today’s modern day workloads. The downside is that most of these workloads are only present during business hours but you end up running and paying for these large VMs even during non-business hours and on weekends.
One option is to have an Azure automation script to shut down the VMs during non-business hours and have another script automation script to power these back up just before start of business.
Although, this solution might work for some dev/test kind of VMs, it won’t be feasible for most of your VMs as you still need the critical services to be up during non-business hours, just not on large monstrous VMs.
The solution here is to have an azure automation script that resizes the VMs to the lowest possible size during non-business hours and have another automation script to resize the VMs to their original size just before start of business.
We will use two resource tags to help us achieve this:
Reducesize=”Yes” Originalsize=<Original size of VM> (Eg: Originalsize=Standard_D4)
The tricky part here is that the lowest possible size differs based on the number of data disks attached to the VM. The script below looks at the number of data disks attached and chooses the lowest possible size for the VM based on it.
Script: ScaleDownVMs
$CredentialAssetName = '<Your Automation Credentials>' $Cred = Get-AutomationPSCredential -Name $CredentialAssetName if(!$Cred) { Throw 'Could not find an Automation Credential Asset named '${CredentialAssetName}'. Make sure you have created one in this Automation Account.' } Add-AzureRmAccount -Credential $Cred | Out-Null Select-AzureRmSubscription -SubscriptionName "<Subscription Name>" $vmList = Find-AzureRmResource | Where-Object {$_.Tags.Name -eq 'Reducesize' -and $_.Tags.Value -eq 'Yes'} foreach($vmEntry in $vmList) { $vm = Get-AzureRmVM -Name $vmEntry.Name -ResourceGroupName $vmEntry.ResourceGroupName $DataDisksCount = $vm.StorageProfile.DataDisks.Count if($DataDisksCount -le 1 ) { $targetSize = "Standard_A0" } elseif($DataDisksCount -le 2 ) { $targetSize = "Standard_A1" } elseif($DataDisksCount -le 4 ) { $targetSize = "Standard_A2" } elseif($DataDisksCount -le 8 ) { $targetSize = "Standard_A3" } else { $targetSize = "Standard_A4" } $vm.HardwareProfile.vmSize = $targetSize Update-AzureRmVM -ResourceGroupName $vmEntry.ResourceGroupName -VM $vm }
Script: ScaleUpVMs
$CredentialAssetName = '<Your Automation Credentials>' $Cred = Get-AutomationPSCredential -Name $CredentialAssetName if(!$Cred) { Throw 'Could not find an Automation Credential Asset named '${CredentialAssetName}'. Make sure you have created one in this Automation Account.'} Login-AzureRmAccount -Credential $Cred Select-AzureRmSubscription -SubscriptionName "<Subscription Name>" $vmList = Find-AzureRmResource | Where-Object {$_.Tags.Name-eq 'Reducesize' -and $_.Tags.Value -eq 'Yes'} foreach($vmEntry in $vmList) { $vm = Get-AzureRmVM -Name $vmEntry.Name -ResourceGroupName $vmEntry.ResourceGroupName $OriginalSize = $vm.Tags.Originalsize.ToString() $vm.HardwareProfile.vmSize = $OriginalSize Update-AzureRmVM -ResourceGroupName $vmEntry.ResourceGroupName -VM $vm }