AMIのイベントを検知したいな
こんにちは、のんピ(@non____97)です。
皆さんはAMIのイベントを検知したいと思ったことはありますか? 私はあります。
具体的にはAMIのイベントを検知して以下の処理を簡単に実装したいなと思っていました。
- AMIの作成が完了したら別リージョンにAMIをコピーする
- AMIの登録解除をしたら関連付くEBSスナップショットを削除する
特に1つ目の処理を実装する場合、AMIの作成が完了したのか定期的にAMIの状態をポーリングする必要がありました。
今回、AMIの作成や登録解除などのイベントがAmazon EventBridgeに送信されるようになりました。
これにより、上述した処理が簡単に実装できそうです。
早速試してみたので紹介します。
対象のAMIのイベント
対象のAMIのイベントは以下の3つです。
available
: AMIが利用可能になったfailed
: AMIの作成が失敗したderegistered
: AMIを登録解除した
以下のいずれかのAPIが実行されると、available
またはfailed
イベントが送信されます。
DeregisterImage APIが実行されると、deregistered
イベントが送信されます。
それぞれのイベントサンプルは以下の通りです。
available イベント
{
"version": "0",
"id": "example-9f07-51db-246b-d8b8441bcdf0",
"detail-type": "EC2 AMI State Change",
"source": "aws.ec2",
"account": "012345678901",
"time": "yyyy-mm-ddThh:mm:ssZ",
"region": "us-east-1",
"resources": ["arn:aws:ec2:us-east-1::image/ami-0123456789example"],
"detail": {
"RequestId": "example-9dcc-40a6-aa77-7ce457d5442b",
"ImageId": "ami-0123456789example",
"State": "available",
"ErrorMessage": ""
}
}
failed イベント
{
"version": "0",
"id": "example-9f07-51db-246b-d8b8441bcdf0",
"detail-type": "EC2 AMI State Change",
"source": "aws.ec2",
"account": "012345678901",
"time": "yyyy-mm-ddThh:mm:ssZ",
"region": "us-east-1",
"resources": ["arn:aws:ec2:us-east-1::image/ami-0123456789example"],
"detail": {
"RequestId": "example-9dcc-40a6-aa77-7ce457d5442b",
"ImageId": "ami-0123456789example",
"State": "failed",
"ErrorMessage": "Description of failure"
}
}
deregistered イベント
{
"version": "0",
"id": "example-9f07-51db-246b-d8b8441bcdf0",
"detail-type": "EC2 AMI State Change",
"source": "aws.ec2",
"account": "012345678901",
"time": "yyyy-mm-ddThh:mm:ssZ",
"region": "us-east-1",
"resources": ["arn:aws:ec2:us-east-1::image/ami-0123456789example"],
"detail": {
"RequestId": "example-9dcc-40a6-aa77-7ce457d5442b",
"ImageId": "ami-0123456789example",
"State": "deregistered",
"ErrorMessage": ""
}
}
なお、以下AWS公式ドキュメントにも記載ありますが、AMIの登録解除が失敗した場合、deregistered
イベントは生成されません。これはDeregisterImage APIが同期処理であるためです。登録解除の失敗を検知するには、APIの操作元で対応が必要そうですね。
AMIのイベントを使って処理してみる
検証する処理
それでは、AMIのイベントを使って処理してみます。
対象の処理は以下の2つです。
- AMIの作成が完了したら別リージョンにAMIをコピーする
- AMIの登録解除をしたら関連付くEBSスナップショットを削除する
検証にあたって必要なリソースはAWS CDKで定義しました。
こちらのコードのリポジトリは以下になります。
AMIの作成が完了したら別リージョンにAMIをコピーする
それでは、まず「AMIの作成が完了したら別リージョンにAMIをコピーする」から試してみます。
AWS CDKで各種リソースをデプロイした後、以下コマンドでAMIを作成します。
$ image=$(aws ec2 create-image \
--instance-id <EC2インスタンスID> \
--name <EC2インスタンスID>_ami \
| jq -r .ImageId)
しばらく待った後、AMIのステータスを確認したところ、利用可能になっていました。
コピーされているか確認するため、コピー先に指定した大阪リージョンのAMIを確認します。
しかし、大阪リージョンに対象のAMIは存在しませんでした。
CloudWatch LogsでLambda関数の実行履歴を確認したところ、Lambda関数が実行されていないようです。
また、EventBridgeルールでCloudWatch Metricsも確認しましたがデータが無く、そもそもイベントが発行されていないようでした。
実行したリージョン(us-east-1
)固有の問題かと思い、他のリージョンでも動作確認してみましたが、結果は同じくAMIの利用可能になったイベントを検知することができませんでした。
イベントパターンの表記ミスかと思い、EventBridgeルールにAWS公式ドキュメントに記載のイベントパターンを指定してみましたが結果は変わらずでした。
{
"source": ["aws.ec2"],
"detail-type": ["EC2 AMI State Change"],
"detail": {"State": ["available"]}
}
せっかくAMIをリージョン間コピーするLambda関数を作成したので、供養の意味を込めて手動で実行してあげます。
Lambdaのコンソールから以下イベントを設定してテスト
をクリックします。
{
"version": "0",
"id": "example-9f07-51db-246b-d8b8441bcdf0",
"detail-type": "EC2 AMI State Change",
"source": "aws.ec2",
"account": "012345678901",
"time": "yyyy-mm-ddThh:mm:ssZ",
"region": "us-east-1",
"resources": ["arn:aws:ec2:us-east-1::image/ami-0dd5eee736ffd8be3"],
"detail": {
"RequestId": "example-9dcc-40a6-aa77-7ce457d5442b",
"ImageId": "ami-0dd5eee736ffd8be3",
"State": "available",
"ErrorMessage": ""
}
}
すると、以下のようにCopyImage APIを受け付けたメッセージが出力されました。
START RequestId: ebaa7260-3552-42cb-afb6-4d439e1bee51 Version: $LATEST
2022-05-10T06:45:55.448Z ebaa7260-3552-42cb-afb6-4d439e1bee51 INFO response : {
"$metadata": {
"httpStatusCode": 200,
"requestId": "fa997007-2adf-4a11-9ca7-d5edca33e401",
"attempts": 1,
"totalRetryDelay": 0
},
"ImageId": "ami-05e0325f7941a83ce"
}
END RequestId: ebaa7260-3552-42cb-afb6-4d439e1bee51
REPORT RequestId: ebaa7260-3552-42cb-afb6-4d439e1bee51 Duration: 2170.77 ms Billed Duration: 2171 ms Memory Size: 128 MB Max Memory Used: 120 MB Init Duration: 700.38 ms
XRAY TraceId: 1-627a0a20-7d51ce9a7a447bbc5dae83e6 SegmentId: 1a56e6dd72cf1d4a Sampled: true
AMIの一覧を確認すると、確かにAMIのリージョン間コピーがされていました。
2022/5/11 17:00追記 先ほど再度試したところ、AMIの利用可能になったイベントを検知することができました。以下改めて検証内容を紹介します。
以下コマンドでAMIを作成します。
$ image=$(aws ec2 create-image \
--instance-id i-0a1366e9501b9f068 \
--name i-0a1366e9501b9f068_ami \
| jq -r .ImageId)
AMIが作成され、利用可能になったことを確認します。
$ aws ec2 describe-images \
--image-ids "$image"
{
"Images": [
{
"Architecture": "x86_64",
"CreationDate": "2022-05-11T08:18:54.000Z",
"ImageId": "ami-03fa4e3d8880f7f67",
"ImageLocation": "<AWSアカウントID>/i-0a1366e9501b9f068_ami",
"ImageType": "machine",
"Public": false,
"OwnerId": "<AWSアカウントID>",
"PlatformDetails": "Linux/UNIX",
"UsageOperation": "RunInstances",
"State": "available",
"BlockDeviceMappings": [
{
"DeviceName": "/dev/xvda",
"Ebs": {
"DeleteOnTermination": true,
"Iops": 3000,
"SnapshotId": "snap-0565aa680122ec8e1",
"VolumeSize": 8,
"VolumeType": "gp3",
"Throughput": 125,
"Encrypted": false
}
},
{
"DeviceName": "/dev/sdb",
"Ebs": {
"DeleteOnTermination": true,
"Iops": 3000,
"SnapshotId": "snap-094538c3ed7840ed2",
"VolumeSize": 1,
"VolumeType": "gp3",
"Throughput": 125,
"Encrypted": false
}
},
{
"DeviceName": "/dev/sdc",
"Ebs": {
"DeleteOnTermination": true,
"Iops": 3000,
"SnapshotId": "snap-0e487c13a1b47cee3",
"VolumeSize": 2,
"VolumeType": "gp3",
"Throughput": 125,
"Encrypted": false
}
}
],
"EnaSupport": true,
"Hypervisor": "xen",
"Name": "i-0a1366e9501b9f068_ami",
"RootDeviceName": "/dev/xvda",
"RootDeviceType": "ebs",
"SriovNetSupport": "simple",
"VirtualizationType": "hvm"
}
]
}
大阪リージョンでAMIを確認したところ、確かにAMIがコピーされていました。
$ aws ec2 describe-images \
--filters "Name=name,Values=$image" \
--region ap-northeast-3
{
"Images": [
{
"Architecture": "x86_64",
"CreationDate": "2022-05-11T08:21:59.000Z",
"ImageId": "ami-0019121662635c453",
"ImageLocation": "<AWSアカウントID>/ami-03fa4e3d8880f7f67",
"ImageType": "machine",
"Public": false,
"OwnerId": "<AWSアカウントID>",
"PlatformDetails": "Linux/UNIX",
"UsageOperation": "RunInstances",
"State": "pending",
"BlockDeviceMappings": [
{
"DeviceName": "/dev/xvda",
"Ebs": {
"DeleteOnTermination": true,
"Iops": 3000,
"VolumeSize": 8,
"VolumeType": "gp3",
"Throughput": 125,
"Encrypted": false
}
},
{
"DeviceName": "/dev/sdb",
"Ebs": {
"DeleteOnTermination": true,
"Iops": 3000,
"VolumeSize": 1,
"VolumeType": "gp3",
"Throughput": 125,
"Encrypted": false
}
},
{
"DeviceName": "/dev/sdc",
"Ebs": {
"DeleteOnTermination": true,
"Iops": 3000,
"VolumeSize": 2,
"VolumeType": "gp3",
"Throughput": 125,
"Encrypted": false
}
}
],
"EnaSupport": true,
"Hypervisor": "xen",
"Name": "ami-03fa4e3d8880f7f67",
"RootDeviceName": "/dev/xvda",
"RootDeviceType": "ebs",
"SriovNetSupport": "simple",
"VirtualizationType": "hvm"
}
]
}
CloudWatch LogsでAMIをコピーするLambda関数の実行履歴を確認したところ、実行した形跡がありました。
START RequestId: 80be7935-eeb2-45af-89b9-6702a5760886 Version: $LATEST
2022-05-11T08:21:59.748Z 80be7935-eeb2-45af-89b9-6702a5760886 INFO response :
{
"$metadata": {
"httpStatusCode": 200,
"requestId": "b52b8bfc-ecbf-48b4-bdd7-2d565d249ee2",
"attempts": 1,
"totalRetryDelay": 0
},
"ImageId": "ami-0019121662635c453"
}
END RequestId: 80be7935-eeb2-45af-89b9-6702a5760886
REPORT RequestId: 80be7935-eeb2-45af-89b9-6702a5760886 Duration: 2126.21 ms Billed Duration: 2127 ms Memory Size: 128 MB Max Memory Used: 120 MB Init Duration: 685.48 ms
XRAY TraceId: 1-627b7224-51b579e17a60cfc53cee2378 SegmentId: 025c8a826926f1d1 Sampled: true
当初AMIの利用可能のイベントを検知できなかったのは、たまたまだったようですね。
AMIの登録解除をしたら関連付くEBSスナップショットを削除する
次に、「AMIの登録解除をしたら関連付くEBSスナップショットを削除する」を試してみます。
以下コマンドで先ほど作成したAMIを登録解除します。
$ aws ec2 deregister-image \
--image-id "$image"
実行後にCloudWatch LogsでLambda関数の実行履歴を確認したところ、対象のAMIに関連付くEBSスナップショットは確かに削除されていそうでした。
START RequestId: 8986e46e-dffe-4ee8-a4ee-ace4dc888c07 Version: $LATEST
2022-05-10T06:53:25.544Z 8986e46e-dffe-4ee8-a4ee-ace4dc888c07 INFO describeSnapshotsCommandResponse :
{
"$metadata": {
"httpStatusCode": 200,
"requestId": "ad99a42d-c288-4d7d-8e37-d67c3c3240b7",
"attempts": 1,
"totalRetryDelay": 0
},
"Snapshots": [
{
"Description": "Created by CreateImage(i-00a53ab2ad68af3c5) for ami-0dd5eee736ffd8be3",
"Encrypted": false,
"OwnerId": "<AWSアカウントID>",
"Progress": "100%",
"SnapshotId": "snap-07a4f312e15a1243c",
"StartTime": "2022-05-10T06:32:17.193Z",
"State": "completed",
"VolumeId": "vol-038351192fbbc98b3",
"VolumeSize": 1,
"StorageTier": "standard"
},
{
"Description": "Created by CreateImage(i-00a53ab2ad68af3c5) for ami-0dd5eee736ffd8be3",
"Encrypted": false,
"OwnerId": "<AWSアカウントID>",
"Progress": "100%",
"SnapshotId": "snap-0b202f3be3817d681",
"StartTime": "2022-05-10T06:32:17.193Z",
"State": "completed",
"VolumeId": "vol-054a49873ea442962",
"VolumeSize": 8,
"StorageTier": "standard"
},
{
"Description": "Created by CreateImage(i-00a53ab2ad68af3c5) for ami-0dd5eee736ffd8be3",
"Encrypted": false,
"OwnerId": "<AWSアカウントID>",
"Progress": "100%",
"SnapshotId": "snap-00572020c97cce254",
"StartTime": "2022-05-10T06:32:17.193Z",
"State": "completed",
"VolumeId": "vol-0ab6f1f19d8b6802c",
"VolumeSize": 2,
"StorageTier": "standard"
}
]
}
2022-05-10T06:53:25.563Z 8986e46e-dffe-4ee8-a4ee-ace4dc888c07 INFO delete snapshotId : snap-07a4f312e15a1243c
2022-05-10T06:53:25.584Z 8986e46e-dffe-4ee8-a4ee-ace4dc888c07 INFO delete snapshotId : snap-0b202f3be3817d681
2022-05-10T06:53:25.584Z 8986e46e-dffe-4ee8-a4ee-ace4dc888c07 INFO delete snapshotId : snap-00572020c97cce254
END RequestId: 8986e46e-dffe-4ee8-a4ee-ace4dc888c07
REPORT RequestId: 8986e46e-dffe-4ee8-a4ee-ace4dc888c07 Duration: 837.38 ms Billed Duration: 838 ms Memory Size: 128 MB Max Memory Used: 120 MB Init Duration: 681.74 ms
XRAY TraceId: 1-627a0be3-0ea3a69b0d841550410c3915 SegmentId: 39358d847b43adcd Sampled: true
実際にEBSスナップショット一覧を確認したところ、登録解除したAMIに関連付くEBSスナップショットは全て削除されていました。
地味ありがたいアップデートが来た
AMIの作成や登録解除などのイベントがAmazon EventBridgeに送信されるようになったアップデートを紹介しました。
「AMIの作成や登録解除が終わったことをトリガーに後続の処理を実行したいんだよな〜」と思っていた方には朗報ですね。
この記事が誰かの助けになれば幸いです。
以上、AWS事業本部 コンサルティング部の のんピ(@non____97)でした!