AWSマルチアカウント環境でのEC2リザーブドインスタンス期限通知システム構築

システム構成

AWSマルチアカウント環境での期限切れが近いEC2リザーブドインスタンスを通知するシステムをLambdaを使用して構築しました。

 

■ 構成図

file

 

 

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時に起動するルール

file

期限をチェックLambdaをターゲットとして選択
file

 

最後に

今回のシステムにより、AWSマルチアカウント環境でのEC2リザーブドインスタンスの期限を効率的に管理できます。LambdaとEventBridgeを組み合わせることで、定期的なチェックと通知が自動化され、リザーブドインスタンスの有効期限切れを防ぐことができます。

Last modified: 2024-07-05

Author