元ネタ
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より参照可能にするためにロールを作成します。
ロール作成手順
- アカウント2でログインし、IAMコンソールよりロールを開き、「ロールを作成」を選択する。
- 「信頼されたエンティティタイプ」に「AWSアカウント」を選択する。「AWSアカウント」では「別のAWSアカウント」を選択した上で、「アカウントID」にアカウント1のAWSアカウントID(ダッシュなし12桁)を入力し、「次へ」を選択する。
- 「許可を追加」では変更せず、「次へ」を選択する。
- 「ロールの詳細」の「ロール名」に「LambdaS3ListBuckets」を入力する。
- 「ロールを作成」を選択する。
- 作成完了のメッセージを確認し、「ロールを表示」を選択する。
- 表示された「概要」より、中央の「ARN」をコピーしておく。
- 「許可」タブより、「許可を追加」にある「インラインポリシーを作成」を選択する。
- 「アクセス許可を指定」より「JSON」を選択し、ポリシーエディタに以下を貼り付け、「次へ」を選択する。
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "S3ListAllMyBuckets",
"Effect": "Allow",
"Action": [
"s3:ListAllMyBuckets"
],
"Resource": "*"
}
]
}
- 「ポリシーの詳細」の「ポリシー名」に「LambdaS3ListBucketsPolicy」を入力し、「ポリシーの作成」を選択する。
- 作成完了のメッセージを確認する。
2. アカウント1のロール作成
アカウント1にてLambda関数に適用するロールを作成します。
ロール作成手順
- アカウント1でログインし、IAMコンソールよりロールを開き、「ロールを作成」を選択する。
- 「信頼されたエンティティタイプ」に「AWSのサービス」を、「ユースケース」の「サービスまたはユースケース」に「Lambda」、「ユースケース」に「Lambda」を選択し、「次へ」を選択する。
- 「許可を追加」は何もせず、「次へ」を選択する。
- 「ロールの詳細」の「ロール名」に「Lambda-Assume-Roles」を入力する。
- 「ロールを作成」を選択する。
- 作成完了のメッセージを確認し、「ロールを表示」を選択する。
- 「概要」の「ARN」をコピーする。(とあるが実際は使わない。)
- 「許可」タブより、「許可を追加」にある「インラインポリシーを作成」を選択する。
- 「アクセス許可を指定」より「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": "*"
}
]
}
- 「ポリシーの詳細」の「ポリシー名」に「Lambda-Assume-Roles-Policy」を入力し、「ポリシーを作成」を選択する。
- 作成完了のメッセージを確認する。
3. アカウント1のLambda関数作成
アカウント2のS3バケット一覧を取得するLambda関数をアカウント1にて作成します。
Lambda関数作成手順
- アカウント1でログインし、Lambdaコンソールの関数を開き、「関数の作成」を選択する。
- 「関数の作成」では「一から作成」を選択し、「関数名」に「Lambda-Assume-Roles」、「ランタイム」に「Python 3.11」を選択する。
- 「デフォルトの実行ロールの変更」を開き、「実行ロール」で「既存のロールを使用する」を選択の上、「既存のロール」に「Lambda-Assume-Roles」を選択する。「関数の作成」を選択する。
- 作成完了のメッセージを確認する。
- 「コード」タブの「コードソース」に以下を貼り付け、「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
- 正常更新のメッセージを確認する。
- 「テスト」タブに「テスト」を選択する。
- 最初の数回はタイムアウトエラーが発生する。成功するとLambda実行結果を確認する。
Appendix. クリーンアップ手順
作成したリソースのクリーンアップ手順です。
Lambda削除手順
- アカウント1でログインし、Lambdaコンソールより関数を開き、作成した関数「Lambda-Assume-Roles」をオンにした上で、「アクション」より「削除」を選択する。
- 「1関数の削除」の最下部の入力ボックスに「削除」を入力し、「削除」を選択する。
- 「1関数の削除」で削除が完了し、「閉じる」を選択する。
アカウント1のロール削除手順
- アカウント1でログインし、IAMコンソールよりロールを開き、作成したロール「Lambda-Assume-Roles」をオンにした上で、「削除」を選択する。
- 「Lambda-Assume-Rolesを削除しますか?」の最下部の入力ボックスに「Lambda-Assume-Roles」を入力し、「削除」を選択する。
- 削除完了のメッセージを確認する。
アカウント2のロール削除手順
- アカウント2でログインし、IAMコンソールよりロールを開き、作成したロール「LambdaS3ListBuckets」をオンにした上で、「削除」を選択する。
- 「LambdaS3ListBucketsを削除しますか?」の最下部の入力ボックスに「LambdaS3ListBuckets」を入力し、「削除」を選択する。
- 削除完了のメッセージを確認する。