Skip to main content
discount · azure

Deallocated VMs whose reservations keep billing (detected, not dollar-tagged)

resource types
1
rule IDs covered
1
severity
high

What does ZopNight detect here?

Reserved Instances and Savings Plans bill every hour of their 1- or 3-year term regardless of VM power state, so a deallocated covered VM wastes committed spend. ZopNight detects the condition but abstains from claiming a saving: a sunk commitment has no lever that reduces next month's bill.

Signal and threshold

How ZopNight evaluates Deallocated VMs whose reservations keep billing (detected, not dollar-tagged).
Field Value
Rule IDsRC-1380
Categorydiscount
Severityhigh
Metricnone — pure configuration read
Sourceri_deallocated.go

Deallocating a reserved VM saves nothing

Deallocation releases compute and stops on-demand billing. The reflex is correct for pay-as-you-go VMs. Under a Reserved Instance or Savings Plan the reflex fails: the commitment bills every hour of its term whether the covered VM runs or not. A deallocated VM with RI coverage is the worst of both worlds: no workload, full committed cost, and reservation utilization quietly falling below 100%.

What the rule checks before saying anything

Three gates run in order: the VM’s power state must be stopped or deallocated (transient starting and stopping states are excluded), billing coverage must attribute the VM to a Reservation or SavingsPlan purchase, and a positive committed cost must be known. Running covered VMs are exactly right and pass silently.

Why the finding carries no dollar figure

Every lever available on a sunk commitment fails the test of being a real, immediate saving. Exchanging the reservation onto another workload re-points the same dollars, for a net $0. Letting it lapse at term end is a future decision, not a monthly delta. Azure’s own unused-reservation billing rows are reconciliation artifacts, not a per-VM waste figure the recommender can stand behind. Rather than print an invented number or a $0 recommendation that downstream filters would drop anyway, the rule abstains by design. The gates stay wired for the day a true reservation-waste feed exists.

Run the two-sided check yourself

Terminal window
az vm list -d --query \
"[?powerState=='VM deallocated' || powerState=='VM stopped'].{name:name, size:hardwareProfile.vmSize}" \
-o table

Cross-reference the list against reservation utilization in Cost Management → Reservations, where per-reservation usage percentages make idle coverage visible.

The three real responses

Restart the workload the reservation was sized for; exchange the reservation toward a size or region you do run (Azure permits exchanges within policy limits); or calendar the term end and let it expire. Which one applies is a finance-and-capacity decision no scanner should make alone.

Access footprint

Reader establishes power state; Cost Management Reader supplies the coverage attribution. Nothing here is automated. The rule exists to make committed-spend waste visible early.

See it fire on your bill.

Connect an account read-only. The first findings land in minutes.

417 rule families across 353 resource types on 22 platforms. Every threshold, metric, and IAM action is documented on these pages before you grant anything.

417 rule families documented
353 resource types covered
read-only default access level
Multi-cloud automation· Production-ready in 30 min· SOC 2 · ISO 27001· 20–60% off the bill, first month· 4 platforms · 1 console· Multi-cloud automation· Production-ready in 30 min· SOC 2 · ISO 27001· 20–60% off the bill, first month· 4 platforms · 1 console·