AMIの作成時間が知りたかったのでSNS Topicで通知させてみた

小ネタです。AMIの作成時間を調べたい状況がありちょっと調べていたのですが、作成済のAMI、およびEBSからは作成にどれくらいかかったのか?を読み取ることができませんでした。CloudWatchEventsから取得できることがわかったので、SNSでいい感じに通知させてみたいと思います。
2018.07.18

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

ご機嫌いかがでしょうか、豊崎です。

小ネタです。AMIの作成時間を調べたい状況がありちょっと調べていたのですが、作成済のAMI、およびEBSからは作成にどれくらいかかったのか?を読み取ることができませんでした。CloudWatchEventsから取得できることがわかったので、SNSでいい感じに通知させてみたいと思います。

AWS CLIのdescribe系コマンドでの表示

AMIに対して「aws ec2 describe-images」を打った場合

$ aws ec2 describe-images --owners <自分のAWSアカウントID>
{
    "Images": [
        {
            "VirtualizationType": "hvm",
            "Description": "demo",
            "Hypervisor": "xen",
            "EnaSupport": true,
            "SriovNetSupport": "simple",
            "ImageId": "ami-2d7917c0",
            "State": "available",
            "BlockDeviceMappings": [
                {
                    "DeviceName": "/dev/xvda",
                    "Ebs": {
                        "Encrypted": false,
                        "DeleteOnTermination": true,
                        "VolumeType": "gp2",
                        "VolumeSize": 8,
                        "SnapshotId": "snap-XXXXXXXXXXXX"
                    }
                }
            ],
            "Architecture": "x86_64",
            "ImageLocation": "XXXXXXXXXXXX/demoami",
            "RootDeviceType": "ebs",
            "OwnerId": "XXXXXXXXXXXX",
            "RootDeviceName": "/dev/xvda",
            "CreationDate": "2018-07-17T13:40:43.000Z",
            "Public": false,
            "ImageType": "machine",
            "Name": "demoami"
        }
    ]
}

EBSに対して「aws ec2 describe-images」を打った場合

$ aws ec2 describe-snapshots --snapshot-ids snap-XXXXXXXXXXXX
{
    "Snapshots": [
        {
            "Description": "Created by CreateImage(i-XXXXXXXXXXXX) for ami-d9761834 from vol-XXXXXXXXXXXX",
            "Encrypted": false,
            "VolumeId": "vol-XXXXXXXXXXXX",
            "State": "completed",
            "VolumeSize": 8,
            "StartTime": "2018-07-17T13:30:59.000Z",
            "Progress": "100%",
            "OwnerId": "XXXXXXXXXXXX",
            "SnapshotId": "snap-XXXXXXXXXXXX"
        }
    ]
}

CreationDataやStartTimeはあるものの、どちらも終了時間がわかりません。。

調べていったところ、 CloudWatchEventsのイベントソースにサービス名:EC2、イベントタイプ:EBS Snapshot Notificationを指定すれば、作成開始と終了について通知がされることがわかりました。

Amazon EBS イベント https://docs.aws.amazon.com/ja_jp/AmazonCloudWatch/latest/events/EventTypes.html#ebs-event-types

作ってみた

それでは作っていきたいと思います。

ちなみに構成としては以下のようなイメージになります。CloudWatchEventsからターゲットに渡されるJSONを整形したかったのでLambdaを間に挟んでいます。

 

SNS Topicをつくる

それでははじめに以下ブログを参考にしてSNSのTopicを作成しましょう。ここでは自分のメールドレスを通知先として設定しました。

[基本操作]Amazon SNSでメールを送信する

Lambdaをつくる

次にCloudWatchEventのターゲットとなるLambdaを作成します。

ここではpython3.6で書いたスクリプトだけ書き残したいと思います。 Lambdaの作成方法は

python3.6で以下のようなfunctionを書いてみました。 テスト用なのでLambdaへのロールはadmin権限を付与しています。

import boto3

def lambda_handler(event, context):
    result = event['detail']['result']
    snapshotId = event['detail']['snapshot_id']
    startTime = event['detail']['startTime']
    endTime = event['detail']['endTime']
    
    client = boto3.client('sns')

    sns_response = client.publish(
        TopicArn="arn:aws:sns:ap-northeast-1:223994872378:demo-sns",
        Message=('SNS のスナップショットが作成されました。\n詳細は以下です。\n\n結果:'
        + result
        + '\nスナップショットID:'
        + snapshotId
        + '\n作成開始時間:'
        + startTime
        + '\n作成終了時間:'
        + endTime
        + '\n\n'),
        Subject='demo-SnapshotCreateTime'
    )

    return sns_response

CloudWatchEventsを設定する

AWSマネジメントコンソールのCloudWatchダッシュボードから、イベント>ルールの作成をクリックします。

以下画面でイベントソースを以下のように設定します。

ターゲットには先ほど作成したLambdaを指定します。

 

試してみる

任意のEC2を選択して、アクション>イメージ>イメージの作成からAMIを作成してみます。

するとCloudWatchEventsからLambdaが呼び出され、SNSで自分のメールアドレスに通知が届きました。

問題なく受け取れていますね。

さいごに

今回はCloudWatchEventsから渡されるJSONを整形したかったので、Lambdaを使用しましたが、JSONのままでOKと言うことであればCloudWatchEventsからそのままターゲットにSNSを指定するのが簡単です。ちょっと備忘録的な感じになりましたが、この記事が誰かのお役に立てば幸いです。

補足

今回のケースでCloudWatchEventsから渡されるJSONは以下のような形式なので、必要に応じてLambdaのスクリプトを修正して使っていただければと思います。

{
    "version": "0",
    "id": "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX",
    "detail-type": "EBS Snapshot Notification",
    "source": "aws.ec2",
    "account": "XXXXXXXXXXXX",
    "time": "2018-07-17T13:40:45Z",
    "region": "ap-northeast-1",
    "resources": [
        "arn:aws:ec2::ap-northeast-1:snapshot/snap-XXXXXXXXXXXXXXXX"
    ],
    "detail": {
        "event": "createSnapshot",
        "result": "succeeded",
        "cause": "",
        "request-id": "",
        "snapshot_id": "arn:aws:ec2::ap-northeast-1:snapshot/snap-XXXXXXXXXXXXXXXX",
        "source": "arn:aws:ec2::ap-northeast-1:volume/vol-XXXXXXXXXXXX",
        "startTime": "2018-07-17T13:40:43.000Z",
        "endTime": "2018-07-17T13:40:44.883Z"
    }
}