前提
メンテナンス時など、バックアップを取る際にスナップショットを手動で取得している。
課題
メンテナンスが問題なく完了した後、不必要になったスナップショットの削除を行う運用ルールがなく、無駄なコストが発生していた。
目的
スナップショット作成から一定期間経過したものは削除する仕組みをLambdaに関数登録し、トリガーとしてCloudWatch Eventsで日時実行する。
原則AMIに登録されているスナップショットの削除は行わない。
ソース
auto_delete_snapshot.py
import boto3
from datetime import datetime, timedelta
import dateutil.tz
########## 変数定義 ##########
# AWSアカウントID
acountId = "xxxxxxxxxx"
# 何日前以前を削除対象とするか指定 default=7
days = 7
########## 削除処理 ##########
def lambda_handler(event, context):
# 削除対象日付を取得
delete_date = (datetime.now(dateutil.tz.tzlocal()) - timedelta(days=days))
print(delete_date)
# 本AWSアカウント上に存在するスナップショットを全て取得
ec2 = boto3.client("ec2")
snapshots = ec2.describe_snapshots(
Filters=[
{
"Name": "owner-id",
"Values": [acountId]
}
]
)["Snapshots"]
# 本AWSアカウント上に存在するAMIを全て取得
images = ec2.describe_images(
Filters=[
{
"Name": "owner-id",
"Values": [acountId]
}
]
)["Images"]
print('全スナップショット')
print(snapshots)
print('全AMI')
print(images)
# 作成から7日以上経過したスナップショットを取得
old_snapshots = [s for s in snapshots if s["StartTime"] < delete_date]
# AMIに登録されているスナップショットを削除対処から除外する
for x in images:
for y in old_snapshots:
for block_devices in x['BlockDeviceMappings']:
if 'Ebs' in block_devices:
if block_devices['Ebs']['SnapshotId'] == y['SnapshotId']:
old_snapshots.remove(y)
print('AMI以外の削除対象スナップショット')
print(old_snapshots)
# 削除対象のスナップショットを削除
for s in old_snapshots:
ec2.delete_snapshot(SnapshotId = s['SnapshotId'])
print(s['SnapshotId'] + "を削除しました")
まとめ
実行結果は以下から確認可能です。
Lambda > モニタリング > CloudWatchのログを表示 > ログストリームから該当のログを選択
AMIに登録されているスナップショットの扱いをどうするのか、現場の運用ルールによってはAMIの登録解除→スナップショットの削除までやってもいいと思います。
今回はLambda、CLIからのSnapshot、AMIの扱い、CloudWatch Event、IAMのポリシーとロール、アクセス許可設定について理解が深まりました。
最後まで読んでいただきありがとうございました!