AMIと紐付けのないスナップショットをCloudShellで一括削除してみた。

AMIの解除後、課金継続状態で残ったままのEBSスナップショットをCloudShellで一括削除してみました。
2022.05.22

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

EC2のAMI(Amazon Machine Image)、EBSスナップショットのストレージ費用の実費で利用できますが、 不要となったAMIを撤去する際には、AMIの登録解除と、EBSスナップショットの削除をそれぞれ行う必要があります。

今回、AWSのマネージメントコンソール上でCloudShellを利用して、 AMIの登録解除に残ったEBSスナップショットの特定、確認、削除の操作を行う機会がありましたので、紹介させていただきます。

CloudShell

AWSマネジメントコンソールで、「サービス」→「開発ツール」→「CloudShell」を利用しました。

AWSCLIは、CloudShellのデフォルトを利用しました。

$ aws --version
aws-cli/2.7.0 Python/3.9.11 Linux/4.14.275-207.503.amzn2.x86_64 exec-env/CloudShell exe/x86_64.amzn.2 prompt/off

手順

EBSスナップショットIDを取得

aws ec2 describe-snapshots \
  --owner-ids self \
  --region=${AWS_REGION} \
  --filters "Name=description,Values=*ami-*" "Name=storage-tier,Values=standard" \
  --query 'Snapshots[].[SnapshotId]' \
  --output text \
  | sort > snapshot.txt
  • 自身が保有、CLIの実行リージョンに存在するスナップショットを対象としました。
  • フィルタ指定を行い、descriptionの記述に「ami-」を含み、標準ティアのスナップショットを抽出しました。
  • 出力は改行区切りのテキスト、commコマンドを利用した差分比較のため、ソートしました。

一定数(数万以上)のスナップショットが存在するアカウントでCloudShellのメモリ不足となる場合、より多くのメモリが利用可能なEc2などの実行環境をお試しください。

AMIで利用中のスナップショットIDを取得

aws ec2 describe-images \
  --owners self \
  --region=${AWS_REGION} \
  --query "Images[].BlockDeviceMappings[].Ebs.[SnapshotId]" \
  --output text \
  | sort > ami-snapshot.txt
  • 自身が保有するAMI情報より、スナップショットIDを取得します。
  • commコマンドを利用した差分比較のため、ソートを行います。

AMIで利用されていないスナップショットIDの取得

comm -23 snapshot.txt ami-snapshot.txt
  • 「comm」コマンドで、自身が保有するEBSスナップショットのIDとから、AMIに含まれるスナップショットIDの差分を比較。

実行例

$ comm -23 snapshot.txt ami-snapshot.txt
snap-xxxxxxxxxxxxxxxxx

識別用のタグ付け

AMIに紐付けのないスナップショットを対象に、識別用のタグを付与しました。

TagKey="cm-no-ami-link"
TagValue=`date '+%Y%m%d'`
comm -23 snapshot.txt ami-snapshot.txt | while read ID
do
  echo ${ID}
  aws ec2 create-tags --resources ${ID} --tags "Key=${TagKey},Value=${TagValue}"
done

対象確認

識別用のタグを利用し、AMIに紐付けのないスナップショットの確認を行いました。

CLI

aws ec2 describe-snapshots \
  --owner-ids self \
  --region=${AWS_REGION} \
  --filters Name=tag:${TagKey},Values=${TagValue} \
  --query 'Snapshots[].[SnapshotId,VolumeId,VolumeSize,StartTime,Description]' \
  --output text

snap-xxxx  vol-ffffffff    8       2022-05-19T14:59:24.415000+00:00        Created by CreateImage(i-xxxx) for ami-xxxx from vol-xxxx

GUI

Ec2ダッシュボードで、識別用のタグ(キー、値)を指定、AMIに紐付けのないスナップショットの詳細を確認しました。

スナップショット削除

識別タグを利用して、EBSスナップショットの削除を行いました。

TagKey="cm-no-ami-link"
TagValue=`date '+%Y%m%d'`
aws ec2 describe-snapshots \
  --owner-ids self \
  --region=${AWS_REGION} \
  --filters Name=tag:${TagKey},Values=${TagValue} \
  --query 'Snapshots[].[SnapshotId]' \
  --output text | while read ID
do
  echo ${ID}
  aws ec2 delete-snapshot --snapshot-id ${ID} --no-dry-run
done

まとめ

AWSリソースの棚卸しなどで、登録解除されたAMIで利用されていた多数のスナップショットが発覚、 一斉撤去が必要な場合に今回の手順をお試しください。

2021年にサポートされたEBSスナップショットのゴミ箱機能を利用する事で、猶予期間を設ける事が可能です。 AMI以外でEBSスナップショットが利用されている可能性がある場合、一斉削除の切り戻しを可能とするため一定の猶予期間を設ける利用をおすすめします。

また、AMIと紐付けのないスナップショットが発生しやすい環境の場合、 EBSスナップショットの削除を行うLambda関数を用意いただき、AMIの削除をEvent Bridge(CloudWatch Event)で検出、 自動削除を実現する利用もお試しください。