Bagaimana cara membersihkan snapshot AWS EC2 yatim?

22

Kita berakhir dengan sejumlah besar snapshot AWS EC2 di mana AMI telah dihapus, tetapi snapshot tersebut ditinggalkan untuk membusuk. Saya ingin cara non-manual mengidentifikasi dan menghapus anak-anak yatim ini untuk menghemat uang dan ruang.

Idealnya saya sedang memikirkan skrip bash yang meningkatkan CLI , tetapi AWS-fu saya lemah. Saya berasumsi seseorang telah melakukan ini sebelumnya tetapi saya tidak dapat menemukan skrip yang benar-benar berfungsi.

Dalam skenario terbaik, ini juga akan memeriksa volume dan membersihkannya juga, tetapi itu mungkin lebih cocok untuk pertanyaan kedua.

Alex
sumber
Versi saya tentang python. Cara menggunakan dan tautan github
E.Big

Jawaban:

13

Sebagian besar terinspirasi oleh posting blog dan intisari sudah ditautkan dalam jawaban lain, di sini adalah saya mengambil masalah.

Saya memang menggunakan beberapa fungsi JMESpath yang berbelit-belit untuk mendapatkan daftar foto dan tidak perlu tr.

Penafian : Gunakan dengan risiko Anda sendiri , saya melakukan yang terbaik untuk menghindari masalah dan tetap waras, tetapi saya tidak akan bertanggung jawab jika itu menyebabkan masalah bagi Anda.

#!/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"

Saya harap skrip itu sendiri cukup dikomentari.

Penggunaan default (tanpa-params) akan mencantumkan perintah penghapusan snapshot yatim untuk akun saat ini dan wilayah eu-west-1, ekstrak:

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

Anda dapat mengarahkan output ini ke file untuk ditinjau sebelum mengambilnya untuk menjalankan semua perintah.

Jika Anda ingin skrip mengeksekusi perintah alih-alih mencetaknya, ganti print(cmd)dengan system(cmd).

Penggunaan adalah sebagai ikuti dengan skrip bernama snap_cleaner:

untuk perintah dry-run di wilayah us-west-1

./snap_cleaner no us-west-1

untuk perintah yang dapat digunakan di eu-central-1

./snap_cleaner IAMSURE eu-central-1 

Parameter ketiga dapat digunakan untuk mengakses akun lain (saya lebih suka untuk beralih peran ke akun lain sebelumnya).

Lepaskan versi skrip dengan skrip awk sebagai 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"
Tensibai
sumber
Luar biasa! Dan kecuali dari 'follow' (IMO yang seharusnya 'follow'), saya pikir jawaban ini harus dianggap sebagai sampel posting berkualitas tinggi. Satu-satunya hal di dalamnya yang tampaknya sedikit berlebihan, adalah penafian (apa pun yang digunakan seseorang dari sesuatu di situs SE dilengkapi dengan "gunakan dengan risiko Anda sendiri"). Saya hanya dapat memikirkan 1 peningkatan tambahan yang mungkin ingin Anda tambahkan: indikasi jika Anda memang menguji skrip ini dan jika demikian, bagaimana meringkas hasil pengujiannya (seperti "berfungsi seperti yang dirancang"?). Jelas, jika Anda sudah menggunakannya sendiri, itu indikasi yang lebih baik.
Pierre.Vriens
@pierre menulisnya pagi ini, diuji sebagian, mungkin akan memasuki saluran kami sore ini, dan sementara saya setuju pada gagasan umum 'disediakan sebagaimana adanya', tingkat risiko menghapus 'cadangan' tinggi dan saya merasa saya harus menekankannya bahkan lebih.
Tensibai
Hm, sehingga kami dapat membuat Anda terlibat untuk memulai layanan penulisan kode gratis untuk jenis kebutuhan DevOps ini (dengan beberapa pelepasan tanggung jawab hukum) ... menarik! Saya menyarankan agar nanti (ketika waktunya tepat), Anda menambahkan pembaruan kecil (di akhir) seperti " skrip saya memasuki saluran kami sore ini ".
Pierre.Vriens
@ Pierre.Vriens Saya katakan mungkin, bukan jaminan, bisa minggu depan atau lambat juga;)
Tensibai
1
Sempurna, terima kasih sudah mengedit! Bekerja persis seperti yang dimaksudkan.
Alex
5

Saya menggunakan skrip berikut di GitHub oleh Rodrigue Koffi (bonclay7) dan ini bekerja dengan sangat baik.

https://github.com/bonclay7/aws-amicleaner

Perintah:

amicleaner --check-orphans

Dari posting blog dokumentasi itu melakukan beberapa hal lagi:

Ini sebenarnya sedikit lebih dari itu, pada hari ini memungkinkan:

  • Menghapus daftar gambar dan foto terkait
  • Memetakan AMI:
    • Menggunakan nama
    • Menggunakan tag
  • Memfilter AMI:
    • digunakan dengan menjalankan instance
    • dari grup autoscaling (konfigurasi peluncuran) dengan kapasitas yang diinginkan diatur ke 0
    • dari konfigurasi peluncuran terlepas dari kelompok autoscaling
  • Tentukan berapa banyak AMI yang ingin Anda pertahankan
  • Membersihkan foto anak yatim
  • Sedikit pelaporan
Pengguna StackOverFlow
sumber
3

Berikut ini adalah satu skrip yang dapat membantu Anda menemukan foto-foto yatim

comm -23 <(echo $(ec2-describe-snapshots --region eu-west-1 | grep SNAPSHOT | awk '{print $2}' | sort | uniq) | tr ' ' '\n') <(echo $(ec2-describe-images --region eu-west-1 | grep BLOCKDEVICEMAPPING | awk '{print $3}' | sort | uniq) | tr ' ' '\n') | tr '\n' ' '

(dari sini )

Anda juga dapat memeriksa artikel ini dari serverfault

PS Tentu saja Anda dapat mengubah wilayah untuk mencerminkan Anda

PPS Berikut adalah kode yang diperbarui:

 comm -23 \
<(echo $(aws ec2 describe-snapshots --region eu-west-1 |awk '/SNAPSHOT/ {print $2}' | sort -u) | tr ' ' '\n') \
<(echo $(aws ec2 describe-images --region eu-west-1 |  awk '/BLOCKDEVICEMAPPING/ {print $3}' | sort -u) | tr ' ' '\n') | tr '\n' ' '

Contoh exaplanations yang dilakukan oleh kode:

echo $(aws ec2 describe-snapshots --region eu-west-1 | awk '/SNAPSHOT/ {print $2}' | sort -u) | tr ' ' '\n')

kirim ke STDOUT daftar foto. konstruksi ini:

<(...)

buat filehandler sementara virtual untuk membuat commperintah membaca dari dua "file" dan membandingkannya

Romeo Ninov
sumber
Apakah Anda mengujinya? Saya menemukan artikel yang sama tetapi tidak dapat membuatnya berfungsi. Jika Anda bisa, kesalahan pengguna di pihak saya, tapi saya khawatir itu mungkin sudah ketinggalan zaman berdasarkan usia artikel.
Alex
@Alex, dapat memeriksanya besok
Romeo Ninov
Perintah see telah berubah, gunakan aws ec2 mendeskripsikan / menghapus
Tensibai
1
Saya memang menemukan sumber yang sama, tetapi chaining hero awk sort dan uniq membuat sisi coder shell saya sedih, saya akan memposting versi saya besok :)
Tensibai
1
Baik untuk saya, hanya ingin memberikan Anda beberapa umpan balik (konstruktif) agar Anda tahu bahwa apa yang mungkin terlihat seperti bahasa Inggris biasa untuk seorang ahli (seperti Anda), terlihat sangat mirip dengan Cina bagi saya, oke? PS: dan kedengarannya tidak Flemish juga ... Berikan saya komentar tambahan jika Anda ingin memberi tahu saya setelah Anda selesai (jika Anda ingin umpan balik saya yang diperbarui).
Pierre.Vriens
2

Berikut ini cuplikan kode GitHub Gist dari apa yang Anda minta oleh Daniil Yaroslavtsev.

Ini menggunakan daftar semua gambar dan snapshot mereka dan membandingkan ID untuk daftar semua ID snapshot. Apa pun yang tersisa adalah yang yatim piatu. Kode ini bekerja dengan prinsip yang sama dengan jawaban di atas, tetapi lebih baik diformat dan sedikit lebih mudah dibaca.

Kode mengambil keuntungan dari opsi JMESPath dengan --query Snapshots[*].SnapshotId(Anda juga dapat menggunakan utilitas baris perintah jp untuk itu, jika sudah dalam distribusi Anda. Format output sebagai teks dengan --output text. Berikut adalah tautan ke referensi API dan beberapa contoh. Ini sedikit lebih elegan dari rantai panjang pipa grep / awk / sort / uniq / tr.

Peringatan oleh Todd Walton : Jangan salah dengan utilitas 'jq' yang menggunakan bahasa kueri yang berbeda untuk mem-parsing dokumen json.

Jiri Klouda
sumber
Hanya FYI, utilitas baris perintah jq bukan bahasa kueri JSON yang sama dengan apa yang digunakan perintah "aws". Perintah "aws" menggunakan JMESPath.
Todd Walton
Terima kasih telah menunjukkannya. Saya telah belajar sesuatu yang baru hari ini.
Jiri Klouda
0

Saya telah menulis skrip snapshots.py yang mengulang semua snapshot (dalam daftar wilayah yang ditentukan) dan menghasilkan report.csv. File ini berisi informasi tentang instance, AMI dan volume yang dirujuk oleh semua snapshot.

Ada juga perintah untuk secara interaktif menghapus snapshot yang menjuntai.

omong kosong
sumber