Weitgehend inspiriert von den Blog-Beiträgen und dem Inhalt der anderen Antworten, hier ist meine Sicht auf das Problem.
Ich habe einige verschachtelte JMESpath- Funktionen verwendet, um eine Liste von Schnappschüssen zu erhalten, die nicht erforderlich sind tr
.
Haftungsausschluss : Die Verwendung erfolgt auf eigenes Risiko . Ich habe mein Bestes getan, um Probleme zu vermeiden und vernünftige Standardeinstellungen beizubehalten. Ich übernehme jedoch keine Schuld, wenn es Ihnen Probleme bereitet.
#!/bin/sh
# remove x if you don't want to see the commands
set -ex
# Some variable initialisation with sane defaults
DRUN='--dry-run'
DO_DELETE=${1:-'no'}
REGION=${2:-'eu-west-1'}
ACCOUNTID=${3:-'self'}
# Get two temporary files
SNAP_FILE=$(mktemp)
IMAGE_FILE=$(mktemp)
# Get the snapshot list and the volume list
aws --region "$REGION" ec2 describe-snapshots --owner-ids "$ACCOUNTID" --query 'Snapshots[*].[SnapshotId]' --output text > "$SNAP_FILE"
aws --region "$REGION" ec2 describe-images --owners "$ACCOUNTID" --filters Name=state,Values=available --query 'Images[*].BlockDeviceMappings[*].Ebs.[SnapshotId]' --output text > "$IMAGE_FILE"
# Check if the outputed command should be dry-run (default) or not
if [ "$DO_DELETE" = "IAMSURE" ]
then
DRUN=''
fi
# count each snapshot id, decrease when a volume reference it, print delete command for those with no volumes
awk -v REGION="$REGION" -v DRUN="$DRUN" '
FNR==NR { snap[$1]++; next } # increment snapshots and get to next line in file immediately
{ snap[$1]-- } # we changed file, decrease the snap counter when a volume reference it
END {
for (s in snap) { # loop over the snapshots
if (snap[s] > 0) { # if we did not decrese under 1 that means there is no volume referencing this snapshot
cmd="aws --region " REGION " " DRUN " ec2 delete-snapshot --snapshot-id " s
print(cmd)
}
}
}
' "$SNAP_FILE" "$IMAGE_FILE"
# Clean up the temp files
rm "$SNAP_FILE" "$IMAGE_FILE"
Ich hoffe, das Skript selbst ist genug kommentiert.
Die Standardverwendung (ohne Parameter) listet Löschbefehle für verwaiste Snapshots für das aktuelle Konto und die Region eu-west-1 auf.
aws --region eu-west-1 --dry-run ec2 delete-snapshot --snapshot-id snap-81e5856a
aws --region eu-west-1 --dry-run ec2 delete-snapshot --snapshot-id snap-95c68c7e
aws --region eu-west-1 --dry-run ec2 delete-snapshot --snapshot-id snap-a3bf50bd
Sie können diese Ausgabe zur Überprüfung in eine Datei umleiten, bevor Sie alle Befehle ausführen.
Wenn Sie möchten, dass das Skript den Befehl ausführt, anstatt ihn zu drucken, ersetzen Sie ihn print(cmd)
durch system(cmd)
.
Die Verwendung ist wie folgt mit einem Skript namens snap_cleaner
:
für trockenlaufbefehle in der region us-west-1
./snap_cleaner no us-west-1
für verwendbare Befehle in eu-central-1
./snap_cleaner IAMSURE eu-central-1
Ein dritter Parameter kann verwendet werden, um auf ein anderes Konto zuzugreifen (ich bevorzuge es, die Rolle zu einem anderen Konto zu wechseln).
Reduzierte Version des Skripts mit awk-Skript als Oneliner:
#!/bin/sh
set -ex
# Some variable initialisation with sane defaults
DRUN='--dry-run'
DO_DELETE=${1:-'no'}
REGION=${2:-'eu-west-1'}
ACCOUNTID=${3:-'self'}
# Get two temporary files
SNAP_FILE=$(mktemp)
IMAGE_FILE=$(mktemp)
# Get the snapshot list and the volume list
aws --region "$REGION" ec2 describe-snapshots --owner-ids "$ACCOUNTID" --query 'Snapshots[*].[SnapshotId]' --output text > "$SNAP_FILE"
aws --region "$REGION" ec2 describe-images --owners "$ACCOUNTID" --filters Name=state,Values=available --query 'Images[*].BlockDeviceMappings[*].Ebs.[SnapshotId]' --output text > "$IMAGE_FILE"
# Check if the outputed command should be dry-run (default) or not
if [ "$DO_DELETE" = "IAMSURE" ]
then
DRUN=''
fi
# count each snapshot id, decrease when a volume reference it, print delete command for those with no volumes
awk -v REGION="$REGION" -v DRUN="$DRUN" 'FNR==NR { snap[$1]++; next } { snap[$1]-- } END { for (s in snap) { if (snap[s] > 0) { cmd="aws --region " REGION " " DRUN " ec2 delete-snapshot --snapshot-id " s; print(cmd) } } }' "$SNAP_FILE" "$IMAGE_FILE"
# Clean up the temp files
rm "$SNAP_FILE" "$IMAGE_FILE"