Skip to main content
orphan · azure

Deallocated Azure VM Residual Cost

resource types
1
rule IDs covered
1
severity
low

What does ZopNight detect here?

Deallocated standalone Azure VMs bill $0 for compute yet keep charging for attached managed disks and public IPs. Savings sum the priced monthly cost of those residual children, itemised into disk and IP components; the rule abstains when no child matches or every child is unpriced.

Signal and threshold

How ZopNight evaluates Deallocated Azure VM Residual Cost.
Field Value
Rule IDsRC-1384
Categoryorphan
Severitylow
Metricnone — pure configuration read
Sourcedeallocated_vm_residual.go

Deallocated, standalone, and still billing children

Azure VM with Status = deallocated (compute billing stopped) and no ParentUID (standalone, not a VMSS member). The Azure analog of GCP RC-109 / AWS RC-001.

  • resource.Status: must be deallocated (a merely stopped/not-deallocated VM still bills compute, so the residual-only basis does not apply).
  • resource.ParentUID: empty (standalone).
  • ResourceContextAware (SetResources) + PricingAware (SetPricing): the org resource set + per-UID monthly cost, to find and price the VM’s residual children.
  • Child association: managed disk already carries ParentUID = managedBy (the VM); public-ip carries ParentUID = VM via the discoverer’s public-ip → NIC → VM ARG join (applyPublicIPLookupSets).

Adding up the disks and public IPs left behind

concrete-or-abstain (Category orphan, exempt from shouldDropLowSavings). Compute is $0 for a deallocated VM, so the deletable saving is the residual: Σ cost[child] over attached managed disks + public IPs (gated by the shared model.IsResidualCostChildType). CurrentCostUSD = SavingsUSD = residual, OptimizedCostUSD = 0. SavingsBreakdown itemises the residual into Managed disk + Public IP components (summing to SavingsUSD) for the UI. The child↔VM ParentUID match is case-insensitive (Azure returns the VM id and its children’s cross-ref ids with divergent resourceGroup casing). The rule abstains when resources/pricing were not injected, no child matched, or every child is unpriced, and never emits a $0 or advisory rec. Disjoint from RC-1380 (RI/SP commitment, compute-domain) and idle_vm.go (running VMs only).

Deleting the leftovers, or starting the VM

  1. Check whether the VM is intentionally deallocated (e.g., a long-running batch worker).
  2. If no longer needed, delete the VM, then its non-auto-delete managed disks.
  3. Release/delete any Standard public IP associated with the VM (it bills while allocated).
  4. If it should be running, start it (az vm start).

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·