adaptive.run TECH BLOG

Cloud can be tricky sometimes. Find out what scenarios we've ran into that are worth being mentioned and explained.

Automating Common Cost Optimizations in Azure

Level: 200
Publishing date: 26-Mar-2024
Author: Catalin Popa

Azure cost optimizations are often simple fixes, such as cleaning up forgotten Public IPs, removing lingering VM Snapshots, or deallocating stopped VMs. To maintain good cost hygiene, it's beneficial to automate these tasks using Azure Automation. This article guides you through the process of setting up an Automation Account and deploying a script for common cost optimizations.

Setting up the Automation Account
Begin by creating an Automation Account. If using the portal, default settings should be enough. For code deployment (using Bicep in this example), include the managed identity. The following Bicep script achieves this:

 param location string = resourceGroup().location

resource automationAccount 'Microsoft.Automation/automationAccounts@2019-06-01' = {
name: 'CostOptimizationAutomation'
location: location
identity: {
type: 'SystemAssigned'
}
properties: {
sku: {
name: 'Free'
}
}

After creating the Automation Account, add the necessary role assignment directly from the Automation Account blade under Identity.

azure.microsoft.com
In the Azure role assignments window, view existing roles and add new roles. 

azure.microsoft.com
azure.microsoft.com
For least-privilege, consider using built-in roles like Disk Snapshot Contributor, Desktop Virtualization Power On Off Contributor, and Network Contributor. Alternatively, create a custom role with only the required permissions for the script:

Microsoft.Compute/virtualMachines/read
Microsoft.Compute/virtualMachines/deallocate/action
Microsoft.Compute/snapshots/delete
Microsoft.Compute/snapshots/read
Microsoft.Network/publicIPAddresses/read
Microsoft.Network/publicIPAddresses/delete

The Script
The script checks for three conditions: Public IPs not connected to any resource, snapshots older than 60 days, and VMs stopped but not deallocated. Create a Runbook, paste the script, and connect it to a schedule for regular execution.

PowerShell:


$exclusiontag = "ExcludeCostOptimization"

Connect-AzAccount -Identity

$subscriptions = Get-AzSubscription

foreach($subscription in $subscriptions) {
$pips = Get-AzResource -Tag @{$exclusiontag="false"} -Resourcetype "Microsoft.Network/publicIPAddresses"
foreach($pip in $pips){
get-azpublicIPAddress -name $pip.name | Where-Object IpConfiguration -eq $null | Remove-AzPublicIpAddress -Force
}

$snapshots = Get-AzResource -Tag @{$exclusiontag="false"} -Resourcetype "Microsoft.Compute/Snapshots"
$date = (Get-Date).AddDays(-60)
foreach($snapshot in $snapshots) {
Get-AzSnapshot -SnapshotName $snapshot.name | Where-Object { $_.TimeCreated -lt $date } | Remove-AzSnapshot -Force
}

$vms = Get-AzResource -Tag @{$exclusiontag="false"} -Resourcetype "Microsoft.Compute/VirtualMachines"
foreach($vm in $vms) {
get-azvm -Status -Name $vm.Name | Where-Object PowerState -eq "VM stopped" | Stop-AzVM -Force
}

This script automates the detection and resolution of Public IPs, snapshots, and VMs that can be optimized for cost efficiency. Customize the script based on your specific needs and schedule it to run at regular intervals for continuous cost optimization in your Azure environment.

adaptive.run

Transform your business.
Run adaptive.

Contact

Phone: +40 73 523 0005
Email: hello@adaptive.run

© Copyright  2019-2024 adaptive.run- All Rights Reserved