Azure waste

Old snapshots still billing in Azure

Old backups of disks that no longer exist
The agent fixes this
Why it happens

Snapshots are taken before a risky change and then forgotten. They keep billing long after the thing they protected is gone.

Snapshots are taken before a risky change and then forgotten. They bill quietly forever, and the disk they protected is often long gone.

Paste this into Resource Graph Explorer in the Azure portal.

resources
| where type =~ 'microsoft.compute/snapshots'
// Scope below matches CloudFinOpsPro policy DEFAULTS: exclusions.protectTag, environment.tagKeys,
// environment.allowedTagValues, and allowUntagged false so an untagged resource counts as production.
// If your policy.yaml differs, edit the three lines below or this will disagree with your own agent.
| where tolower(tostring(coalesce(tags['cfop:protect'], ''))) !in ('true', 'yes', '1')
| extend cfopEnv = tolower(trim(' ', tostring(coalesce(tags['Environment'], tags['environment'], tags['env'], ''))))
| where cfopEnv in ('dev', 'development', 'test', 'qa', 'sandbox', 'nonprod', 'non-prod', 'staging')
| extend sourceDiskId = tolower(tostring(properties.creationData.sourceResourceId))
| extend ageDays = datetime_diff('day', now(), todatetime(properties.timeCreated))
| extend agentCreated = isnotempty(tostring(tags['cfop:origin']))
| extend retentionDays = iff(agentCreated, 14, 90)
| where ageDays >= retentionDays
| join kind=leftouter (
    resources
    | where type =~ 'microsoft.compute/disks'
    | project sourceDiskId = tolower(id), sourceDiskStillExists = 'yes'
  ) on sourceDiskId
| where isempty(sourceDiskStillExists)
| project name, resourceGroup, ageDays, retentionDays, agentCreated,
          sizeGb = toint(properties.diskSizeGB), sourceDiskId
| order by ageDays desc

The join is the important half and the previous version of this query did not have it. A snapshot whose source disk still exists is a deliberate backup, not waste, and the agent will not touch one: the code calls that check the only thing standing between this rule and deleting every backup in the estate. Without the join this lists your live backups and tells you the agent proposes deleting them. The two retention windows are not cosmetic either. A snapshot the agent took itself before deleting a disk carries a cfop:origin tag and is reclaimed after 14 days; anyone else's needs 90, so publishing a flat 90 hid the agent's own snapshots for the 76 days in between. Verified against the reference subscription: at 14 days it returns nothing, because those snapshots are ten days old, and lowering the window to 1 day returns exactly the seven whose source disks are gone and correctly leaves out the eighth, whose disk is still there.

Applies to microsoft.compute/snapshots
What the agent does about it

A snapshot past its retention window whose source disk no longer exists.

And what stops it

It has to see the same thing on three consecutive runs before it will act, it stays away from anything a person changed recently, and it will not touch a resource unless you tagged it non-production. Untagged counts as production. Every refusal is written down with the rule that caused it.