Stopped Standalone GCE VM
What does ZopNight detect here?
TERMINATED standalone GCE VMs pay $0 for compute but keep billing attached persistent disks and reserved static IPs. Savings sum the priced monthly cost of those residual children, broken down per component; when no child matches or none carries a positive price, the rule abstains.
Signal and threshold
| Field | Value |
|---|---|
| Rule IDs | RC-109 |
| Category | orphan |
| Severity | low |
| Metric | none — pure configuration read |
| Source | stopped_vm.go |
Where it applies
Terminated, with no parent group
GCE VM with Status = TERMINATED and no ParentUID (excludes MIG / GKE node-pool members whose lifecycle is parent-managed).
- resource.Status: must be TERMINATED
- resource.ParentUID: must be empty (standalone, not MIG-managed)
- ResourceContextAware (SetResources): the full org resource set, so the rule can find the VM’s attached-disk / reserved-static-IP child resources (matched by ParentUID, normalized via normalizeComputeUID to bridge the raw asset-name vs. //compute.googleapis.com/… link form).
- PricingAware (SetPricing): per-resource monthly cost keyed by UID, used to price each child.
The residual disks and static IPs still billing
concrete-or-abstain (Category orphan, which is exempt from shouldDropLowSavings). Compute is $0 for a TERMINATED VM, so the deletable saving is the residual: residual = Σ cost[child] over every attached child (persistent disks + reserved static IPs) with a positive priced cost, so CurrentCostUSD = SavingsUSD = residual, OptimizedCostUSD = 0. The child-type gate is the shared model.IsResidualCostChildType (also used by the org engine’s cross-chunk residual pricing, so the fold and pricing can’t drift). SavingsBreakdown itemises the residual into Persistent disk + Static IP components (summing to SavingsUSD) for the UI, at parity with RC-001. Abstains (returns nil) when resources/pricing were not injected, no child matched, or every child is unpriced/zero: never a $0 or advisory rec, never a fabricated fraction of compute. (Was previously documented as advisory-only / not auto-remediable; reworked under the 2026-06-27 concrete-or-abstain directive.)
Deleting the VM and its leftovers
- Check whether the VM is intentionally stopped (e.g., long-running batch worker).
- If no longer needed, delete the VM. Confirm attached disks have autoDelete enabled, or delete them separately.
- Release any reserved static external IPs.
- If the VM should be running, restart via gcloud compute instances start.