AMI削除時にスナップショットも自動で削除するCloudWatch Events

2016.02.16

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

コンニチハ、千葉です。

AMI削除するとき、スナップショットは削除されません。これに気付かず、スナップショットが残ると無駄な費用がかかってしまいます。また、削除する場合も手動で削除する必要があり、誤って必要なスナップショットを削除してしまったら大変です。

そんな時は、CloudWatch Eventsの出番です。 AMI登録解除のAPIをトリガーに、スナップショットを削除するLambdaファンクションをキックさせれば万事解決です。

Lambdaファンクションの作成

以下の様な感じで、Lambdaファンクションを作成します。

  • ランタイム:Python
  • ロール:EC2の操作権限があるロール
  • タイムアウト:実行に少し時間がかかるようなので、タイムアウト15秒

コードは以下です。

import boto3
import logging

logger = logging.getLogger()
logger.setLevel(logging.INFO)

def lambda_handler(event, context):
    try:
        client = boto3.client('ec2')
        imageID = event['detail']['requestParameters']['imageId']

        response = client.describe_snapshots(
            Filters=[
                {
                    'Name': 'description',
                    'Values': [
                        'Created by CreateImage(*) for ' + imageID + ' from *',
                    ]
                }
            ]
        )

        for i in response['Snapshots']:
            client.delete_snapshot(
                SnapshotId=i['SnapshotId']
                )

            logger.info("Delete target:" + i['SnapshotId'] + ", Description:" + i['Description'])

    except Exception as e:
        print(e)
        raise e

簡単に説明すると、

  • eventに登録解除したAMIのIDが入っていくるので取得
  • AMIのIDを元に、削除対象のスナップショット検索。検索方法は、DescriptionにAMIのIDが入っているので、そこでフィルタします。(初めて知ったのですが、フィルタに*を使うとワイルドカードになるようです)
  • 削除対象のスナップショットIDが取得できたので、繰り返し削除を行う

CloudWatch Eventsの設定

CloudWatch Eventsの設定を行います。トリガーはAMI登録解除AMIが実行されたタイミグ、実行は先程登録したLambdaファンクションを指定します。

delete-ami-and-snapshot-1

AMI削除時にスナップショットも削除されるかやってみた

testというAMIを削除します。

delete-ami-and-snapshot-2

AMIで使っているスナップショットは2つです。

delete-ami-and-snapshot-3

この状態でAMIの登録解除を実行してみます。

delete-ami-and-snapshot-4

ちゃんと削除されました。

delete-ami-and-snapshot-5

Lambdaの実行ログを確認しても、ちゃんと削除対象のスナップショットの2つが削除されています。

delete-ami-and-snapshot-6

まとめ

かなり地味な気がしないでもないですが、沢山AMIを利用される方には効果抜群な気もします。なるべく運用は楽にしたいものです。