はじめに
SSM Maintenance WindowのAWS-CreateImageでAMIを作成した後、毎回手動で許可設定へAWSアカウントIDを追加していました。
手作業をなくすため、AMI作成完了をトリガーに自動で共有設定を付与する仕組みを構築しました。
使用するサービス
Maintenance Window:定期実行
AWS-CreateImage:AMI作成
EventBridge:AMI作成完了検知
Lambda:AMI共有設定追加
EventBridge設定
- イベントパターン
{
"source": ["aws.ec2"],
"detail-type": ["EC2 AMI State Change"],
"detail": {
"State": ["available"]
}
}
- ターゲット
Lambda関数:lambda-share-ami
※SHARE_ACCOUNT_IDは環境変数にて明記
Lambda設定
- コード
import boto3
import logging
import os
ec2 = boto3.client("ec2")
logger = logging.getLogger()
logger.setLevel(logging.INFO)
SHARE_ACCOUNT_ID = os.environ["SHARE_ACCOUNT_ID"]
def lambda_handler(event, context):
logger.info("Received event: %s", event)
image_id = event["detail"]["ImageId"]
logger.info(
"Start AMI sharing: image_id=%s, account_id=%s",
image_id,
SHARE_ACCOUNT_ID
)
ec2.modify_image_attribute(
ImageId=image_id,
LaunchPermission={
"Add": [
{
"UserId": SHARE_ACCOUNT_ID
}
]
}
)
logger.info(
"AMI sharing completed: image_id=%s, account_id=%s",
image_id,
SHARE_ACCOUNT_ID
)
return {
"statusCode": 200,
"message": f"AMI {image_id} shared with {SHARE_ACCOUNT_ID}"
}
- 許可アクション
logs:CreateLogGroup
logs:CreateLogStream
logs:PutLogEvents
ec2:ModifyImageAttribute
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "CloudWatchLogs",
"Effect": "Allow",
"Action": [
"logs:CreateLogGroup",
"logs:CreateLogStream",
"logs:PutLogEvents"
],
"Resource": [
"arn:aws:logs:ap-northeast-1:<AWS_ACCOUNT_ID>:*",
"arn:aws:logs:ap-northeast-1:<AWS_ACCOUNT_ID>:log-group:/aws/lambda/lambda-share-ami:*"
]
},
{
"Sid": "ModifyAMILaunchPermission",
"Effect": "Allow",
"Action": [
"ec2:ModifyImageAttribute"
],
"Resource": "*"
}
]
}
実行結果
[INFO] Start AMI sharing: image_id=ami-0306822946e12aa1c, account_id=<AWS_ACCOUNT_ID>
[INFO] AMI sharing completed: image_id=ami-0306822946e12aa1c, account_id=<AWS_ACCOUNT_ID>
さいごに
現状のEventBridgeルールは、オートメーションAMI作成に関わらず、AMIがavailableになると、対象を限定せずLambdaを起動します。
そのため、拡張案としては、カスタムオートメーションで、AWS-CreateImageと特定のタグ付与のランブックを作成して、Lambdaで付与したAMIのタグを取得し、対象を限定する方法が挙げられます。