この記事は公開されてから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を作成しましょう。ここでは自分のメールドレスを通知先として設定しました。
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"
}
}