Medical physicist
Medical physicist

Reputation: 2594

Delete the oldest AWS EC2 snapshots

I'm trying to remove all my AWS EC2 snapshots except the last 6 with this script:

#!/bin/bash
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games

# Backup script

Volume="{VOL-DATA}"
Owner="{OWNER}"
Description="{DESCRIPTION}"
Local_numbackups=6
Local_region="us-west-1"

# Remove old snapshots associated to a description, keep the last $Local_numbackups
aws ec2 describe-snapshots --filters Name=description,Values=$Description | grep "SnapshotId" | head -n -$Local_numbackups | awk '{print $2}' | sed -e 's/,//g' | xargs -n 1 -t aws ec2 delete-snapshot --snapshot-id

However it doesn't work. It deletes instances, but not the oldest ones. Why?

Upvotes: 1

Views: 4359

Answers (3)

Karen B
Karen B

Reputation: 2763

You're trying to do something too complex to be handled (gracefully) in one line, so we'll need to break it down a bit. First, let's get the snapshots sorted by age, oldest to newest:

aws ec2 describe-snapshots --filters Name=description,Values=$Description --query 'Snapshots[*].[StartTime,SnapshotId]' --output text | sort -n

Then we can drop the StartTime field to get the snapshot ID alone:

aws ec2 describe-snapshots --filters Name=description,Values=$Description --query 'Snapshots[*].[StartTime,SnapshotId]' --output text | sort -n | sed -e 's/^.*\t//'

head (or tail) aren't really suitable for discarding the fixed number of snapshots we want to keep. We need to filter those out another way. So, putting it altogether:

# Get array of snapshot IDs sorted by age (oldest to newest)
snapshots=($(aws ec2 describe-snapshots --filters Name=description,Values=$Description --query 'Snapshots[*].[StartTime,SnapshotId]' --output text | sort -n | sed -e 's/^.*\t//'))
# Get number of snapshots
count=${#snapshots[@]}

if [ "$count" -lt "$Local_numbackups" ]; then
  echo "We already have less than $Local_numbackups snapshots"
  exit 0
else
  # Drop the last (newest) $Local_numbackups IDs from the array
  snapshots=(${snapshots[@]:0:$((count - Local_numbackups))})
  # Loop through the remaining snapshots and delete
  for snapshot in ${snapshots[@]}; do
    aws ec2 delete-snapshot --snapshot-id $snapshot
  done
fi

(While it's obviously possible to do this in bash with the AWS CLI, it's complex enough that I'd personally rather use a more robust language and the AWS SDK.)

Upvotes: 2

Ajay Trivedi
Ajay Trivedi

Reputation: 87

We can delete all old snapshots using below steps:-

  • List out all snapshots ID's they are old and put in one file like:- /opt/snapshot.txt

  • And then use "aws configure" command for setup access AWS account from command line, at this time we need to provide credentials:-

Such as:

AWS Access Key ID [None]: XXXXXXXXXXXXXXXXXX    
AWS Secret Access Key [None]: XXXXXXXXXXXXXXXXXXXXX    
Default region name [None]: XXXXXXXXXXXXXXXX
  • After that we can use below shell script, we need to give snapshots ID's file name

Codes:

#!/bin/bash 

list=$(cat /opt/snapshot.txt) 

for i in $list 

do 

   aws ec2 delete-snapshot --snapshot-id $i 

   if [ $? -eq 0 ]; then 

     echo Going Good 

   else 

     echo FAIL 

   fi 

done

Thanks

Upvotes: 0

Rags Kinnigoly
Rags Kinnigoly

Reputation: 21

Here is a sample.

  days2keep="30"
  region="us-west-2"
  name="jdoe"

  #date - -v is for Osx

  cutoffdate=`date -j -v-${days2keep}d '+%Y-%m-%d'`

  echo "Finding list of snapshots before $cutoffdate "
  oldsnapids=$(aws ec2 describe-snapshots --region $region --filters Name=tag:Name,Values=$name --query Snapshots[?StartTime\<=\`$cutoffdate\`].SnapshotId --output text)

  for snapid in $oldsnapids
  do
    echo Deleting snapshot $snapid
    aws ec2 delete-snapshot --snapshot-id $snapid --region $region
  done

Upvotes: 2

Related Questions