[Lambdaでクロスアカウント] Lambda 関数で AssumeRole して他の AWS アカウントのリソースにアクセスする
こんにちは、菊池です。
Lambda関数で異なるAWSアカウントのリソースにアクセスしたい場合、S3やSQSのようにリソース側でアクセスポリシーを設定可能なサービスであれば、それを利用してクロスアカウントのアクセス許可を与えるのが一般的です。
しかし、リソース側でポリシーを設定できないサービスの場合にはそうもいきません。そのようなケースでは、信頼関係を結んだIAMロールを使って、一時クレデンシャルを発行してアクセスする方法があります。
PythonのAWS SDKであるBoto3を使った例が以前紹介されていました。
今回は、これを応用してLambda関数で同様の処理を行い、他のAWSアカウントのリソースにアクセスすることを試してみました。
動作イメージ
処理のイメージは以下のようになります。
あらかじめアカウントBで、アカウントAのIAMロールAを信頼した、IAMロールBを作成しておきます。Lambda関数はまず、IAMロールAの認証情報を利用して、IAMロールBの一時クレデンシャルを取得します。その認証情報を利用して、アカウントBのリソースにアクセスします。
サンプルコード
import boto3 from boto3.session import Session # 異なるAWSアカウント/ロールのクレデンシャル取得を実行する def sts_assume_role(account_id,role_name): role_arn = "arn:aws:iam::" + account_id + ":role/" + role_name session_name = "foobar" region = "ap-northeast-1" client = boto3.client('sts') # AssumeRoleで一時クレデンシャルを取得 response = client.assume_role( RoleArn=role_arn, RoleSessionName=session_name ) session = Session( aws_access_key_id=response['Credentials']['AccessKeyId'], aws_secret_access_key=response['Credentials']['SecretAccessKey'], aws_session_token=response['Credentials']['SessionToken'], region_name=region ) return session def lambda_handler(event,context): account_id = event['account'] role_name = event['role'] # イベントで指定されたAWSアカウント/ロールのクレデンシャルを取得 session = sts_assume_role(account_id,role_name) sts = session.client('sts') # 取得したクレデンシャルを使って処理を実行 response = sts.get_caller_identity()["Account"] return response
イベントとして、アクセス先のAWSアカウントIDとIAMロール名(上記図の、アカウントB/IAMロールBに相当)を入力することで動作します。
{ "account": (AWSアカウントID), "role": (IAMロール名) }
上記サンプルでは、取得した認証情報のAWSアカウントIDをsts.get_caller_identityで出力するのみの処理です。
まとめ
Lambdaを使ったクロスアカウントアクセスを柔軟にできないかと思い、試してみました。
Lambda関数に元々割り当てていたIAMロールで直接アクセスするのに比べ、AssumeRoleが必要な分、処理のオーバーヘッドがありますので、パフォーマンスにシビアなユースケースでは注意が必要です。