システム構成
AWSマルチアカウント環境での期限切れが近いEC2リザーブドインスタンスを通知するシステムをLambdaを使用して構築しました。
■ 構成図
1. IAMポリシー、IAMロール
■ Lambdaが各アカウントのリザーブドインスタンスの期限をチェックするポリシーとロールを作成
IAMポリシー
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "sts:AssumeRole",
"Resource": "アカウント1に作成したロールarn"
},
{
"Effect": "Allow",
"Action": "sts:AssumeRole",
"Resource": "アカウント2に作成したロールarn"
},
{
"Effect": "Allow",
"Action": "sts:AssumeRole",
"Resource": "アカウント3に作成したロールarn"
},
{
"Effect": "Allow",
"Action": "ec2:DescribeReservedInstances",
"Resource": "*"
},
{
"Effect": "Allow",
"Action": "sns:Publish",
"Resource": "通知先のアドレスを登録しているSNSトピックのarn"
}
]
}
IAMロール 信頼ポリシー
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": "lambda.amazonaws.com"
},
"Action": "sts:AssumeRole"
}
]
}
■ 各アカウント側でLambda実行アカウントからのリザーブドインスタンスのチェックを許可するポリシーとロールを作成
IAMポリシー
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"ec2:DescribeReservedInstances"
],
"Resource": "*"
}
]
}
IAMロール 信頼ポリシー
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::Lambda実行アカウントID:root"
},
"Action": "sts:AssumeRole"
}
]
}
2. Lambda
AWSアカウントとIAMロールのリストを定義し、それぞれのアカウントのリザーブドインスタンスの情報を取得し、31日未満の場合にSNSトピックに送信するLambdaを作成
■ コード
import boto3
from datetime import datetime, timedelta
SNS_TOPIC_ARN = 'SNSトピックarn'
ACCOUNTS = [
{
'account_id': '対象アカウントID_1',
'role_arn': 'arn:aws:iam::対象アカウントID_1:role/ロール名'
},
{
'account_id': '対象アカウントID_2',
'role_arn': 'arn:aws:iam::対象アカウントID_2:role/ロール名'
},
{
'account_id': '対象アカウントID_3',
'role_arn': 'arn:aws:iam::対象アカウントID_3:role/ロール名'
}
]
def lambda_handler(event, context):
now = datetime.utcnow()
notification_threshold = 31
sts_client = boto3.client('sts')
sns_client = boto3.client('sns')
# すべての対象アカウントに対して処理を実行
for account in ACCOUNTS:
account_id = account['account_id']
role_arn = account['role_arn']
credentials = sts_client.assume_role(
RoleArn=role_arn,
RoleSessionName='CrossAccountSession'
)['Credentials']
ec2_client = boto3.client(
'ec2',
aws_access_key_id=credentials['AccessKeyId'],
aws_secret_access_key=credentials['SecretAccessKey'],
aws_session_token=credentials['SessionToken']
)
# リザーブドインスタンスの情報取得
reserved_instances = ec2_client.describe_reserved_instances()
for reserved_instance in reserved_instances['ReservedInstances']:
expiry_date = reserved_instance['End']
remaining_days = (expiry_date - now).days
if remaining_days <= notification_threshold:
# 通知メールに記載したい情報
message = (f"アカウントID: {account_id}\n"
f"リザーブドインスタンスID: {reserved_instance['ReservedInstancesId']}\n"
f"終了日: {expiry_date} ({remaining_days} 日後)")
sns_client.publish(
TopicArn=SNS_TOPIC_ARN,
Message=message,
Subject='リザーブドインスタンス期限切れ通知'
)
3. EventBridge
定期的にLambdaを起動するEventBridgeルールを作成
※画像は毎月1日の午前9時に起動するルール
期限をチェックLambdaをターゲットとして選択
最後に
今回のシステムにより、AWSマルチアカウント環境でのEC2リザーブドインスタンスの期限を効率的に管理できます。LambdaとEventBridgeを組み合わせることで、定期的なチェックと通知が自動化され、リザーブドインスタンスの有効期限切れを防ぐことができます。