23
27

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

AWS Lambda Python で AMI の取得を自動化する

Last updated at Posted at 2015-12-03

ありそうでなかったので書いてみます。

これまで AMI を取る専用の EC2 を常時起動していたのですが、今回それを Lambda に移行してみました。
もともとの取得スクリプトは旧バージョンの Boto で書いていたので、Lambda 化することより Boto3 化する方が大変でした。

Lambda ファンクションの作成

新しい Lambda ファンクションを作成してください。
各画面の操作方法はこちらの投稿に詳しく載せていますので、よければ参考にしてください。
注意したいのは、AMI の登録(削除)を行うので、EC2 の操作ポリシーをロールにつけてあげる必要がある点です。

今回は EC2 関連の全ての権限をつけてしまったのですが、本当は使う Action に絞って権限付与すべきです。
ポリシジェネレータで作成しましょう。

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

Code

client で対象のインスタンス情報を取ってから、resource で Image 作成しています。
使い方があってるかいまいち自信がないのですが、、特に client の部分もっと簡単に書けるのであれば教えていただきたいです。

今回は Instance ID ではなく、Name で対象インスタンスを決めるようにしています。
TARGET_INSTANCE_NAME の部分だけご自分のインスタンス名に変更すれば、動くと思います。

create_ami.py
# -*- coding: utf-8 -*-

import commands, boto3

TARGET_INSTANCE_NAME = '***' # Enter your target Instance Name

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

def create_image(instance_name):
    
    instance_id = ""
    for reservation in boto3.client('ec2').describe_instances()["Reservations"]:
        for instance in reservation["Instances"]:
            for tag in instance["Tags"]:
                if(tag["Key"] == "Name" and tag["Value"] == instance_name):
                    instance_id = instance["InstanceId"]
    
    if instance_id != "":
        instance = boto3.resource('ec2').Instance(instance_id)
        image_name = _('TZ=JST-9 date +"%Y%m%d"') + "_" + instance_name 
        instance.create_image(Name=image_name)

def handler(event, context):
    create_image(TARGET_INSTANCE_NAME)

Configuration

Handler は create_ami.handler としてください。
Timeout は 3秒では心許ないので、5秒〜10秒くらいにしましょう。

Event sources

私は朝4時に取得したいので、cron(0 4 ? * * *) としています。

ちなみに、上のコードでは AMI の名前が YYYYMMDD_(インスタンス名) となります。
そのため、同じ日に複数回実行すると(同じ名前の AMI は作れないので)エラーになります。

もし、1日複数回 AMI を取得する必要があるのであれば、
image_name = _('TZ=JST-9 date +"%Y%m%d"') + "_" + instance_name
image_name = _('TZ=JST-9 date +"%Y%m%d%H"') + "_" + instance_name とすれば大丈夫だと思います。

まとめ

ここまでで完了です。
試しにテスト実行してみてください。AMI が取れましたでしょうか。

感想としては、冒頭にも書きました通り、Lambda 周りでは全くつまらず、Boto3 を使う部分で少し苦戦しました。
そういう意味では「ビジネスロジックに集中」できているのかもしれません。

次回は、AMI の世代管理を自動化します。

23
27
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
23
27

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?