# Azure RI/SP Covering Deallocated VM

> 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.

Source: https://zop.dev/integrations/azure/recommendations/azure-ri-sp-covering-deallocated-vm
Updated: 2026-08-19

---

## 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

```bash
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.
