← Back to Engineering Blog
πŸ—“οΈ Oct 10, 2023⏱️ 5 min read

Automating Cloud Hygiene: Reclaiming Unattached Managed Disks & Public IPs at Scale

Why deleting Azure VMs leaves expensive Premium SSDs burning $56,000 monthly, and how automated Azure Runbooks safely reclaimed orphaned assets.

πŸŽ™οΈ Listen to ArticleREADY
AI Audio Synthesis Narrator
Share Post:

β€œDeleting an Azure Virtual Machine does not automatically delete its associated Premium SSD managed disk or static Public IP address. Unattached resources linger silently in your resource groups, burning tens of thousands of dollars on your monthly invoice.”

In October 2023, in my current role as Associate Director, Cloud Architecture & AI, I led a comprehensive Cloud FinOps audit for a banking client across 40 enterprise Azure subscriptions.

The client’s development teams and automated CI/CD pipelines deployed and decommissioned hundreds of Azure Virtual Machines and AKS Kubernetes worker nodes every month.

The infrastructure team assumed that when a VM was deleted, Azure cleaned up all associated resources.

They were wrong.


The Default Behavior Trap

In Azure, a Virtual Machine, its Managed Disks, its Network Interfaces (NICs), and its Public IP addresses are separate resource providers.

When an engineer clicks β€œDelete” on an Azure VM in the portal or runs az vm delete, Azure deletes the VM compute shellβ€”but leaves the underlying Managed Disks (DiskState = Unattached) and Public IPs (IpAddress = Unattached) untouched.

Unless explicit cascading deletion rules are configured during VM creation, every decommissioned VM leaves an expensive storage footprint behind.

Our FinOps audit ran a cross-subscription query to inventory unattached resources.

The results were staggering:

# Azure CLI Inventory Query for Unattached Managed Disks
az graph query -q "Resources | where type =~ 'microsoft.compute/disks' and properties.diskState =~ 'Unattached'"
# Output: Found 420 Unattached Managed Disks (P30 1TB Premium SSDs)
# Output: Found 180 Unattached Static Public IP Addresses

A 1TB Premium SSD (P30 disk) costs approximately $135 per month in Azure, whether it is attached to an active VM or sitting 100% idle in Unattached state.

420 unattached 1TB Premium SSDs were generating a silent, wasted charge of $56,700 USD per month ($680,400 USD per year)!

The client’s finance department had been paying this invoice for 14 months without realizing that half a million dollars was being burned on orphaned disks.


The Mess: The Deleted Forensic Database Disk

When the FinOps audit revealed the $56,700 monthly loss, an eager junior cloud engineer wrote a simple Bash script to clean up the environment:

# The dangerous immediate deletion script:
az disk delete --ids $(az disk list --query "[?managedBy==null && diskState=='Unattached'].id" -o tsv) --yes

He executed the script on a Tuesday afternoon.

Two hours later, an emergency P1 ticket was raised by the lead database administrator.

The DBA had intentionally detached a 2TB production SQL Server database disk from an offline VM earlier that morning to execute a manual forensic database repair.

Because the disk was temporarily in Unattached state while the DBA prepared his recovery commands, the junior engineer’s script scanned the disk, identified it as β€œunattached,” and deleted it permanently from Azure!

The database team spent 12 hours restoring the database from secondary backups.

Immediate deletion scripts without safety protocols were an operational hazard. We needed automated cloud hygiene with strict safety guardrails.


The Solution: The 7-Day Quarantine & Snapshot Runbook

We replaced manual deletion scripts with an automated Azure Automation Runbook executing PowerShell and Azure CLI scripts on a weekly schedule.

# Automated 4-Step Asset Reclamation Pipeline

1. **Identification & Snapshot:** Identify disks in `Unattached` state for >7 days. Automatically take a low-cost Standard LRS snapshot of the disk.
2. **Quarantine Tagging:** Apply tag `PendingDeletion = True` and `QuarantineDate = <Date>` to the unattached disk.
3. **Owner Notification:** Send an automated Teams/Slack notification and email to the Resource Group owner listing tagged disks.
4. **Automated Purge:** If the disk remains in `Unattached` state with `PendingDeletion = True` for 7 days after tagging, execute hard deletion automatically.
# Azure Automation PowerShell Runbook Snippet
$UnattachedDisks = Get-AzDisk | Where-Object { $_.ManagedBy -eq $null -and $_.DiskState -eq "Unattached" }

foreach ($Disk in $UnattachedDisks) {
    $QuarantineDate = (Get-Date).ToString("yyyy-MM-dd")

    # 1. Take a low-cost safety snapshot before tagging
    New-AzSnapshot -ResourceGroupName $Disk.ResourceGroupName -SnapshotName "$($Disk.Name)-SafetySnap" -Snapshot (New-AzSnapshotConfig -Location $Disk.Location -CreateOption Copy -SourceResourceId $Disk.Id)

    # 2. Tag disk with Quarantine metadata
    $Tags = $Disk.Tags
    if ($Tags -eq $null) { $Tags = @{} }
    $Tags["PendingDeletion"] = "True"
    $Tags["QuarantineDate"] = $QuarantineDate

    Set-AzDisk -ResourceGroupName $Disk.ResourceGroupName -DiskName $Disk.Name -Tag $Tags

    Write-Output "Quarantined Disk: $($Disk.Name) in RG: $($Disk.ResourceGroupName)"
}

If a DBA detaches a disk for manual maintenance, he has a 7-day safety window to remove the PendingDeletion tag or re-attach the disk before any deletion occurs, backed by an automated recovery snapshot.


The Impact

  • $56,700 Monthly Savings: Reclaimed $56,700 per month ($680,000/year) in wasted unattached disk and Public IP storage spend.
  • Zero Data Loss: Safety snapshots and 7-day quarantine tagging guaranteed 100% protection against accidental disk deletions.
  • Automated Cloud Hygiene: Built a self-sustaining Azure Automation Runbook that keeps subscriptions 100% clean of orphaned cloud waste.

Key Takeaway

Deploy Automated Scheduled Cleanup Runbooks for Orphaned Cloud Assets.

Never run immediate bulk deletion scripts against unattached cloud disks. Deploy an Azure Automation Runbook that takes low-cost safety snapshots, applies a 7-day Quarantine Tagging Protocol, and notifies resource owners via automated webhooks before executing hard deletions to reclaim unattached disk and IP waste safely.


Architecture and decisions: mine. Debugging sessions at odd hours: mine. AI assistance: structure, syntax, first draft. β€” Sachin

SKS

Sachin Kumar Sharma

Associate Director (Infrastructure & Cloud Architecture Strategy) | 20+ Yrs Exp

Architecting resilient multi-cloud enterprise landing zones, SDN overlay fabrics, DevSecFinOps automation pipelines, and autonomous Agentic AI platforms.

πŸ“¬

πŸ“¬ Stay Updated on Tech Releases

Sign up to get notified when I publish new production war stories, agentic AI architecture blueprints, or open-source infrastructure tools.

⚑ Theme Adaptive Shift
Switching layouts matching domain reading affinity...