Accessing two tables from different accounts within the same lambda function
Asked Answered
U

3

7

Is it possible to access two tables within one lambda function while one of the tables is in the same account as the lambda function and the other is in another account?

I've seen articles on cross-account access delegation using IAM roles here and there. But I'm not sure how the code should reflect accessing a resource from another account. This is how I usually access some DynamoDb table:

const dynamodb = new AWS.DynamoDB();
const docClient = new AWS.DynamoDB.DocumentClient({ service: dynamodb });
docClient
  .get({
    TableName: 'SomeTable',
    Key: { id }
  });

Looking at the documentation, there's no mention of account ID in the constructor. So I'm not sure how I can have two connections at the same time, one pointing to one account and the other pointing to another account!?

Unbeknown answered 14/2, 2019 at 14:8 Comment(2)
Possible duplicate of AWS: Boto3: AssumeRole example which includes role usageCissy
@Cissy I honestly don't see how that question has anything to do with mine! Maybe because that question is in Python and mine is in Nodejs. But that does not help me at all.Unbeknown
C
15

Yes, it's possible to access 2 dynamoDb Tables (1 is in another AWS account) from same lambda function.

It's straight-forward to access the same Account's DynamoDB table.

dynamodb_client_of_same_account = boto3.client('dynamodb', region_name='us-east-1')

To access the Table of another AWS account, a new dynamoDb client needs to be created. You need to create cross account IAM Role and use STS to get temporary credentials. Follow the below steps to create cross account role.

AWS Account A has Lambda-----trying read/write on-----> AWS Account B with DynamoDB

Create an IAM Role in Account B to establish a Trust Relationship with Account A.

  1. Go to IAM Role -------> Create Role ------> Select *Another AWS account *in the widget-----> Type AWS Account A Id and create the role

  2. Don't forget to add DynamoDBAccess policy to this IAM Role.

Attach STS Assume Role policy to your AWS Lambda's Role in Account A

  1. Create a new policy with below JSON and attach this policy to your Lambda Role.

    { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": "sts:AssumeRole", "Resource": "" } ] }

  2. Use the below code to create a new client to access DynamoDB table in another account.

    roleARN = '*<ARN of the role created in Step-1>*'
    client = boto3.client('sts')
    response = client.assume_role(RoleArn=roleARN, 
                                  RoleSessionName='RoleSessionName', 
                                  DurationSeconds=900)
    
    dynamodb_client_for_other_account = boto3.client('dynamodb', region_name='us-east-1',
                aws_access_key_id=response['Credentials']['AccessKeyId'],
                aws_secret_access_key=response['Credentials']['SecretAccessKey'],
                aws_session_token = response['Credentials']['SessionToken'])
    
Cameroun answered 27/4, 2020 at 14:54 Comment(0)
P
1

2024 update: DynamoDB now supports resource-based policies, meaning you can give specific permission to a given account/role and query it directly, without the need to assume role.

Platysma answered 28/7 at 19:17 Comment(0)
S
-1

you could create a IAM user on the second account,
add DynamoDB permissions and get access/key secret for it
and then:

const dynamodb1 = new AWS.DynamoDB();
const dynamodb2 = new AWS.DynamoDB({
    accessKeyId:     'x',
    secretAccessKey: 'y',
    region: 'z',
})

dynamodb1 will work with the role permissions from lambda
and dynamodb2 with the IAM user from the second account

Solenne answered 14/2, 2019 at 15:3 Comment(1)
You could do this, and it would work, but it's not the best practice. The solution is to delegate access across AWS accounts using IAM roles.Emmen

© 2022 - 2024 — McMap. All rights reserved.