Edited at

AWS STSを使って、Lambdaから別環境のDynamoDBにクロスアカウントアクセスする


注意

当記事を参考にし実装された内容に関して、当記事は責任を負いません。

あくまでも自分向けに記録したものであり、

ご参考いただく際は各自ご判断ください。


参考

当記事は、こちらの記事を参考にさせていただきました。ありがとうございます。

https://dev.classmethod.jp/cloud/aws/assume-role-in-lambda-function/


何をするの?

AWS STSを使って、Lambdaから別環境のDynamoDBにクロスアカウントアクセスします。

とある案件で、自社サービスを運用しているAアカウントから、追加機能をBアカウントに移行しました。

ただし、追加機能の設定テーブルはAアカウントのままで、BアカウントのLambdaからAアカウントのDynamoDBを参照しないといけない状況でした。

アクセスキーを発行してもいいのですが、それを保存するDBはどうするのか…などの問題があり、今回はクロスアカウントアクセスというものを試してみました。


やること

STSを使い、AssumeRoleをし、発行した一時キーを使ってアカウントを跨いでLambda→DynamoDBのアクセスを行います。

以下、AアカウントのLambda → BアカウントのDynamoDBテーブルのクロスアカウントアクセスの設定方法です。


IAMの準備

AアカウントとBアカウントの両方でロールを作成する必要があります。

Aアカウントのロール…参照元。LambdaにSTSの権限を与えるポリシーをアタッチしたロール

Bアカウントのロール…参照先。信頼したアカウントIDのLambdaからのアクセスを特定のサービスに許可するポリシーをアタッチしたロール


参照元のロールの設定(Aアカウント側)

Lambda関数を作成し、新規ロールを作成して紐付けてください。

以下はそのロールの編集です。

[アクセス権限]>[インラインポリシーの追加]から以下のポリシーを追加してください。

IAM_Management_Console.png

{

"Version": "2012-10-17",
"Statement": {
"Effect": "Allow",
"Action": "sts:AssumeRole",
"Resource": "参照先のロールのARN"
}
}


参照先のロールの設定(Bアカウント側)

参照先のBアカウントでロールを作成し、[信頼関係]>[信頼関係の編集]から、信頼するロールを記述します。

IAM_Management_Console.png

以下のポリシーを上書きしてください。

{

"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": "許可するアカウントのロールのARN"
},
"Action": "sts:AssumeRole",
"Condition": {}
}
]
}

[アクセス権限]>[インラインポリシーの追加]から以下のポリシーを追加してください。

{

"Version": "2012-10-17",
"Statement": [
{
"Sid": "VisualEditor0",
"Effect": "Allow",
"Action": [
"dynamodb:GetItem",
"dynamodb:Scan",
"dynamodb:Query",
"dynamodb:GetRecords"
],
"Resource": "許可するDynamoDBテーブルのARN"
}
]
}


STSを利用したLambdaのコーディング(Python 3.7)

STSで発行した一時キーを利用し、信頼関係にあるDynamoDBからget_itemします。

role_arn はクロスアカウントアクセスを許可しているロールのARNを当ててください。


caa.py

import boto3

from boto3.session import Session

def get_sts_session():
role_arn = "リソース側のロールのARN" # クロスアカウントアクセスを許可しているロール
session_name = "なんか適当な名前"
region = "us-east-1"
client = boto3.client('sts')

# assume_roleでロールに設定された権限のクレデンシャル(一時キー)を発行する
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 get_item_cross_account(session):
# 新しく発行したsessionを使って実行する
dynamodb = session.resource("dynamodb")
table = dynamodb.Table("hoge")
id = "id001"
items = table.get_item(
Key={
"device_id": id
}
)
print(items)

def lambda_handler(event,context):
session = get_sts_session()
get_item_cross_account(session)


無事、アカウントをまたいでget_itemすることができました!

以上でクロスアカウントアクセスの説明を終わります。

Lambda_Management_Console.png