AWS
lambda
boto3

AWS Lambda Python で AMI の世代管理を自動化する

More than 3 years have passed since last update.

こちらの投稿で Lambda を使ってサーバレスに AMI の取得を自動化しました。

取得を自動化したら次は世代管理(一定数を超えたらpurge)の自動化ですね!

こちらも Lambda を使ってやってみました。


Lambda ファンクションの作成

AMI 取得の Lambda ファンクションと同様に、EC2 の操作権限のあるロールを指定します。

{

"Version": "2012-10-17",
"Statement": [
{
"Sid": "Stmt1448895482556",
"Action": "ec2:*",
"Effect": "Allow",
"Resource": "*"
}
]
}


Code

今回も対象のインスタンス名を指定するかたちで、purge 処理を行います。

自身に紐付いている Image を取得順に並び替えて、保存したい世代数 GEM_NUM を超過した分を削除しています。

普通に Image を消すだけだと Snapshot との紐付けは消えるのですが、Snapshot 自体は残ってしまうので、Snapshot も明示的に削除するようにしています。


deregister_ami.py

# -*- coding: utf-8 -*-

import commands, boto3

TARGET_INSTANCE_NAME = "***" # Enter your target Instance Name
GEM_NUM = 2 # 保存世代数

def _(cmd):
return commands.getoutput(cmd)

def handler(event, context):
images = boto3.client('ec2').describe_images(Owners=["self"])["Images"]

delete_count = len(images) - GEM_NUM
targetImages = []
for image in sorted(images, key=lambda x: x["CreationDate"]):
if (delete_count == 0) :
break
elif image["Name"].count(TARGET_INSTANCE_NAME):
targetImages.append(image)
delete_count -= 1

for targetImage in targetImages:
ec2 = boto3.resource('ec2')
ec2.Image(targetImage["ImageId"]).deregister()
for block in targetImage["BlockDeviceMappings"]:
ec2.Snapshot(block["Ebs"]["SnapshotId"]).delete()



Configuration

Handler は deregister_ami.handler としてください。

Timeout はデフォルトの 3秒終わらないことがあるかもしれません。

少し伸ばしましょう。


Event sources

私の場合は朝4時に AMI を取得しているので、

取得処理が終わっているであろう10分後に purge するように cron(10 4 ? * * *) としています。

-> 今回の本題からは外れますが AMI の取得は API を呼び出しに成功しても途中で失敗することがあります。

  ですので、例えば purge する Image がひとつもないときはその日の AMI 取得がうまくいかなかったとみなし、

  管理者に通知あるいはメールを送るといったことができるといいなーと思ってます。今度実装してみます。


制限


  • 対象インスタンス名は一つしか指定できません(取得の方も同様)が、これに関しては今回は Lambda を使うことが本題で対応しなかっただけで、対象を指定する変数を配列化すればすぐに修正できると思います。

  • 手動で取得した Image も削除対象になることがあります。purge判定は「指定したインスタンス名が含まれている」かつ「取得したタイミングが古い」の2点だけで判断しているためです。本当は自動で取った AMI に自動で取ったことがわかるようなタグを付与し、そのタグがあるものだけを自動 purge すべきです。これも実装しようと思えばできると思いますが、今回は対応していません。


まとめ

Python さえ書ければ運用スクリプトの多くを Lambda でサーバレス化できるような気がします。

次は、アプリロジックを書き、API Gateway と組み合わせて API を作ってみたいです。

アプリロジック書くなら Java にすべきでしょうか。

Lambda で採用する言語についてもいろいろ考察してみたいです。