[AWS](WA)Lambda クロスアカウント IAM ロールの仮定

AWS

元ネタ

AWSのWell-Architected Frameworkを改めて整理。せっかくなんでハンズオン形式で学べるAWS Well-Architected Labsをやってみよう!ということで、備忘も兼ねて実践&記録をしてみました。

Workshop Studio
Discover and participate in AWS workshops and GameDays

前提条件

  • AWSのrootアカウントが2つあること
  • 一方のアカウントにS3バケットがあること

ハンズオン開始

0. 概要

このハンズオンでは、AWS アカウント 1 (送信元) で Python boto SDK を使用して Lambda 関数を実行し、アカウント 2 (送信先) で IAM ロールを引き受け、バケットを一覧表示する方法を示します。

1. アカウント2のロール作成

S3バケットを開示する側のアカウント2にて、アカウント1より参照可能にするためにロールを作成します。

ロール作成手順

  1. アカウント2でログインし、IAMコンソールよりロールを開き、「ロールを作成」を選択する。
  1. 「信頼されたエンティティタイプ」に「AWSアカウント」を選択する。「AWSアカウント」では「別のAWSアカウント」を選択した上で、「アカウントID」にアカウント1のAWSアカウントID(ダッシュなし12桁)を入力し、「次へ」を選択する。
  1. 「許可を追加」では変更せず、「次へ」を選択する。
  1. 「ロールの詳細」の「ロール名」に「LambdaS3ListBuckets」を入力する。
  1. 「ロールを作成」を選択する。
  1. 作成完了のメッセージを確認し、「ロールを表示」を選択する。
  1. 表示された「概要」より、中央の「ARN」をコピーしておく。
  1. 「許可」タブより、「許可を追加」にある「インラインポリシーを作成」を選択する。
  1. 「アクセス許可を指定」より「JSON」を選択し、ポリシーエディタに以下を貼り付け、「次へ」を選択する。
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "S3ListAllMyBuckets",
            "Effect": "Allow",
            "Action": [
                "s3:ListAllMyBuckets"
            ],
            "Resource": "*"
        }
    ]
}
  1. 「ポリシーの詳細」の「ポリシー名」に「LambdaS3ListBucketsPolicy」を入力し、「ポリシーの作成」を選択する。
  1. 作成完了のメッセージを確認する。

2. アカウント1のロール作成

アカウント1にてLambda関数に適用するロールを作成します。

ロール作成手順

  1. アカウント1でログインし、IAMコンソールよりロールを開き、「ロールを作成」を選択する。
  1. 「信頼されたエンティティタイプ」に「AWSのサービス」を、「ユースケース」の「サービスまたはユースケース」に「Lambda」、「ユースケース」に「Lambda」を選択し、「次へ」を選択する。
  1. 「許可を追加」は何もせず、「次へ」を選択する。
  1. 「ロールの詳細」の「ロール名」に「Lambda-Assume-Roles」を入力する。
  1. 「ロールを作成」を選択する。
  1. 作成完了のメッセージを確認し、「ロールを表示」を選択する。
  1. 「概要」の「ARN」をコピーする。(とあるが実際は使わない。)
  1. 「許可」タブより、「許可を追加」にある「インラインポリシーを作成」を選択する。
  1. 「アクセス許可を指定」より「JSON」を選択し、「ポリシーエディタ」に以下を貼り付け、「次へ」を選択する。<account1>にはアカウント1のAWSアカウントID(ダッシュなし12桁)、<account2>にはアカウント2のAWSアカウントID(ダッシュなし12桁)を、必要に応じてリージョンを置き換える。
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "stsassumerole",
            "Effect": "Allow",
            "Action": "sts:AssumeRole",
            "Resource": "arn:aws:iam::<account2>:role/LambdaS3ListBuckets",
            "Condition": {
                "StringLike": {
                    "aws:UserAgent": "*AWS_Lambda_python*"
                }
            }
        },
        {
            "Sid": "logsstreamevent",
            "Effect": "Allow",
            "Action": [
                "logs:CreateLogStream",
                "logs:PutLogEvents"
            ],
            "Resource": "arn:aws:logs:us-east-1:<account1>:log-group:/aws/lambda/Lambda-Assume-Roles*/*"
        },
        {
            "Sid": "logsgroup",
            "Effect": "Allow",
            "Action": "logs:CreateLogGroup",
            "Resource": "*"
        }
    ]
}
  1. 「ポリシーの詳細」の「ポリシー名」に「Lambda-Assume-Roles-Policy」を入力し、「ポリシーを作成」を選択する。
  1. 作成完了のメッセージを確認する。

3. アカウント1のLambda関数作成

アカウント2のS3バケット一覧を取得するLambda関数をアカウント1にて作成します。

Lambda関数作成手順

  1. アカウント1でログインし、Lambdaコンソールの関数を開き、「関数の作成」を選択する。
  1. 「関数の作成」では「一から作成」を選択し、「関数名」に「Lambda-Assume-Roles」、「ランタイム」に「Python 3.11」を選択する。
  1. 「デフォルトの実行ロールの変更」を開き、「実行ロール」で「既存のロールを使用する」を選択の上、「既存のロール」に「Lambda-Assume-Roles」を選択する。「関数の作成」を選択する。
  1. 作成完了のメッセージを確認する。
  1. 「コード」タブの「コードソース」に以下を貼り付け、「Deploy」を選択する。<enterAccount2CopiedARNhere>にはアカウント2で作成したロールのARNを置き換える。
import json
import boto3
import os
import uuid

def lambda_handler(event, context):
    try:
        account2RoleArn='<enterAccount2CopiedARNhere>'
        client = boto3.client('sts')
        response = client.assume_role(RoleArn=account2RoleArn,RoleSessionName="{}-s3".format(str(uuid.uuid4())[:5]))
        session = boto3.Session(aws_access_key_id=response['Credentials']['AccessKeyId'],aws_secret_access_key=response['Credentials']['SecretAccessKey'],aws_session_token=response['Credentials']['SessionToken'])

        s3 = session.client('s3')
        s3list = s3.list_buckets()
        print (s3list)
        return str(s3list['Buckets'])

    except Exception as e:
        print(e)
        raise e
  1. 正常更新のメッセージを確認する。
  1. 「テスト」タブに「テスト」を選択する。
  1. 最初の数回はタイムアウトエラーが発生する。成功するとLambda実行結果を確認する。

Appendix. クリーンアップ手順

作成したリソースのクリーンアップ手順です。

Lambda削除手順

  1. アカウント1でログインし、Lambdaコンソールより関数を開き、作成した関数「Lambda-Assume-Roles」をオンにした上で、「アクション」より「削除」を選択する。
  1. 「1関数の削除」の最下部の入力ボックスに「削除」を入力し、「削除」を選択する。
  1. 「1関数の削除」で削除が完了し、「閉じる」を選択する。

アカウント1のロール削除手順

  1. アカウント1でログインし、IAMコンソールよりロールを開き、作成したロール「Lambda-Assume-Roles」をオンにした上で、「削除」を選択する。
  1. 「Lambda-Assume-Rolesを削除しますか?」の最下部の入力ボックスに「Lambda-Assume-Roles」を入力し、「削除」を選択する。
  1. 削除完了のメッセージを確認する。

アカウント2のロール削除手順

  1. アカウント2でログインし、IAMコンソールよりロールを開き、作成したロール「LambdaS3ListBuckets」をオンにした上で、「削除」を選択する。
  1. 「LambdaS3ListBucketsを削除しますか?」の最下部の入力ボックスに「LambdaS3ListBuckets」を入力し、「削除」を選択する。
  1. 削除完了のメッセージを確認する。
タイトルとURLをコピーしました