Lambda 不要なAMIを定期削除する

開発中、テスト用の環境にデプロイするたびにAMIを自動取得していたら、不要なAMIが山のようになってしまったので掃除をする。

以前作成したこちらの記事のLambdaを元に、不要なAMIを定期的に削除するようにしてみます。
Lambda 不要なAMIとスナップショットをまとめて削除する

従来の方法(手動実行用)

元のLambda関数では下記のように、削除対象のAMIを手打ちして、eventから取得していました。

{
    "delete_amis": [
        "ami-0123456789abcdef1",
        "ami-0123456789abcdef2",
        "ami-0123456789abcdef3"
    ]
}
def lambda_handler(event, context):
    delete_amis = event['delete_amis']
    print(delete_amis)

    for delete_ami in delete_amis:
        # Delete AMI.
        unregister_ami(delete_ami)
    
        # Delete Snapshots.
        delete_related_snapshots(delete_ami)
    
    return

今回の方法(自動実行用)

  1. 現在所有しているAMIの一覧から、適当なフィルターをかけつつ一部を取得します。
    • Filtersを指定しなかったり、Filters=[{'Name': 'name', 'Values': ['*']}]のように全指定すると、describe_images()からのレスポンスが非常に遅くなるので注意。
  2. AMIの作成日部分を取得して、一週間以上古いものというざっくり基準で削除対象のリストに放り込みます。
    (リスト内包表記となぜか実行時間が変わらなかったので、可読性がヤバいことになるのを避けるためにappendで書いています)
  3. 削除対象となったAMI-IDのリストを元に、以前作成したAMI+Snapshotの削除処理を実行します。
def get_old_ami():
    # Describe target AMIs.
    try:
        response = ec2.describe_images(
            Filters=[{'Name': 'name', 'Values': ['delete-sample*']}]
        )
        if response.get('ResponseMetadata', {}).get('HTTPStatusCode', -1) != 200:
            raise('# Cannot describe images!')
        images = response.get('Images')
        print('# All delete-sample images:', len(images))
    except ClientError as e:
        print(e.response['Error']['Code'])
        print(e.response['Error']['Message'])
        logging.error("# Describe images error: %s", e)
        return
    
    seven_days = 604800
    old_images = []
    epoc_now = int(time.time())
    print('# epoc now:', epoc_now)
    
    # Those older than 7 days are subject to deletion.
    for image in images:
        creation_date = image.get('CreationDate')
        datetime = dt.strptime(creation_date, "%Y-%m-%dT%H:%M:%S.000Z")
        epoc_datetime = int(dt.timestamp(datetime))

        if epoc_now - epoc_datetime > seven_days:
            old_images.append(image.get('ImageId'))

    return old_images
def lambda_handler(event, context):
    # Get the AMI to be deleted.
    delete_amis = get_old_ami()
    print('# Target AMIs:', len(delete_amis))
    print(delete_amis)

    for delete_ami in delete_amis:
        # Delete AMI.
        unregister_ami(delete_ami)
    
        # Delete Snapshots.
        delete_related_snapshots(delete_ami)
    
    return

定期実行

トリガーにEventBridgeを指定し、cron式でスケジュールを設定しました。
JSTで「火~土 AM00:00」に実行したい場合、下記のように指定します。

cron(0 15 ? * MON-FRI *)
カテゴリーAWS

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です