EventBridge + Lambdaを使用してEC2インスタンスに自動的にIAMロールを付与する方法
はじめに
かつまたです。マネージドインスタンスを作成する際に、AmazonSSMManagedInstanceCoreポリシーが付与されたポリシーを作成し、EC2にアタッチするといった、EC2作成後のロール付与の動作を行うことがあると思います。今回はIAMロールが無いEC2が作成された時に指定したロールを自動で付与する構成をEventbridge+Lambdaで構築してみたので手順をご紹介します。
EC2用IAMロール作成
EC2にアタッチする用のIAMロールを作成します。今回はマネージドインスタンスを操作するためのAmazonSSMManagedInstanceCoreポリシーを利用します。
1.「IAM」の「ロールを作成」からロールを作成します。「信頼されたエンティティタイプ」を「AWSサービス」、「ユースケース」を「EC2」から「EC2 Role for AWS Systems Manager」と選択します。
2.許可ポリシーに「AmazonSSMManagedInstanceCore」が自動で追加されていることを確認します。ロールを作成します。このロール名は後ほど使用します。
Lambda作成
IAMロールがアタッチされていないインスタンスに、該当のIAMロールを付与するLambda関数を作成します。
1.「Lambdaを作成」から「関数名」を入力し、「ランタイム」を「Python 3.12」とします。関数を作成します。
2.作成したLambda関数の詳細画面から「コード」上に以下のソースコードを記述します。デプロイします。
Python例
import boto3
import logging
from botocore.exceptions import ClientError
logger = logging.getLogger()
logger.setLevel(logging.INFO)
def lambda_handler(event, context):
"""
EC2インスタンスが起動したときにIAMロールをアタッチするLambda関数
:param event: EventBridgeからのイベントデータ
:param context: Lambda実行コンテキスト
:return: 実行結果を示す辞書
"""
try:
# EC2クライアントの初期化
ec2 = boto3.client('ec2')
# イベントからインスタンスIDを取得
instance_id = event['detail']['instance-id']
logger.info(f"Processing instance: {instance_id}")
# インスタンスの詳細を取得
response = ec2.describe_instances(
InstanceIds=[instance_id],
Filters=[{'Name': 'instance-state-name', 'Values': ['running']}]
)
# インスタンスが見つからない場合は処理を終了
if not response['Reservations']:
logger.info(f"Instance {instance_id} not found or not in running state")
return
instance = response['Reservations'][0]['Instances'][0]
# IAMロールがアタッチされていない場合、ロールをアタッチ
if 'IamInstanceProfile' not in instance:
attach_response = ec2.associate_iam_instance_profile(
IamInstanceProfile={'Name': 'EC2にアタッチするIAMロール名'},
InstanceId=instance_id
)
logger.info(f"Attached role to instance {instance_id}")
else:
logger.info(f"Instance {instance_id} already has a role attached")
return {'statusCode': 200, 'body': 'Function executed successfully'}
except ClientError as e:
logger.error(f"AWS API error: {e}")
raise
except Exception as e:
logger.error(f"Unexpected error: {e}")
raise
3.Lambda関数の実行ロールに対して、Lambda関数がEC2インスタンスにIAMロールをアタッチするために必要な権限を付与します。作成したLambda関数の「設定」→「アクセス権限」から「実行ロール」のロール名を選択してIAMの画面に移動します。
4.該当ロールの「許可を追加」→「インラインポリシーを作成」からポリシー編集画面に移動します。
5.ポリシーエディタに以下のポリシーをアタッチします。
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"ec2:DescribeInstances",
"ec2:AssociateIamInstanceProfile"
],
"Resource": "*"
},
{
"Effect": "Allow",
"Action": "iam:PassRole",
"Resource": "arn:aws:iam::アカウントID:role/EC2にアタッチしたいロール名"
}
]
}
Eventbridge作成
1.「Eventbridge」→の「ルール」からEventbridgeルールを作成します。「イベントパターンを持つルール」での作成を実施します。
2.「イベントパターン」の「AWSのサービス」を「EC2」として、「イベントタイプ」を「EC2 Instance State-change Notification」と設定します。「イベントタイプの仕様」を「特定の状態」から「runnning」を指定し、EC2が起動した際にEventbridgeが実行するよう設定します。
3.「ターゲットを選択」において「ターゲットタイプ」を「AWSのサービス」として、作成したLambda関数を指定します。
動作確認
1.インスタンスプロファイルが無いEC2を作成して、動作を確認します。EC2作成時に「高度な詳細」の「IAMインスタンスプロフィール」で作成時のロール付与がないことを確認します。
2.EC2作成し、少し待った後、EC2詳細のインスタンス概要を確認して、指定したIAMロールがアタッチされていることを確認します。
おわりに
今回の構成では全ての作成したインスタンスをトリガーとして検知、付与する構成でしたが、Eventbridgeの設定を変更することで、特定タグが付与されたインスタンスに対してのロール付与自動化といった発展的な構成も考えられます。ご覧いただきありがとうございました。
アノテーション株式会社について
アノテーション株式会社はクラスメソッドグループのオペレーション専門特化企業です。サポート・運用・開発保守・情シス・バックオフィスの専門チームが、最新 IT テクノロジー、高い技術力、蓄積されたノウハウをフル活用し、お客様の課題解決を行っています。当社は様々な職種でメンバーを募集しています。「オペレーション・エクセレンス」と「らしく働く、らしく生きる」を共に実現するカルチャー・しくみ・働き方にご興味がある方は、アノテーション株式会社 採用サイトをぜひご覧ください。