0

In my use case, I want to access DynamoDB table created in AWS account A and Lambda created in account B. For this I have followed many references on Internet which suggests me to use AWS assume role feature. I have added following permission in Lambda execution role

{
  "Version": "2012-10-17",
  "Statement": {
    "Effect": "Allow",
    "Action": "sts:AssumeRole",
    "Resource": "arn:aws:iam::aws-account-A-number:role/test-db-access"
   }
}

Following is the trust relationship of Lambda

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
           "Service": "lambda.amazonaws.com"
       },
      "Action": "sts:AssumeRole"
    },
    {
      "Effect": "Allow",
      "Principal": {
      "AWS": "arn:aws:iam::aws-account-A-number:root"
       },
     "Action": "sts:AssumeRole"
    }
  ]
}

In account A, I have created role(test-db-access) for allowing others to access this account and added AmazonDynamoDBFullAccess and AdministratorAccess policies. Following is the trust relationship I have added in this account

{
  "Version": "2012-10-17",
   "Statement": [
     {
        "Effect": "Allow",
        "Principal": {
        "AWS": "arn:aws:iam::aws-account-B-number:role/sam-dev-test- 
            TestLambda-LambdaRole-1FH5IC18J0MYT"
         },
       "Action": "sts:AssumeRole"
     },
     {
       "Effect": "Allow",
       "Principal": {
           "Service": "lambda.amazonaws.com"
         },
       "Action": "sts:AssumeRole"
     }
  ]
}

Following is the Java code I have added to access Dynamo DB instance

AssumeRoleRequest assumeRequest = new AssumeRoleRequest()
            .withRoleArn("arn:aws:iam::aws-account-A-number:role/test-db-access").withRoleSessionName("cross_acct_lambda").withDurationSeconds(900);
final AWSSecurityTokenService sts = AWSSecurityTokenServiceClientBuilder.standard().withRegion("eu-west-1").build();
final Credentials credentials = sts.assumeRole(assumeRequest).getCredentials();

following is the crash log coming on executing lambda

{ "errorMessage": "User: arn:aws:sts::aws-account-B-number:assumed-role/sam-dev-test-TestLambda-LambdaRole-1FH5IC18J0MYT/sam-dev-test-TestLambda-LambdaFunction-73TVOBN6VXXX is not authorized to perform: sts:AssumeRole on resource: arn:aws:iam::aws-account-A-number:role/test-db-access (Service: AWSSecurityTokenService; Status Code: 403; Error Code: AccessDenied; Request ID: 100bd3a3-3f9c-11ea-b642-d3b4d9ff35de)", "errorType": "com.amazonaws.services.securitytoken.model.AWSSecurityTokenServiceException" }

4

1 回答 1

3

看来您的要求是:

  • 从 中的 AWS Lambda 函数Account-B,访问 中的 DynamoDB 表Account-A

为了重现您的情况,我执行了以下操作:

  • 在中创建了一个 DynamoDB 表Account-A
  • 使用以下策略创建了一个 IAM 角色 ( Role-A) :Account-A
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": "dynamodb:*",
            "Resource": "arn:aws:dynamodb:ap-southeast-2:<Account-A>:table/Inventory"
        }
    ]
}

而这个信任关系(指向下一步创建的角色):

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "AWS": "arn:aws:iam::<Account-B>:role/role-b"
      },
      "Action": "sts:AssumeRole"
    }
  ]
}
  • 使用以下策略创建了一个 IAM 角色 ( Role-B) 以Account-B用于 Lambda 函数:
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": "sts:AssumeRole",
            "Resource": "arn:aws:iam::<Account-A>:role/role-a"
        }
    ]
}

有了这种信任关系:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "Service": "lambda.amazonaws.com"
      },
      "Action": "sts:AssumeRole"
    }
  ]
}
  • 在其中创建了一个 AWS Lambda 函数Account-B
    • 假设Role-AAccount-A
    • 访问 DynamoDB 表Account-A

我是 Python 人,所以我的功能是:

import boto3

def lambda_handler(event, context):

    # Assume Role
    sts_client = boto3.client('sts')

    response = sts_client.assume_role(
        RoleArn='arn:aws:iam::<Account-A>:role/stack-role-a', 
        RoleSessionName='bar')

    session = boto3.Session(
        aws_access_key_id=response['Credentials']['AccessKeyId'],
        aws_secret_access_key=response['Credentials']['SecretAccessKey'],
        aws_session_token=response['Credentials']['SessionToken']
    )

    # Update DynamoDB
    dynamodb_client = session.client('dynamodb')

    dynamodb_client.update_item(
        TableName='Inventory',
        Key={'Item': {'S': 'foo'}},
        UpdateExpression="ADD #count :increment",
        ExpressionAttributeNames = {
            '#count': 'count'
        },
        ExpressionAttributeValues = {
            ':increment': {'N': '1'},
        }
    ) 

我通过在 中的 Lambda 函数上单击测试对此进行了测试Account-B。它成功更新Account-A.

我怀疑不同之处在于您的信任政策,这似乎有点不同。

于 2020-01-28T02:57:19.863 回答