Shashi B
Shashi B

Reputation: 135

Delete older than month AWS EC2 snapshots

Is this below given command will work or not to delete older than month AWS EC2 Snapshot.

aws describe-snapshots | grep -v (date +%Y-%m-) | grep snap- | awk '{print $2}' | xargs -n 1 -t aws delete-snapshot

Upvotes: 7

Views: 26115

Answers (4)

bhargav joshi
bhargav joshi

Reputation: 482

Date condition must be within Parenthesis ()

aws ec2 describe-snapshots \
    --owner-ids 012345678910 \
    --query "Snapshots[?(StartTime<='2020-03-31')].[SnapshotId]"

Upvotes: 0

once
once

Reputation: 1399

you can use 'self' in '--owner-ids' and delete the snapshots created before a specific date (e.g. 2018-01-01) with this one-liner command:

for i in $(aws ec2 describe-snapshots --owner-ids self --query 'Snapshots[?StartTime<=`2018-01-01`].SnapshotId' --output text); do echo Deleting $i; aws ec2 delete-snapshot --snapshot-id $i; sleep 1; done;

Upvotes: 3

Roman Zhuzha
Roman Zhuzha

Reputation: 664

Your command won't work mostly because of a typo: aws describe-snapshots should be aws ec2 describe-snapshots.

Anyway, you can do this without any other tools than aws:

snapshots_to_delete=$(aws ec2 describe-snapshots --owner-ids xxxxxxxxxxxx --query 'Snapshots[?StartTime<=`2017-02-15`].SnapshotId' --output text)
echo "List of snapshots to delete: $snapshots_to_delete"

# actual deletion
for snap in $snapshots_to_delete; do
  aws ec2 delete-snapshot --snapshot-id $snap
done

Make sure you always know what are you deleting. By echo $snap, for example.
Also, adding --dry-run to aws ec2 delete-snapshot can show you that there are no errors in request.


Edit:

There are two things to pay attention at in the first command:

  1. --owner-ids - you account unique id. Could easily be found manually in top right corner of AWS Console: Support->Support Center->Account Number xxxxxxxxxxxx

  2. --query - JMESPath query which gets only snapshots created later than specified date (e.g.: 2017-02-15): Snapshots[?StartTime>=`2017-02-15`].SnapshotId

Upvotes: 23

WEBjuju
WEBjuju

Reputation: 6581

+1 to @roman-zhuzha for getting me close. i did have trouble when $snapshots_to_delete didn't parse into a long string of snapshots separated by whitespaces.

this script, below, does parse them into a long string of snapshot ids separated by whitespaces on my Ubuntu (trusty) 14.04 in bash with awscli 1.16:

#!/usr/bin/env bash

dry_run=1
echo_progress=1

d=$(date +'%Y-%m-%d' -d '1 month ago')
if [ $echo_progress -eq 1 ]
then
  echo "Date of snapshots to delete (if older than): $d"
fi

snapshots_to_delete=$(aws ec2 describe-snapshots \
    --owner-ids xxxxxxxxxxxxx \
    --output text \
    --query "Snapshots[?StartTime<'$d'].SnapshotId" \
)
if [ $echo_progress -eq 1 ]
then
  echo "List of snapshots to delete: $snapshots_to_delete"
fi


for oldsnap in $snapshots_to_delete; do

  # some $oldsnaps will be in use, so you can't delete them
  # for "snap-a1234xyz" currently in use by "ami-zyx4321ab"
  # (and others it can't delete) add conditionals like this

  if [ "$oldsnap" = "snap-a1234xyz" ] ||
     [ "$oldsnap" = "snap-c1234abc" ]
  then
    if [ $echo_progress -eq 1 ]
    then
       echo "skipping $oldsnap known to be in use by an ami"
    fi
    continue
  fi

  if [ $echo_progress -eq 1 ]
  then
     echo "deleting $oldsnap"
  fi

  if [ $dry_run -eq 1 ]
  then
    # dryrun will not actually delete the snapshots
    aws ec2 delete-snapshot --snapshot-id $oldsnap --dry-run
  else
    aws ec2 delete-snapshot --snapshot-id $oldsnap
  fi
done

Switch these variables as necesssary:

dry_run=1           # set this to 0 to actually delete
echo_progress=1     # set this to 0 to not echo stmnts

Change the date -d string to a human readable version of the number of days, months, or years back you want to delete "older than":

d=$(date +'%Y-%m-%d' -d '15 days ago')  # half a month

Find your account id and update these XXXX's to that number:

    --owner-ids xxxxxxxxxxxxx \

Here is an example of where you can find that number:

enter image description here


If running this in a cron, you only want to see errors and warnings. A frequent warning will be that there are snapshots in use. The two example snapshot id's (snap-a1234xyz, snap-c1234abc) are ignored since they would otherwise print something like:

An error occurred (InvalidSnapshot.InUse) when calling the DeleteSnapshot operation: The snapshot snap-a1234xyz is currently in use by ami-zyx4321ab

See the comments near "snap-a1234xyx" example snapshot id for how to handle this output.


And don't forget to check on the handy examples and references in the 1.16 aws cli describe-snapshots manual.

Upvotes: 4

Related Questions