AMIの作成時間が知りたかったのでSNS Topicで通知させてみた
ご機嫌いかがでしょうか、豊崎です。
小ネタです。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を作成しましょう。ここでは自分のメールドレスを通知先として設定しました。
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" } }