I have this situation: A dynamoDB table in region X account A and a Lambda function in region Y account B. and I want to write to that dynamoDB table using the lambda function. What I did so far:
but still doesn't work and it throws me AccessDeniedException
.
am I missing something here or is it even possible to do it in this case ?
Here are the steps required to resolve the issue:
Lambda_DDBTest
with Lambda execution role <LambdaExecutionRole>
are present in Account ALambdaTest
is present in Account BSign in to the AWS Management Console as an administrator of the target account, and open the IAM console.
In the navigation pane on the left, choose “Roles” and Click on the "Create New Role" button, enter a role name and click "Next"
In the next page Select button related to "Another AWS account: Belonging to you or 3rd party"
Enter in the Account ID of the Source Account and in Options Select “Require external ID” and give it an External ID value (e.g. I gave “testcrossaccountddb”). Note down the External ID value for later (we use it in lambda function).
In the next window click on the checkbox for "AmazonDynamoDBFullAccess" and click "Next Step"
Review your settings and type the role name (e.g. ‘crossaccount-LambdaDDB’)
After reviewing the role, choose “Create role”. Once the Role is created, you can see it in the Roles list. Open the Role again, add an inline policy to add lambda function execution role from Account A to allow assume role to access DynamoDB table from Account B.
{
"Version": "2012-10-17",
"Statement": {
"Effect": "Allow",
"Action": "sts:AssumeRole",
"Resource": "arn:aws:iam::<Account A>:role/<LambdaExecutionRole>"
}
}
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "sts:AssumeRole",
"Resource": " arn:aws:iam::<Account B>:role/crossaccount-LambdaDDB”
}
]
}
Once I made the above configurations, I used the below python boto3 sample code in Lambda function to access DynamoDB table ‘LambdaTest’ in Account B. In this sample code I tried to scan the table and insert a new item into that table.
import json
import boto3
import time
from boto3.dynamodb.conditions import Key, Attr
DDB_TABLE = '<Account B Table name>' # this is the table in your account that you want to put data to
regionValue = '<Account B table region>'
def lambda_handler(context, event):
sts_connection = boto3.client('sts')
acct_b = sts_connection.assume_role(
RoleArn="arn:aws:iam::<Account B Number>:role/<Account B Role Created in Step 1 of Documnet>",
RoleSessionName="cross_acct_lambda",
ExternalId="testcrossaccountddb"
)
ACCESS_KEY = acct_b['Credentials']['AccessKeyId']
SECRET_KEY = acct_b['Credentials']['SecretAccessKey']
SESSION_TOKEN = acct_b['Credentials']['SessionToken']
# create service client using the assumed role credentials, e.g. dynamodbddbOne = boto3.client(
'dynamodb',
region_name=regionValue,
aws_access_key_id=ACCESS_KEY,
aws_secret_access_key=SECRET_KEY,
aws_session_token=SESSION_TOKEN,
)
ddbOne.put_item(TableName=DDB_TABLE, Item={'Id':{'S':'LambdatoDDB_CrossAccount Successful'}})
print("Let's start scanning")
response=ddbOne.scan(
TableName=DDB_TABLE
)
print("Lambda to DDB Access was Successful")
return response
https://aws.amazon.com/premiumsupport/knowledge-center/lambda-function-assume-iam-role/