0
votes

I have a lambda function in account A trying to access resources from account B. Created a new lambda role with basic execution with access to upload logs to cloud watch.

Here's my function code in Python 3.7:

import boto3

allProfiles = ['account2']

def lambda_handler(event, context):

    sts_connection = boto3.client('sts')
    acct_b = sts_connection.assume_role(
        RoleArn="arn:aws:iam::2222222222:role/role-on-source-account",
        RoleSessionName="account2"
    )

    for profiles in allProfiles:
        print("\nusing profile %s" % profiles)
        newMethod..
    return {
        'statusCode': 200,
        'body': json.dumps('Hello from Lambda!')
    }

Also modified the trust policy of the assumed role in account B as mentioned in documentation: https://aws.amazon.com/premiumsupport/knowledge-center/lambda-function-assume-iam-role/

ERROR: An error occurred (AccessDenied) when calling the AssumeRole operation: User: arn:aws:sts::11111111:assumed-role/lambda-role/lambda-function is not authorized to perform: sts:AssumeRole on resource: arn:aws:iam::2222222222:role/role-on-source-account"

Note: I am able to run this in my local successfully but not in lambda.

2

2 Answers

1
votes

Ok so what we have is:

  • Your (your own trusted account) accountA need to assume a specific role in the AccountB account
  • A role in the AccountB (the trusting account) that your lambda is going to access a, let's say a bucket on.

  • AccountBBucket

You mentioned you had Basic execution for your lambda and that alone would not be enough...

Solution:

  1. Create a role "UpdateBucket": you need to establish trust between AccountB(account ID number:999) and AccountA.
    Create an IAM role and define the AccountA as a trusted entity, specify a permission policy that allows trusted users to update the AccountB_resource(AccountBBucket).
    We Are in AccountA now

    
    
    {
      "Version": "2012-10-17",
      "Statement": [
        {
          "Effect": "Allow",
          "Action": "s3:ListAllMyBuckets",
          "Resource": "*"
        },
        {
          "Effect": "Allow",
          "Action": [
            "s3:ListBucket",
            "s3:GetBucketLocation"
           ],
          "Resource": "arn:aws:s3:::AccountBBucket"
        },
        {
          "Effect": "Allow",
          "Action": [
            "s3:GetObject",
            "s3:PutObject",
            "s3:DeleteObject"
          ],
          "Resource": "arn:aws:s3:::AccountBBucket/*"
        }
      ]
    }
    
    
  2. Grant Access:
    we will now use the role we created earlier, the (UpdateBucket) role
    This needs to be added to your AccountB permissions
    We are now in AccountB now:

    {
      "Version": "2012-10-17",
      "Statement": {
        "Effect": "Allow",
        "Action": "sts:AssumeRole",
        "Resource": "arn:aws:iam::999:role/UpdateBucket"
      }
    }
    
    Note that the 999 above is AccountB account Id and the UpdateBucket is the role that was created in AccountA
    This would create the trust you need for your lambda to access the bucket on AccountB

More info on here: Delegate Access Across AWS Accounts Using IAM Roles

4
votes

Created a new lambda role with basic execution with access to upload logs to cloud watch

Basic execution role for lambda is not enough. You need to explicitly allow your function to AssumeRole. The following statement in your execution role should help:

{
  "Effect": "Allow",
  "Action": [
    "sts:AssumeRole"
  ],
  "Resource": [
    "arn:aws:iam::2222222222:role/role-on-source-account"
  ]
}