Skip to main content
idle · aws

EKS node groups at zero nodes with orphaned volumes still billing

resource types
1
rule IDs covered
1
severity
medium

What does ZopNight detect here?

An EKS node group scaled to 0 nodes, or stuck in DEGRADED status, bills nothing itself; the waste sits in what it strands. ZopNight sums the cluster's Released and Available PersistentVolumes' backing EBS volumes, plus load balancers with zero healthy targets, and reports that whole amount as recoverable.

Signal and threshold

How ZopNight evaluates EKS node groups at zero nodes with orphaned volumes still billing.
Field Value
Rule IDsRC-043
Categoryidle
Severitymedium
Metricnone — pure configuration read
Sourceeks_abandoned_workloads.go

Zero desired nodes or a DEGRADED status

Two signals mark an EKS node group as abandoned. Either its discovered desired node count is exactly 0 (read from metadata the discoverer records, so a group with no recorded count is never assumed empty), or the group sits in the DEGRADED state AWS uses for an unrecoverable error. Either signal starts the evaluation; a healthy group with running nodes never does.

Why the node group row bills $0

An EKS managed node group is a free control object: the per-cluster hourly charge covers the control plane, not the group. Its worker EC2 instances are billed individually, and a group at zero nodes has none. So the rule refuses to price the group row itself: a made-up dollar figure against a $0 resource is precisely the kind of finding the platform bans. What abandonment actually costs is the debris left around it.

Released volumes and dead load balancers

When workloads leave a cluster, two kinds of paid resources routinely stay behind. A PersistentVolume in the Released phase (its claim was deleted but the reclaim policy kept the volume) or the Available phase (provisioned, never bound) still has an EBS volume billed on provisioned size every month; Bound volumes are in active use and excluded. Service-created load balancers whose target health reports 0 healthy targets are the second kind. The rule joins each orphaned PersistentVolume to its EBS volume through the CSI volume handle, joins each cluster service to its load balancer through the DNS name, and sums the monthly price of everything it matches.

One node group owns the cluster’s orphan bill

A cluster can hold several abandoned node groups, and one EBS volume can be referenced from two abandoned clusters. In both cases a single owner (the abandoned group, then the cluster, with the smallest UID) carries the whole figure. Companion rules for orphaned EBS volumes and idle load balancers cede these same resources, so the money is counted once, never per rule.

Spotting an abandoned group from the CLI

Terminal window
aws eks describe-nodegroup --cluster-name my-cluster --nodegroup-name workers \
--query 'nodegroup.{status:status,desired:scalingConfig.desiredSize}'

Follow up inside the cluster with kubectl get pv and look for Released or Available entries.

When RC-043 reports nothing

The evaluation abstains without an org-wide resource and pricing context, since the join is cross-resource by nature. It also stays silent when the group has no recorded parent cluster, when another group owns the cluster’s figure, and when the orphaned-attachment total comes to zero. A load balancer whose health probe never ran contributes nothing. Fail closed, never guess.

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·