Skip to main content
orphan · aws

Unattached EBS volumes in the available state for at least 7 days

resource types
1
rule IDs covered
1
severity
low

What does ZopNight detect here?

ZopNight flags an Amazon EBS volume in the `available` state, attached to nothing, once it has existed for at least 7 days and is not managed by Kubernetes. AWS charges for provisioned storage until the volume is deleted, so the saving is the volume's full monthly cost, including any provisioned IOPS and throughput.

Signal and threshold

How ZopNight evaluates Unattached EBS volumes in the available state for at least 7 days.
Field Value
Rule IDsRC-002
Categoryorphan
Severitylow
Metricnone — pure configuration read
Thresholdavailable (unattached), 7+ days old
Evaluation window7d
SourceZopNight
Permissions usedec2:DescribeVolumes · ec2:DescribeSnapshots

Detaching a volume does not stop the bill

Amazon EBS pricing charges volume storage by the GB you provision per month until you release it, with extra charges for IOPS and throughput above the baseline on types that support them. The detach guide is direct about it: after you detach a volume you are still charged for its storage, and you must delete it to stop the charges.

Volumes end up unattached when instances are terminated with data volumes set to be preserved, when someone detaches a disk for a quick fix, or when a test environment is torn down unevenly.

Listing unattached volumes

Terminal window
aws ec2 describe-volumes --filters Name=status,Values=available \
--query 'Volumes[].[VolumeId,Size,VolumeType,CreateTime,Tags]' --output table

Look at the tags before anything else. The EBS CSI driver’s tagging docs list ebs.csi.aws.com/cluster and CSIVolumeName as tags it adds to every volume it creates; volumes like that belong to a Kubernetes cluster and should be handled through it, not the EC2 console.

Three checks before a finding

  1. The volume’s state is available, meaning it is not attached to any instance.
  2. It does not look Kubernetes-managed: no name starting pvc- or kubernetes-dynamic-pvc-, and no kubernetes.io/created-for/pvc/name, kubernetes.io/cluster/ or KubernetesCluster tag. Deleting a volume that backs a persistent volume claim would strand the pod that needs it.
  3. When ZopNight has the volume’s creation time, the volume must be at least 7 days old, which keeps volumes still being provisioned or migrated out of the list.

Cases handled elsewhere or left out

AWS exposes no detach timestamp, so the 7 days count from creation; an old volume detached yesterday can still qualify, which is why the fix steps start with a check. A volume that backs a released Kubernetes persistent volume in a cluster whose node group has been abandoned is counted under EKS Abandoned Node Group instead, so the same cost is not reported twice. Volumes with no price are skipped.

The full volume cost comes back

Terminal window
saving = the volume's monthly cost (storage + provisioned IOPS + provisioned throughput)
cost after fix = 0

Removing an unattached volume

  1. Check the volume’s tags and recent CloudTrail DetachVolume events to see who detached it and when.
  2. Snapshot it if the data may be needed: aws ec2 create-snapshot --volume-id vol-0123456789abcdef0.
  3. Delete it with aws ec2 delete-volume --volume-id vol-0123456789abcdef0.

See it fire on your bill.

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

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

472 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·