如何访问其他账户创建的aws资源

How to access aws resources created in other account

在我的用例中,我想访问在 AWS 账户 A 中创建的 DynamoDB table 和在账户 B 中创建的 Lambda。为此,我在 Internet 上遵循了许多建议我使用的参考资料AWS 承担角色功能。 我在 Lambda 执行角色

中添加了以下权限
{
  "Version": "2012-10-17",
  "Statement": {
    "Effect": "Allow",
    "Action": "sts:AssumeRole",
    "Resource": "arn:aws:iam::aws-account-A-number:role/test-db-access"
   }
}

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"
    }
  ]
}

在账户 A 中,我创建了角色(test-db-access)以允许其他人访问此账户并添加了 AmazonDynamoDBFullAccess 和 AdministratorAccess 策略。以下是我在这个账号中添加的信任关系

{
  "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"
     }
  ]
}

以下是我添加的用于访问 Dynamo 数据库实例的 Java 代码

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();

以下是执行 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" }

看来您的要求是:

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

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

  • Account-A
  • 中创建了一个 DynamoDB table
  • 使用以下策略在 Account-A 中创建了一个 IAM 角色 (Role-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"
    }
  ]
}
  • Account-B 中创建了一个 IAM 角色 (Role-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"
    }
  ]
}
  • Account-B 中创建了一个 AWS Lambda 函数,它将:
    • 假设 Role-AAccount-A
    • Account-A
    • 中访问 DynamoDB table

我是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'},
        }
    ) 

我通过在 Account-B 中的 Lambda 函数上单击 测试 来测试它。 已成功更新 Account-A 中的 DynamoDB table。

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