Azure Automation -Automatically resize Virtual Machines – Scale Up and Scale Down – Save Money!!!

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
}

 

Leave a comment