AWS lambda 无法承担由 cloudformation 触发的角色
AWS lambda cannot assume a role triggered by cloudformation
Lambda 在通过 CloudFormation 脚本触发时无法承担跨账户角色。
我有一个 CloudFormation 脚本,它在账户 A 中创建并触发 Lambda 函数。此函数需要从账户 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 上,我有以下角色,执行 lambda,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 脚本在我的 lambda 函数中,
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脚本returns出现如下错误,
botocore.exceptions.ClientError: An error occurred (AccessDenied) when calling the AssumeRole operation: Access denied
但是如果我在测试模式下 运行 相同的 Lambda(使用 CloudFormation 脚本创建)(使用 AWS 控制台上的 "Test" 按钮),它会毫无错误地下载文件。
谢谢
您的政策包含以下错误:
- 信任策略应将帐户 A 指定为委托人,这意味着来自该帐户的授权用户可以使用 CrossAccountAccessRole 角色。您不能直接在策略中指定不同账户中 users/roles 的 ARN。
- account-A 中的管理员必须附加一个策略,允许角色为 CrossAccountAccessRole 的 ARN 调用 AssumeRole。
- 确保在创建时将 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
)
您在几个地方 (ARN) 写了 Account-A,实际上它应该是 Account-B,但我猜这些是错别字。
您不需要为此管理跨帐户角色。您可以简单地允许从目标存储桶策略中的帐户 A 进行访问。为您的 lambda 角色附加权限,您可以直接访问存储桶而无需承担任何角色。转到您的 S3 存储桶,转到权限选项卡并单击 'Bucket Policy'。您的政策看起来像,
{
"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>/*"
]
}
]
}
Lambda 在通过 CloudFormation 脚本触发时无法承担跨账户角色。
我有一个 CloudFormation 脚本,它在账户 A 中创建并触发 Lambda 函数。此函数需要从账户 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 上,我有以下角色,执行 lambda,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 脚本在我的 lambda 函数中,
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脚本returns出现如下错误,
botocore.exceptions.ClientError: An error occurred (AccessDenied) when calling the AssumeRole operation: Access denied
但是如果我在测试模式下 运行 相同的 Lambda(使用 CloudFormation 脚本创建)(使用 AWS 控制台上的 "Test" 按钮),它会毫无错误地下载文件。
谢谢
您的政策包含以下错误:
- 信任策略应将帐户 A 指定为委托人,这意味着来自该帐户的授权用户可以使用 CrossAccountAccessRole 角色。您不能直接在策略中指定不同账户中 users/roles 的 ARN。
- account-A 中的管理员必须附加一个策略,允许角色为 CrossAccountAccessRole 的 ARN 调用 AssumeRole。
- 确保在创建时将 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
)
您在几个地方 (ARN) 写了 Account-A,实际上它应该是 Account-B,但我猜这些是错别字。
您不需要为此管理跨帐户角色。您可以简单地允许从目标存储桶策略中的帐户 A 进行访问。为您的 lambda 角色附加权限,您可以直接访问存储桶而无需承担任何角色。转到您的 S3 存储桶,转到权限选项卡并单击 'Bucket Policy'。您的政策看起来像,
{
"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>/*"
]
}
]
}