I’ve been cleaning up a lot of AWS resources lately and thought I would share a couple of commands that I use for cleaning up EBS volumes.

I started with a command that would lookup up the volumes in a specific region that were older than 3 days:

aws ec2 describe-volumes --region us-east-2 --filters "Name=status,Values=available" \
  --query "Volumes[?CreateTime<='$(date -v -3d +%Y-%m-%d)'].VolumeId" \
  --output text        

I quickly got tired of doing it for every region that we have resources in, so I created a snippet that looked up the regions and then described the available volumes in all of them.

for region in `aws ec2 describe-regions --output text | cut -f 2|cut -d . -f 2`;
do 
echo "-- $region"; 
aws ec2 describe-volumes --region $region --filters "Name=status,Values=available" \
	--query "Volumes[?CreateTime<='$(date -v -3d +%Y-%m-%d)'].VolumeId" \
	--output text        
	echo ;
done

Just displaying the volumes doesn’t really help to save costs, so I came up with commands to delete available volumes from a specific region:

for a in `aws ec2 describe-volumes \
	--region us-east-2 \
	--filters "Name=status,Values=available" \
    --query "Volumes[?CreateTime<='$(date -v -3d +%Y-%m-%d)'].VolumeId" \
	--output text`
do
	echo "Deleting $a..."
	aws ec2 delete-volume --region $region -volume-id $a
done        

as well as for deleting them in all regions:

for region in `aws ec2 describe-regions --output text | cut -f 2|cut -d . -f 2`;
do 
echo "-- $region"; 
	for a in `aws ec2 describe-volumes \
		--region $region \
		--filters "Name=status,Values=available" \
    --query "Volumes[?CreateTime<='$(date -v -3d +%Y-%m-%d)'].VolumeId" \
		--output text`
	do
		echo "Deleting $a..."
		aws ec2 delete-volume --region $region --volume-id $a
	done        
echo ;
done

Since we have different retention periods for production and non-production resources, I decided to write a shell function that I could pass the number of days I want to be older than:

aws-av() {
  if [ -z "$1" ]; then
   echo "Need to include the number of days to list"
  else
    for region in `aws ec2 describe-regions --output text | cut -f 2|cut -d . -f 2`;
    do
      echo "-- $region";
        aws ec2 describe-volumes --region $region --filters "Name=status,Values=available" \
          --query "Volumes[?CreateTime<='$(date -v -${1}d +%Y-%m-%d)'].VolumeId" \
          --output text
      echo ;
    done
  fi
}

I did the same thing for the actual deletion:

aws-avc() {
  if [ -z "$1" ]; then
   echo "Needs number of days old to clean up"
  else
    for region in `aws ec2 describe-regions --output text | cut -f 2|cut -d . -f 2`;
    do
      echo "-- $region";
      for a in `aws ec2 describe-volumes \
        --region $region \
        --filters "Name=status,Values=available" \
        --query "Volumes[?CreateTime<='$(date -v -${1}d +%Y-%m-%d)'].VolumeId" \
        --output text`
      do
        echo "Deleting $a..."
        aws ec2 delete-volume --region $region --volume-id $a
      done
      echo ;
    done
  fi
}

These commands can help you quickly view and cleanup unused EBS resources.