Как получить доступ к ресурсам aws, созданным в другой учетной записи

В моем случае использования я хочу получить доступ к таблице DynamoDB, созданной в учетной записи AWS A, и Lambda, созданной в учетной записи B. Для этого я следил за многими ссылками в Интернете, которые предлагают мне использовать функцию роли 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"
     }
  ]
}

Ниже приведен код Java, который я добавил для доступа к экземпляру Dynamo DB.

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

ниже приведен журнал сбоев при выполнении лямбда

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


person priyadhingra19    schedule 25.01.2020    source источник
comment
Не могли бы вы уточнить: какая учетная запись имеет учетные данные пользователя IAM, с помощью которой вы используете учетную запись службы? Кроме того, не могли бы вы уточнить, что вы хотите делать с Lambda в аккаунте B? Вы просто хотите вызвать лямбда-функцию?   -  person John Rotenstein    schedule 27.01.2020
comment
@JohnRotenstein Я хочу вызвать лямбда в учетной записи B . Эта лямбда пытается получить доступ к таблице Dynamo DB, представленной в учетной записи A.   -  person priyadhingra19    schedule 27.01.2020
comment
@JohnRotenstein Не могли бы вы уточнить: у какой учетной записи есть учетные данные пользователя IAM, вы используете учетную запись службы? Я не могу понять этот вопрос. Я создал роль в учетной записи A, которая имеет политику adminAccess. Я пытаюсь взять на себя эту роль в своем лямбда-коде, но он выдает исключение unauth   -  person priyadhingra19    schedule 27.01.2020


Ответы (1)


Похоже, ваши требования:

  • Из функции 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"
    }
  ]
}
  • Created an AWS Lambda function in Account-B that will:
    • Assume Role-A in Account-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. Он успешно обновил таблицу DynamoDB в Account-A.

Я подозреваю, что разница в ваших политиках доверия, которые кажутся немного другими.

person John Rotenstein    schedule 28.01.2020