Blog yazılarından büyük ölçüde esinlenilmiş ve diğer cevaplarla zaten bağlantılı olan özü, işte benim sorunum.
Bazı anlık JMESpath işlevlerini, anlık görüntülerin bir listesini almak için kullandım ve gerektirmedik tr.
Feragatname : Kendi risklerinizde kullanın, herhangi bir sorunu önlemek ve aklı başında olmak için elimden gelenin en iyisini yapmak için elimden gelenin en iyisini yaptım, ama eğer sana soruna neden olursa suçlamayacağım.
#!/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"
Umarım betiğin kendisi yeterince yorumlanır.
Varsayılan kullanım (param olmadan), cari hesap ve bölge eu-west-1 için artık anlık görüntülerin silme komutlarını listeler:
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
Tüm komutları yürütmek için kaynak göstermeden önce bu çıktıyı incelenmek üzere bir dosyaya yönlendirebilirsiniz.
Eğer komut yerine onları baskı komutunu çalıştırmak istiyorsanız, yerine print(cmd)göre system(cmd).
Kullanımı şu adında bir script ile takip edilir snap_cleaner:
us-west-1 bölgesindeki kuru komutlar için
./snap_cleaner no us-west-1
eu-central-1'de kullanılabilir komutlar için
./snap_cleaner IAMSURE eu-central-1
Başka bir hesaba erişmek için üçüncü bir parametre kullanılabilir (Daha önce bir hesaba rol değiştirmeyi tercih ederim).
Bir oneliner olarak awk betiği ile betiğin çıkarılmış sürümü:
#!/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"