孤立したAWS EC2スナップショットをクリーンアップする方法は?


22

AMIが削除されたAWS EC2スナップショットはかなりの量になりますが、スナップショットは腐敗したままです。お金とスペースを節約するために、これらの孤児を特定して削除する非手動の方法が欲しい

理想的には、CLIを活用するbashスクリプトを考えていますが、AWS-fuは弱いです。誰かがこれをやったことがあると思いますが、実際に動作するスクリプトは見つかりません。

最良のシナリオでは、これもボリュームをチェックし、それらをクリーンアップしますが、2番目の質問により適している場合があります。


Pythonでの私のバージョン。使用方法とgithubリンク
E.Big

回答:


13

ブログの投稿と他の回答で既にリンクされている要点から大いに影響を受けましたが、ここで問題に対する私の見解を示します。

いくつかの複雑なJMESpath関数を使用して、スナップショットのリストを取得しましたtr

免責事項自己責任で使用してください。問題を回避し、健全なデフォルトを維持するために最善を尽くしましたが、問題が発生した場合でも責任を負いません。

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

スクリプト自体が十分にコメントされていることを願っています。

デフォルトの使用法(no-params)は、現在のアカウントとリージョンeu-west-1の孤立したスナップショットの削除コマンドを一覧表示します。

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

この出力をレビュー用にファイルにリダイレクトしてから、すべてのコマンドを実行するように仕向けることができます。

スクリプトではなく、それらを印刷するコマンドを実行したい場合は、交換してくださいprint(cmd)によるsystem(cmd)

スクリプトの使用方法は次のsnap_cleanerとおりです。

us-west-1リージョンでの予行演習用

./snap_cleaner no us-west-1

eu-central-1で使用可能なコマンド

./snap_cleaner IAMSURE eu-central-1 

3番目のパラメーターを使用して、別のアカウントにアクセスできます(以前に別のアカウントにロールを切り替えることを好みます)。

ワンライナーとしてawkスクリプトを使用したスクリプトのバージョンを削除しました。

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

素晴らしい!そして、「フォロー」(IMOは「フォロー」である必要があります)を除き、この回答は質の高い投稿のサンプルと見なされるべきだと思います。その中で少し冗長に見える唯一のものは免責事項です(SEサイトで使用するものには「自分の責任で使用する」が付属しています)。場合の表示を:私はあなたが追加したい場合があります1点の、追加の改善を考えることができますが、テストにこのスクリプトを行なったし、もしそうならどのように(「設計どおりの作品」のようなものを?)そのテスト結果を要約します。明らかに、すでに自分で使用している場合は、それがさらに良い兆候です。
Pierre.Vriens

@pierreは今朝それを書いて、部分的にテストし、おそらく今日の午後にパイプラインに入るでしょう。そして、「そのまま」という一般的な考えに同意しますが、「バックアップ」を削除するリスクレベルは高く、私はそれを強調すべきだと感じますさらに。
テンシバイ

ええと、このような種類のDevOpsのニーズ(免責事項の文字列を添付)に対応する無料のコード作成サービスを開始するために、あなたを関与させることができます... 後で(時間が適切な場合)、「私のスクリプトが今日の午後にパイプラインに入った」などのマイナーアップデートを(最後に)追加することをお勧めします。
Pierre.Vriens

@ Pierre.Vriensおそらく、保証ではなく、来週以降になるかもしれないと言った;)
Tensibai

1
編集に感謝します!意図したとおりに動作します。
アレックス

5

Rodrigue Koffi(bonclay7)のGitHubで次のスクリプトを使用しましたが、かなりうまく機能します。

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

コマンド:

amicleaner --check-orphans

ドキュメントのブログ投稿から、さらにいくつかのことが行われます。

それは実際にはそれ以上のことをします、今日ではそれが可能です:

  • イメージと関連するスナップショットのリストを削除する
  • AMIのマッピング:
    • 名前を使用する
    • タグを使用する
  • AMIのフィルタリング:
    • 実行中のインスタンスが使用
    • 必要な容量を0に設定した自動スケーリンググループ(起動構成)から
    • 自動スケーリンググループから切り離された起動構成から
  • 保持するAMIの数を指定する
  • 孤立したスナップショットのクリーニング
  • 少しの報告

3

以下は、孤立したスナップショットを見つけるのに役立つスクリプトです。

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' ' '

ここから)

また、serverfaultからこの記事を確認できます

PSもちろん、あなたの地域を反映するように地域を変更することができます

PPSここに更新されたコードがあります:

 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' ' '

コードが実行するサンプルの説明は次のとおりです。

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

スナップショットのリストをSTDOUTに送信します。この構造:

<(...)

仮想一時ファイルハンドラを作成して、commコマンドを2つの「ファイル」から読み取って比較します


テストしましたか?同じ記事を見つけましたが、機能しません。できれば、私の側のユーザーエラーですが、記事の年齢に基づいて時代遅れになる可能性があります。
アレックス

@アレックス、明日確認できます
ロミオ・ニノフ

コマンドが変更されている参照して、使用AWSは説明EC2 /削除
Tensibai

1
私は同じソースを見つけましたが、ヒーローawk sortとuniqを連結するとシェルコーダー側が悲しくなります。明日バージョンを投稿します:)
Tensibai

1
私にとっては、(建設的な)フィードバックを提供して、専門家(おそらくあなた)にとって通常の英語のように見えるものが、私にとっては中国人のように見えることを知らせたいだけです。PS:フラマン語にも聞こえない...完了後に通知する場合は、追加のコメントをお送りください(更新されたフィードバックが必要な場合)。
Pierre.Vriens

2

これは、Daniil Yaroslavtsevがまさに求めているGitHub Gistコードスニペットです。

すべてのイメージとそのスナップショットのリストを使用し、IDをすべてのスナップショットIDのリストと比較します。残っているのは、孤立したものです。コードは上記の答えと同じ原理で機能しますが、より適切にフォーマットされており、少し読みやすくなっています。

コードは--query Snapshots[*].SnapshotIdオプション付きのJMESPathを利用し ます(すでにディストリビューションにある場合は、jpコマンドラインユーティリティも使用できます。出力をテキストとしてフォーマットします。APIリファレンスへ--output textリンクといくつかの例です。 grep / awk / sort / uniq / trパイプの長いチェーンよりもエレガントです。

Todd Waltonによる警告:jsonドキュメントを解析するために異なるクエリ言語を使用する「jq」ユーティリティと間違えないでください。


ちょうどFYI、JQコマンドラインユーティリティはありませんどのような「AWS」コマンドの使用と同じJSONクエリ言語。「aws」コマンドはJMESPathを使用します。
トッドウォルトン

ご指摘いただきありがとうございます。今日は何か新しいことを学びました。
ジリクルダ

0

定義済みのリージョンリスト内のすべてのスナップショットを反復処理して生成するsnapshots.pyスクリプトを記述しましたreport.csv。このファイルには、すべてのスナップショットによって参照されるインスタンス、AMI、およびボリュームに関する情報が含まれています。

ダングリングスナップショットをインタラクティブに削除するコマンドもあります。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.