[アップデート] 別アカウントのAmazon DynamoDB Streamsをイベントソースマッピングとして設定し、別アカウントからAWS Lambdaを実行できるようになりました
AWS Lambda関数のトリガーとして、別アカウントのAmazon DynamoDB Streamsが指定できるようになったぞ
おのやんです。
AWS Lambda(以下、Lambda)が、Amazon DynamoDB(以下、DynamoDB)Streamsからのクロスアカウントアクセスをサポートするようになりました。
今回は、こちらのアップデートの内容についてまとめ、実際に検証していきたいと思います。
アップデート内容のおさらい
今まで、Lambda関数は同じAWSアカウント内のDynamoDB Streamsしかイベントソースとして使用できませんでした。ですので、別アカウントにDynamoDB Streamsのデータを送信する場合はAmazon EventBridgeやAmazon Data Firehoseなどを噛ませる必要がありました。DynamoDB StreamsのデータをLambda経由で別アカウントに送信する類似の構成は、過去に弊社ブログでもご紹介しています。
今回のアップデートにより、別のAWSアカウントにあるlambda関数のイベントソースとしてDynamoDB Streamsを設定できるようになります。
クロスアカウントアクセスを有効にするには、DynamoDB Streamsにリソースベースのポリシーを設定し、別アカウントのLambda関数からのアクセスを許可、その後にLambda関数のイベントソースマッピングとして、別アカウントのDynamoDB Streamsを指定します。
こちらの機能は、すべてのAWSリージョンと、AWS GovCloud (US) リージョンで利用可能です。
実際にやってみた
それでは、実際にクロスアカウントでDynamoDB StreamsとLambdaを連携させてみましょう。
今回は、2つのAWSアカウントを準備して試してみます。アカウントA(111111111111)にはDynamoDBテーブルとStreamsを配置します。アカウントB(222222222222)にはLambda関数を配置します。また、これらの操作はap-northeast-1(東京リージョン)で実施します。
上記の構成にて、アカウントAのDynamoDBに変更があったときに、アカウントBのLambdaが起動される構成を作ります。

アカウントAでDynamoDBテーブルを作成
まず、アカウントAでDynamoDBテーブルを作成し、Streamsを有効化します。
aws dynamodb create-table \
--table-name CrossAccountTest \
--attribute-definitions AttributeName=id,AttributeType=S \
--key-schema AttributeName=id,KeyType=HASH \
--billing-mode PAY_PER_REQUEST \
--stream-specification StreamEnabled=true,StreamViewType=NEW_AND_OLD_IMAGES \
--region ap-northeast-1
アカウントAにて、DynamoDBテーブルが作成されていますね。

テーブルが作成されたら、Stream ARNを確認しておきます。
aws dynamodb describe-table \
--table-name CrossAccountTest \
--region ap-northeast-1 \
--query 'Table.LatestStreamArn' \
--output text
こちらは後ほど使用しますので、メモしておきます。
arn:aws:dynamodb:ap-northeast-1:111111111111:table/CrossAccountTest/stream/2026-02-01T06:30:25.829
アカウントBでLambda関数を作成
次に、アカウントBでLambda関数を作成します。今回はPython 3.13で簡単なログ出力関数を作成します。
まず、Lambda実行用のIAM信頼ポリシーをJSONファイルに記述します。
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": "lambda.amazonaws.com"
},
"Action": "sts:AssumeRole"
}
]
}
こちらのポリシーを使って、IAMロールを作成します。
aws iam create-role \
--role-name lambda-dynamodb-cross-account-role \
--assume-role-policy-document file://trust-policy.json
こちらのIAMロールに、AWSLambdaDynamoDBExecutionRoleのマネージドポリシーをアタッチします。
aws iam attach-role-policy \
--role-name lambda-dynamodb-cross-account-role \
--policy-arn arn:aws:iam::aws:policy/service-role/AWSLambdaDynamoDBExecutionRole
作成したロールのARNをメモしておきます。
aws iam get-role \
--role-name lambda-dynamodb-cross-account-role \
--query 'Role.Arn' \
--output text
arn:aws:iam::222222222222:role/lambda-dynamodb-cross-account-role
次に、Lambda関数のコードを準備します。この際、さきほどメモしてIAMロールのARNを記載します。
import json
from typing import Any, Dict
def lambda_handler(event: Dict[str, Any], context: Any) -> Dict[str, Any]:
print('Received event:', json.dumps(event, indent=2, ensure_ascii=False))
for record in event['Records']:
print(f"EventID: {record['eventID']}")
print(f"EventName: {record['eventName']}")
print(f"DynamoDB: {json.dumps(record['dynamodb'], indent=2, ensure_ascii=False)}")
return {'statusCode': 200, 'body': 'Success'}
このコードをZIPで圧縮し、デプロイします。
$ zip function.zip lambda_function.py
$ aws lambda create-function \
--function-name CrossAccountDynamoDBHandler \
--runtime python3.13 \
--role arn:aws:iam::222222222222:role/lambda-dynamodb-cross-account-role \
--handler lambda_function.lambda_handler \
--zip-file fileb://function.zip \
--region ap-northeast-1
Lambda関数がデプロイできました。

アカウントAでDynamoDB Streamsのリソースベースポリシーを設定
次に、アカウントAのDynamoDB Streamsに、アカウントBのLambda関数がアクセスできるリソースベースのポリシーを設定します。この際、さきほどメモしてDynamoDB StreamsとIAMロールのARNを記述します。
aws dynamodb put-resource-policy \
--resource-arn arn:aws:dynamodb:ap-northeast-1:111111111111:table/CrossAccountTest/stream/2026-02-01T06:30:25.829 \
--policy '{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::222222222222:role/lambda-dynamodb-cross-account-role"
},
"Action": [
"dynamodb:DescribeStream",
"dynamodb:GetRecords",
"dynamodb:GetShardIterator"
],
"Resource": "arn:aws:dynamodb:ap-northeast-1:111111111111:table/CrossAccountTest/stream/2026-02-01T06:30:25.829"
}
]
}' \
--region ap-northeast-1
クロスアカウントアクセスする際の、DynamoDBのリソースベースのポリシーについては、こちらをご参照ください。
こちらの操作にて、DynamoDB Streamsのリソースベースのポリシーが設定できました。

このポリシーにより、アカウントBのLambda実行ロールがアカウントAのDynamoDB Streamsを読み取れるようになります。
アカウントBでイベントソースマッピングを作成
次に、アカウントBのLambda関数のトリガーとして、アカウントAのDynamoDB Streamsを設定します。ここでも、先ほどメモしたDynamoDB StreamsのARNを使用します。
aws lambda create-event-source-mapping \
--function-name CrossAccountDynamoDBHandler \
--event-source-arn arn:aws:dynamodb:ap-northeast-1:111111111111:table/CrossAccountTest/stream/2026-02-01T06:30:25.829 \
--starting-position LATEST \
--region ap-northeast-1
アカウントBのLambda関数のトリガーとして、アカウントAのDynamoDB Streamsを設定できました。

イベントソースマッピングが作成されると、アカウントBのLambdaがアカウントAのDynamoDB Streamsをポーリングし始めます。
動作確認
それでは、アカウントAのDynamoDBに実際にデータを挿入して、クロスアカウントで動作するか確認してみましょう。
aws dynamodb put-item \
--table-name CrossAccountTest \
--item '{"id": {"S": "test-001"}, "name": {"S": "Test User"}, "email": {"S": "test@example.com"}}' \
--region ap-northeast-1
DynamoDBにデータが挿入されました。

アカウントBのLambda関数のCloudWatch Logsを確認すると、DynamoDBのイベント情報が書かれたログが確認できました!

コマンドでも、こんな感じでログを取得できました。
$ aws logs tail /aws/lambda/CrossAccountDynamoDBHandler --follow --region ap-northeast-1
2026-02-01T07:03:58.084000+00:00 2026/02/01/[$LATEST]0d610dcf62874d3e9980e597d1b3d770 INIT_START Runtime Version: python:3.13.v77 Runtime Version ARN: arn:aws:lambda:ap-northeast-1::runtime:2c989696daccfc69ccb5167bebf22a3274048af875cacc431bdb8442374348aa
2026-02-01T07:03:58.217000+00:00 2026/02/01/[$LATEST]0d610dcf62874d3e9980e597d1b3d770 START RequestId: 3f79919b-70f1-4c3a-8db6-144abc39ab55 Version: $LATEST
2026-02-01T07:03:58.218000+00:00 2026/02/01/[$LATEST]0d610dcf62874d3e9980e597d1b3d770 Received event: {
2026-02-01T07:03:58.218000+00:00 2026/02/01/[$LATEST]0d610dcf62874d3e9980e597d1b3d770 "Records": [
2026-02-01T07:03:58.218000+00:00 2026/02/01/[$LATEST]0d610dcf62874d3e9980e597d1b3d770 {
2026-02-01T07:03:58.218000+00:00 2026/02/01/[$LATEST]0d610dcf62874d3e9980e597d1b3d770 "eventID": "8adc758361089d9e8b12b0a1cc6338ea",
2026-02-01T07:03:58.218000+00:00 2026/02/01/[$LATEST]0d610dcf62874d3e9980e597d1b3d770 "eventName": "INSERT",
2026-02-01T07:03:58.218000+00:00 2026/02/01/[$LATEST]0d610dcf62874d3e9980e597d1b3d770 "eventVersion": "1.1",
2026-02-01T07:03:58.218000+00:00 2026/02/01/[$LATEST]0d610dcf62874d3e9980e597d1b3d770 "eventSource": "aws:dynamodb",
2026-02-01T07:03:58.218000+00:00 2026/02/01/[$LATEST]0d610dcf62874d3e9980e597d1b3d770 "awsRegion": "ap-northeast-1",
2026-02-01T07:03:58.218000+00:00 2026/02/01/[$LATEST]0d610dcf62874d3e9980e597d1b3d770 "dynamodb": {
2026-02-01T07:03:58.218000+00:00 2026/02/01/[$LATEST]0d610dcf62874d3e9980e597d1b3d770 "ApproximateCreationDateTime": 1769929437.0,
2026-02-01T07:03:58.218000+00:00 2026/02/01/[$LATEST]0d610dcf62874d3e9980e597d1b3d770 "Keys": {
2026-02-01T07:03:58.218000+00:00 2026/02/01/[$LATEST]0d610dcf62874d3e9980e597d1b3d770 "id": {
2026-02-01T07:03:58.218000+00:00 2026/02/01/[$LATEST]0d610dcf62874d3e9980e597d1b3d770 "S": "test-001"
2026-02-01T07:03:58.218000+00:00 2026/02/01/[$LATEST]0d610dcf62874d3e9980e597d1b3d770 }
2026-02-01T07:03:58.218000+00:00 2026/02/01/[$LATEST]0d610dcf62874d3e9980e597d1b3d770 },
2026-02-01T07:03:58.218000+00:00 2026/02/01/[$LATEST]0d610dcf62874d3e9980e597d1b3d770 "NewImage": {
2026-02-01T07:03:58.218000+00:00 2026/02/01/[$LATEST]0d610dcf62874d3e9980e597d1b3d770 "name": {
2026-02-01T07:03:58.218000+00:00 2026/02/01/[$LATEST]0d610dcf62874d3e9980e597d1b3d770 "S": "Test User"
2026-02-01T07:03:58.218000+00:00 2026/02/01/[$LATEST]0d610dcf62874d3e9980e597d1b3d770 },
2026-02-01T07:03:58.218000+00:00 2026/02/01/[$LATEST]0d610dcf62874d3e9980e597d1b3d770 "id": {
2026-02-01T07:03:58.218000+00:00 2026/02/01/[$LATEST]0d610dcf62874d3e9980e597d1b3d770 "S": "test-001"
2026-02-01T07:03:58.218000+00:00 2026/02/01/[$LATEST]0d610dcf62874d3e9980e597d1b3d770 },
2026-02-01T07:03:58.218000+00:00 2026/02/01/[$LATEST]0d610dcf62874d3e9980e597d1b3d770 "email": {
2026-02-01T07:03:58.218000+00:00 2026/02/01/[$LATEST]0d610dcf62874d3e9980e597d1b3d770 "S": "test@example.com"
2026-02-01T07:03:58.218000+00:00 2026/02/01/[$LATEST]0d610dcf62874d3e9980e597d1b3d770 }
2026-02-01T07:03:58.218000+00:00 2026/02/01/[$LATEST]0d610dcf62874d3e9980e597d1b3d770 },
2026-02-01T07:03:58.218000+00:00 2026/02/01/[$LATEST]0d610dcf62874d3e9980e597d1b3d770 "SequenceNumber": "109600002442871503720585",
2026-02-01T07:03:58.218000+00:00 2026/02/01/[$LATEST]0d610dcf62874d3e9980e597d1b3d770 "SizeBytes": 54,
2026-02-01T07:03:58.218000+00:00 2026/02/01/[$LATEST]0d610dcf62874d3e9980e597d1b3d770 "StreamViewType": "NEW_AND_OLD_IMAGES"
2026-02-01T07:03:58.218000+00:00 2026/02/01/[$LATEST]0d610dcf62874d3e9980e597d1b3d770 },
2026-02-01T07:03:58.218000+00:00 2026/02/01/[$LATEST]0d610dcf62874d3e9980e597d1b3d770 "eventSourceARN": "arn:aws:dynamodb:ap-northeast-1:111111111111:table/CrossAccountTest/stream/2026-02-01T06:30:25.829"
2026-02-01T07:03:58.218000+00:00 2026/02/01/[$LATEST]0d610dcf62874d3e9980e597d1b3d770 }
2026-02-01T07:03:58.218000+00:00 2026/02/01/[$LATEST]0d610dcf62874d3e9980e597d1b3d770 ]
2026-02-01T07:03:58.218000+00:00 2026/02/01/[$LATEST]0d610dcf62874d3e9980e597d1b3d770 }
2026-02-01T07:03:58.218000+00:00 2026/02/01/[$LATEST]0d610dcf62874d3e9980e597d1b3d770 EventID: 8adc758361089d9e8b12b0a1cc6338ea
2026-02-01T07:03:58.218000+00:00 2026/02/01/[$LATEST]0d610dcf62874d3e9980e597d1b3d770 EventName: INSERT
2026-02-01T07:03:58.218000+00:00 2026/02/01/[$LATEST]0d610dcf62874d3e9980e597d1b3d770 DynamoDB: {
2026-02-01T07:03:58.218000+00:00 2026/02/01/[$LATEST]0d610dcf62874d3e9980e597d1b3d770 "ApproximateCreationDateTime": 1769929437.0,
2026-02-01T07:03:58.218000+00:00 2026/02/01/[$LATEST]0d610dcf62874d3e9980e597d1b3d770 "Keys": {
2026-02-01T07:03:58.218000+00:00 2026/02/01/[$LATEST]0d610dcf62874d3e9980e597d1b3d770 "id": {
2026-02-01T07:03:58.218000+00:00 2026/02/01/[$LATEST]0d610dcf62874d3e9980e597d1b3d770 "S": "test-001"
2026-02-01T07:03:58.218000+00:00 2026/02/01/[$LATEST]0d610dcf62874d3e9980e597d1b3d770 }
2026-02-01T07:03:58.218000+00:00 2026/02/01/[$LATEST]0d610dcf62874d3e9980e597d1b3d770 },
2026-02-01T07:03:58.218000+00:00 2026/02/01/[$LATEST]0d610dcf62874d3e9980e597d1b3d770 "NewImage": {
2026-02-01T07:03:58.218000+00:00 2026/02/01/[$LATEST]0d610dcf62874d3e9980e597d1b3d770 "name": {
2026-02-01T07:03:58.218000+00:00 2026/02/01/[$LATEST]0d610dcf62874d3e9980e597d1b3d770 "S": "Test User"
2026-02-01T07:03:58.218000+00:00 2026/02/01/[$LATEST]0d610dcf62874d3e9980e597d1b3d770 },
2026-02-01T07:03:58.218000+00:00 2026/02/01/[$LATEST]0d610dcf62874d3e9980e597d1b3d770 "id": {
2026-02-01T07:03:58.218000+00:00 2026/02/01/[$LATEST]0d610dcf62874d3e9980e597d1b3d770 "S": "test-001"
2026-02-01T07:03:58.218000+00:00 2026/02/01/[$LATEST]0d610dcf62874d3e9980e597d1b3d770 },
2026-02-01T07:03:58.218000+00:00 2026/02/01/[$LATEST]0d610dcf62874d3e9980e597d1b3d770 "email": {
2026-02-01T07:03:58.218000+00:00 2026/02/01/[$LATEST]0d610dcf62874d3e9980e597d1b3d770 "S": "test@example.com"
2026-02-01T07:03:58.218000+00:00 2026/02/01/[$LATEST]0d610dcf62874d3e9980e597d1b3d770 }
2026-02-01T07:03:58.218000+00:00 2026/02/01/[$LATEST]0d610dcf62874d3e9980e597d1b3d770 },
2026-02-01T07:03:58.218000+00:00 2026/02/01/[$LATEST]0d610dcf62874d3e9980e597d1b3d770 "SequenceNumber": "109600002442871503720585",
2026-02-01T07:03:58.218000+00:00 2026/02/01/[$LATEST]0d610dcf62874d3e9980e597d1b3d770 "SizeBytes": 54,
2026-02-01T07:03:58.218000+00:00 2026/02/01/[$LATEST]0d610dcf62874d3e9980e597d1b3d770 "StreamViewType": "NEW_AND_OLD_IMAGES"
2026-02-01T07:03:58.218000+00:00 2026/02/01/[$LATEST]0d610dcf62874d3e9980e597d1b3d770 }
2026-02-01T07:03:58.220000+00:00 2026/02/01/[$LATEST]0d610dcf62874d3e9980e597d1b3d770 END RequestId: 3f79919b-70f1-4c3a-8db6-144abc39ab55
2026-02-01T07:03:58.223000+00:00 2026/02/01/[$LATEST]0d610dcf62874d3e9980e597d1b3d770 REPORT RequestId: 3f79919b-70f1-4c3a-8db6-144abc39ab55 Duration: 2.28 ms Billed Duration: 132 ms Memory Size: 128 MB Max Memory Used: 38 MB Init Duration: 129.19 ms
アカウントを分離している環境だと特に嬉しい
AWS Lambdaが別アカウントのDynamoDB Streamsをイベントソースとして使えるようになりました。特に複数のアカウントを事業部別などで管理している環境ですと、別アカウントのDynamoDB Streamsから直接Lambdaを呼び出せるので、非常に便利です。
マルチアカウント構成でDynamoDBとLambdaを使っている場合はぜひ活用してみてください。では!







