AWS лямбда не может взять на себя роль, вызванную облачным формированием

Lambda не может выполнять роль кросс-аккаунта при запуске через скрипт CloudFormation.

У меня есть скрипт CloudFormation, который создает и запускает лямбда-функцию в учетной записи A. Для этой функции необходимо скопировать объект из учетной записи B. Я использую межсчетный доступ на основе ролей.

В учетной записи B у меня есть следующая роль: для целей тестирования я использую полный доступ S3.

CrossAccountAccessRole: 
    Type: 'AWS::IAM::Role'
    Properties: 
      RoleName: 'CrossAccountAccessRole'
      Path: '/'
      AssumeRolePolicyDocument:
        Version: '2012-10-17'
        Statement:
        - Effect: Allow
          Principal: 
            AWS: !Sub 'arn:aws:iam::<AccountA>:role/CustomerCrossAccountAccessRole'
          Action: sts:AssumeRole  
  CrossAccountAccessPolicy:
    Type: "AWS::IAM::ManagedPolicy"
    Properties:
      Path: '/'
      ManagedPolicyName: CrossAccountAccessPolicy
      Roles: 
        - !Ref CrossAccountAccessRole
      PolicyDocument:
        Version: "2012-10-17"
        Statement:       
        - Effect: Allow
          Action:
            - s3:*  

На учетной записи A у меня есть следующая роль с лямбда-выполнением, полным доступом S3 и принятыми политиками ролей.

  CustomerCrossAccountAccessRole:
    Type: 'AWS::IAM::Role'
    Properties:
      RoleName: CustomerCrossAccountAccessRole
      AssumeRolePolicyDocument:
        Version: 2012-10-17
        Statement:
          - Effect: Allow
            Principal:
              Service: lambda.amazonaws.com
            Action: sts:AssumeRole
      Path: /
      Policies:
        - PolicyName: LambdaBasicExecutionPolicy
          PolicyDocument:
            Version: 2012-10-17
            Statement:
              - Effect: Allow
                Action:
                  - 'logs:CreateLogGroup'
                  - 'logs:CreateLogStream'
                  - 'logs:PutLogEvents'
                Resource: '*'
        - PolicyName: LambdaSourceBucketPolicy
          PolicyDocument:
            Version: 2012-10-17
            Statement:
              Effect: Allow
              Action: 's3:*'
              Resource: '*'
        - PolicyName: LambdaAssumeRolePolicy
          PolicyDocument:
            Version: '2012-10-17'
            Statement:
            - Effect: Allow
              Action: sts:AssumeRole
              Resource: !Sub 'arn:aws:iam::<AccountA>:role/CrossAccountAccessRole'

Я запускаю этот скрипт Python внутри моей лямбда-функции,

    try:
        print('Assume role of a cross account access role')
        boto_sts_client=boto3.client('sts', region_name='ap-southeast-2')
        stsresponse = boto_sts_client.assume_role(
            RoleSessionName = 'CrossAccountAccessSession',
            RoleArn = 'arn:aws:iam::<AccountA>:role/CrossAccountAccessRole',
                DurationSeconds = 3000
        )

        s3_assumed_client = boto3.client(
            's3',
            region_name='ap-southeast-2',
            aws_access_key_id = stsresponse["Credentials"]["AccessKeyId"],
            aws_secret_access_key = stsresponse["Credentials"]["SecretAccessKey"],
            aws_session_token = stsresponse["Credentials"]["SessionToken"]
        )
        s3_assumed_client.download_file(<BucketName>, <FilePath>,<FileName>)
    except:
        traceback.print_exc()

Сценарий CloudFormation возвращает следующую ошибку:

botocore.exceptions.ClientError: An error occurred (AccessDenied) when calling the AssumeRole operation: Access denied

Но если я запускаю ту же Lambda (созданную с помощью скрипта CloudFormation) в тестовом режиме (используя кнопку "Тест" на консоли AWS), она загружает файл без каких-либо ошибок.

Спасибо

2 ответа

Ваша политика содержит следующие ошибки:

  • Политика доверия должна указывать учетную запись A в качестве принципала, что означает, что авторизованные пользователи из этой учетной записи могут использовать роль CrossAccountAccessRole. Вы не можете указать ARN пользователей / ролей в разных учетных записях непосредственно в политиках.
  • Администраторы в учетной записи-A должны прикрепить политику, позволяющую роли вызывать AssumeRole для ARN CrossAccountAccessRole.
  • Убедитесь, что вы присвоили CustomerCrossAccountAccessRole для Lambda при его создании.
CrossAccountAccessRole: 
    Type: 'AWS::IAM::Role'
    Properties: 
      RoleName: 'CrossAccountAccessRole'
      Path: '/'
      AssumeRolePolicyDocument:
        Version: '2012-10-17'
        Statement:
        - Effect: Allow
          Principal: 
            AWS: 'arn:aws:iam::<AccountA>:root'
...
- PolicyName: LambdaAssumeRolePolicy
      PolicyDocument:
        Version: '2012-10-17'
        Statement:
        - Effect: Allow
          Action: sts:AssumeRole
          Resource: 'arn:aws:iam::<AccountB>:role/CrossAccountAccessRole'
stsresponse = boto_sts_client.assume_role(
   RoleSessionName = 'CrossAccountAccessSession',
   RoleArn = 'arn:aws:iam::<Account-B>:role/CrossAccountAccessRole',
   DurationSeconds = 3000
)

Вы написали Аккаунт-A в нескольких местах (ARN), где это должно быть на самом деле Аккаунтом-B, но я думаю, что это опечатки.

Вам не нужно управлять ролью кросс-аккаунта для этого. Вы можете просто разрешить доступ из учетной записи A в политике целевого сегмента. Прикрепите разрешение для своей лямбда-роли, и вы сможете получить прямой доступ к корзине, не принимая на себя никакой роли. Перейдите в корзину S3, перейдите на вкладку прав доступа и нажмите "Политика корзины". Ваша политика будет выглядеть,

{
    "Version": "2008-10-17",
    "Statement": [
        {
            "Sid": "DelegateReadToAccountA",
            "Effect": "Allow",
            "Principal": {
                "AWS": [
                    "arn:aws:iam::<account-A>:root"
                ]
            },
            "Action": [
                "s3:Get*",
                "s3:List*"
            ],
            "Resource": [
                "arn:aws:s3:::<bucket_name>",
                "arn:aws:s3:::<bucket_name>/*"
            ]
        }
    ]
}
Другие вопросы по тегам