1
votes

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:

  1. add a role in account B with the policy for using that dynamoDB table
  2. add a trust policy to that role to be assumed by the account B
  3. assume that role from account A and then attach this role to lambda function.

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 ?

1

1 Answers

1
votes

Just in case someone has the same issue, it's resolved now. Here is the steps required:

Lambda function – “Lambda_DDBTest” with Lambda execution role < LambdaExecutionRole > are present in Account A DynanmoDB table – “LambdaTest” is present in Account B This Lambda function is trying to access the DynamoDB table from Account B and below are steps to be followed to setup IAM configurations.

Step1 : Create a Role in Account B to provide access to Lambda function to assume role for Account B.

  1. Sign in to the AWS Management Console as an administrator of the target account, and open the IAM console.

  2. In the navigation pane on the left, choose “Roles” and Click on the "Create New Role" button, enter a role name and click "Next"

  3. In the next page Select button related to "Another AWS account: Belonging to you or 3rd party"

  4. 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).

  5. In the next window click on the checkbox for "AmazonDynamoDBFullAccess" and click "Next Step"

  6. Review your settings and type the role name (e.g. ‘crossaccount-LambdaDDB’)

  7. 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:::role/" } }

  • Copy your Account A – Lambda Function execution role ARN and replace it with ARN in resource

Screenshot

Step 2 – Configuration to be made in Lambda function execution role in Account A

  1. Go to Account A - Lambda function execution role IAM page.

  2. Provide "AmazonDynamoDBFullAccess" in order for your Lambda function to have permissions to perform DynamoDB operations.

  3. Add the Account B’s role created in Step 1 to Lambda function execution role by adding inline policy as follows:

    { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": "sts:AssumeRole", "Resource": " arn:aws:iam:::role/crossaccount-LambdaDDB” } ] }

enter image description here

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
)
return response
return "Lambda to DDB Access was Successful"

Reference:

https://aws.amazon.com/premiumsupport/knowledge-center/lambda-function-assume-iam-role/