Azure waste

Premium disk on a VM that has been off all window

A Premium SSD attached to a virtual machine that has been deallocated for the whole window, so it bills for performance nothing is using.
The agent reports this
Reversible
Why it happens

A deallocated VM bills nothing for compute, and its managed disk bills in full whether or not the machine ever starts again. A 128 GiB Premium SSD is $17.92 a month against $9.60 on Standard SSD, and a 1 TiB disk is $122.88 against $76.80. The check requires a current power state of deallocated AND zero CPU datapoints across the window, because this product schedules non-prod machines to deallocate overnight and those emit CPU during the day: without the second condition it would recommend a slower disk for a machine the customer deliberately runs every morning.

Paste this into Resource Graph Explorer in the Azure portal.

resources
| where type =~ 'microsoft.compute/virtualmachines'
// 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')
| where tostring(properties.extended.instanceView.powerState.code) =~ 'PowerState/deallocated'
| project vmId = tolower(id), vm = name
| join kind=inner (
    resources
    | where type =~ 'microsoft.compute/disks'
    | where sku.name has 'Premium'
    | project disk = name, resourceGroup,
              sizeGb = toint(properties.diskSizeGB),
              sku = tostring(sku.name),
              vmId = tolower(tostring(managedBy))
) on vmId
| project disk, resourceGroup, sku, sizeGb, attachedTo = vm

managedBy is a top-level Resource Graph column, not a field inside properties. The power state only appears when the virtual machines row carries properties.extended.instanceView, which Resource Graph fills in. A deallocated machine bills nothing for compute while its Premium disk bills in full, but check the machine is not simply switched off overnight on a schedule before moving it to Standard SSD. Resource Graph shows the current power state and nothing about how long it has held, so the query cannot apply the rest of the check: it requires the machine to have published no datapoints for the Percentage CPU metric across the previous 336 hours, which is how a machine that has been off for two weeks is told apart from one deallocated a minute ago.

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

A Premium SSD attached to a virtual machine that has been deallocated for the whole window, so it bills for performance nothing is using.

It will not fix this one

It reports this and takes no action. A check only earns the right to change something once the action behind it can re-read live state before it fires and knows the way back.