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