開発中、テスト用の環境にデプロイするたびに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
今回の方法(自動実行用)
- 現在所有しているAMIの一覧から、適当なフィルターをかけつつ一部を取得します。
- Filtersを指定しなかったり、
Filters=[{'Name': 'name', 'Values': ['*']}]
のように全指定すると、describe_images()
からのレスポンスが非常に遅くなるので注意。
- Filtersを指定しなかったり、
- AMIの作成日部分を取得して、一週間以上古いものというざっくり基準で削除対象のリストに放り込みます。
(リスト内包表記となぜか実行時間が変わらなかったので、可読性がヤバいことになるのを避けるためにappendで書いています) - 削除対象となった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 *)