在 SAM 模板中添加 PermissionBoundary 失败
Adding PermissionBoundary fails in SAM template
以下是 SAM 模板:
Resources:
HelloWorldFunction:
Type: AWS::Serverless::Function
Properties:
CodeUri: hello-world/
Handler: app.LambdaHandler
Runtime: nodejs8.10
Events:
MySQSEvent:
Type: SQS
Properties:
Queue: !GetAtt SomeQueue.Arn
BatchSize: 10
PermissionsBoundary: "arn:aws:iam::${AWS::AccountId}:policy/AddPermission"
SomeQueue:
Type: AWS::SQS::Queue
AddPermission:
Type: AWS::IAM::ManagedPolicy
Properties:
PolicyDocument:
Version: 2012-10-17
Statement:
- Sid: "PermissionBoundaryForLogGroup"
Effect: "Allow"
Action:
- "logs:CreateLogGroup"
Resource:
- !Sub "arn:aws:logs:${AWS::Region}:${AWS::AccountId}:log-group:*"
出现以下错误:
{
"StackId": "arn:aws:cloudformation:us-east-1:285774445527:stack/somestack/f986eb30-a5a0-11e9-9771-1273bfab49fc",
"EventId": "cb4be9e0-a682-11e9-bac4-12d48e821f84",
"ResourceStatus": "UPDATE_ROLLBACK_IN_PROGRESS",
"ResourceType": "AWS::CloudFormation::Stack",
"Timestamp": "2019-07-14T22:00:29.808Z",
"ResourceStatusReason": "The following resource(s) failed to create: [AddPermission]. The following resource(s) failed to update: [HelloWorldFunctionRole]. ",
"StackName": "pocstack",
"PhysicalResourceId": "arn:aws:cloudformation:us-east-1:285774445527:stack/somestack/f986eb30-a5a0-11e9-9771-1273bfab49fc",
"LogicalResourceId": "pocstack"
},
{
"StackId": "arn:aws:cloudformation:us-east-1:285774445527:stack/pocstack/f986eb30-a5a0-11e9-9771-1273bfab49fc",
"EventId": "AddPermission-CREATE_FAILED-2019-07-14T22:00:29.100Z",
"ResourceStatus": "CREATE_FAILED",
"ResourceType": "AWS::IAM::ManagedPolicy",
"Timestamp": "2019-07-14T22:00:29.100Z",
"ResourceStatusReason": "Resource creation cancelled",
"StackName": "pocstack",
"ResourceProperties": "{\"PolicyDocument\":{\"Version\":\"2012-10-17\",\"Statement\":[{\"Action\":[\"logs:CreateLogGroup\"],\"Resource\":[\"arn:aws:logs:us-east-1:285774445527:log-group:*\"],\"Effect\":\"Allow\",\"Sid\":\"PermissionBoundaryForLogGroup\"}]}}",
"PhysicalResourceId": "arn:aws:iam::285774445527:policy/somestack-AddPermission-GKXVOXLQARLR",
"LogicalResourceId": "AddPermission"
},
如果我使用新堆栈,则错误为:"ResourceStatusReason": "Resource creation cancelled"
为什么无法创建名称为 AddPermission
的托管策略?
这几乎没有问题。
首先,您不能像那样硬编码 AddPermission
的资源名称
PermissionsBoundary: "arn:aws:iam::${AWS::AccountId}:policy/AddPermission"
因为您不知道将要创建的资源的实际名称。会是这样的
arn:aws:iam::859119227216:policy/test-permissions-AddPermission-CK3PYCO10NV1
最后是随机字符串。引用它的正确方法是通过 Ref
函数。
PermissionsBoundary: !Ref AddPermission
另一个问题是您正在创建 SQS 轮询器 lambda 函数,但您的权限边界阻止了 SQS 权限,因此堆栈将无法创建该 lambda 函数。
您需要将类似的内容添加到您的权限边界(当然,您不需要为任何资源添加完整的 SQS 权限,只需足以让函数与特定队列一起使用即可)。
- Sid: 'AllowReadSQSMessages'
Effect: 'Allow'
Action:
- 'sqs:*'
Resource: '*'
这是有效的完整模板(假设代码位置和处理程序名称正确,但可以随意更改)。
Transform: 'AWS::Serverless-2016-10-31'
Resources:
HelloWorldFunction:
Type: AWS::Serverless::Function
Properties:
CodeUri: ./src
Handler: index.handler
Runtime: nodejs8.10
Events:
MySQSEvent:
Type: SQS
Properties:
Queue: !GetAtt SomeQueue.Arn
BatchSize: 10
PermissionsBoundary: !Ref AddPermission
SomeQueue:
Type: AWS::SQS::Queue
AddPermission:
Type: AWS::IAM::ManagedPolicy
Properties:
PolicyDocument:
Version: 2012-10-17
Statement:
- Sid: 'PermissionBoundaryForLogGroup'
Effect: 'Allow'
Action:
- 'logs:CreateLogGroup'
Resource:
- !Sub 'arn:aws:logs:${AWS::Region}:${AWS::AccountId}:log-group:*'
- Sid: 'AllowReadSQSMessages'
Effect: 'Allow'
Action:
- 'sqs:*'
Resource: '*'
虽然这会奏效,但请确保您了解自己在做什么。权限边界将阻止不属于它的任何其他权限。例如,SAM 会自动为 CW 日志创建必要的权限。这些是
- 日志:创建日志组
- 日志:CreateLogStream
- 日志:PutLogEvents
您只允许 logs:CreateLogGroup
在您的权限范围内,因此您的函数将无法将任何内容记录到 CloudWatch。
以下是 SAM 模板:
Resources:
HelloWorldFunction:
Type: AWS::Serverless::Function
Properties:
CodeUri: hello-world/
Handler: app.LambdaHandler
Runtime: nodejs8.10
Events:
MySQSEvent:
Type: SQS
Properties:
Queue: !GetAtt SomeQueue.Arn
BatchSize: 10
PermissionsBoundary: "arn:aws:iam::${AWS::AccountId}:policy/AddPermission"
SomeQueue:
Type: AWS::SQS::Queue
AddPermission:
Type: AWS::IAM::ManagedPolicy
Properties:
PolicyDocument:
Version: 2012-10-17
Statement:
- Sid: "PermissionBoundaryForLogGroup"
Effect: "Allow"
Action:
- "logs:CreateLogGroup"
Resource:
- !Sub "arn:aws:logs:${AWS::Region}:${AWS::AccountId}:log-group:*"
出现以下错误:
{
"StackId": "arn:aws:cloudformation:us-east-1:285774445527:stack/somestack/f986eb30-a5a0-11e9-9771-1273bfab49fc",
"EventId": "cb4be9e0-a682-11e9-bac4-12d48e821f84",
"ResourceStatus": "UPDATE_ROLLBACK_IN_PROGRESS",
"ResourceType": "AWS::CloudFormation::Stack",
"Timestamp": "2019-07-14T22:00:29.808Z",
"ResourceStatusReason": "The following resource(s) failed to create: [AddPermission]. The following resource(s) failed to update: [HelloWorldFunctionRole]. ",
"StackName": "pocstack",
"PhysicalResourceId": "arn:aws:cloudformation:us-east-1:285774445527:stack/somestack/f986eb30-a5a0-11e9-9771-1273bfab49fc",
"LogicalResourceId": "pocstack"
},
{
"StackId": "arn:aws:cloudformation:us-east-1:285774445527:stack/pocstack/f986eb30-a5a0-11e9-9771-1273bfab49fc",
"EventId": "AddPermission-CREATE_FAILED-2019-07-14T22:00:29.100Z",
"ResourceStatus": "CREATE_FAILED",
"ResourceType": "AWS::IAM::ManagedPolicy",
"Timestamp": "2019-07-14T22:00:29.100Z",
"ResourceStatusReason": "Resource creation cancelled",
"StackName": "pocstack",
"ResourceProperties": "{\"PolicyDocument\":{\"Version\":\"2012-10-17\",\"Statement\":[{\"Action\":[\"logs:CreateLogGroup\"],\"Resource\":[\"arn:aws:logs:us-east-1:285774445527:log-group:*\"],\"Effect\":\"Allow\",\"Sid\":\"PermissionBoundaryForLogGroup\"}]}}",
"PhysicalResourceId": "arn:aws:iam::285774445527:policy/somestack-AddPermission-GKXVOXLQARLR",
"LogicalResourceId": "AddPermission"
},
如果我使用新堆栈,则错误为:"ResourceStatusReason": "Resource creation cancelled"
为什么无法创建名称为 AddPermission
的托管策略?
这几乎没有问题。
首先,您不能像那样硬编码 AddPermission
的资源名称
PermissionsBoundary: "arn:aws:iam::${AWS::AccountId}:policy/AddPermission"
因为您不知道将要创建的资源的实际名称。会是这样的
arn:aws:iam::859119227216:policy/test-permissions-AddPermission-CK3PYCO10NV1
最后是随机字符串。引用它的正确方法是通过 Ref
函数。
PermissionsBoundary: !Ref AddPermission
另一个问题是您正在创建 SQS 轮询器 lambda 函数,但您的权限边界阻止了 SQS 权限,因此堆栈将无法创建该 lambda 函数。
您需要将类似的内容添加到您的权限边界(当然,您不需要为任何资源添加完整的 SQS 权限,只需足以让函数与特定队列一起使用即可)。
- Sid: 'AllowReadSQSMessages'
Effect: 'Allow'
Action:
- 'sqs:*'
Resource: '*'
这是有效的完整模板(假设代码位置和处理程序名称正确,但可以随意更改)。
Transform: 'AWS::Serverless-2016-10-31'
Resources:
HelloWorldFunction:
Type: AWS::Serverless::Function
Properties:
CodeUri: ./src
Handler: index.handler
Runtime: nodejs8.10
Events:
MySQSEvent:
Type: SQS
Properties:
Queue: !GetAtt SomeQueue.Arn
BatchSize: 10
PermissionsBoundary: !Ref AddPermission
SomeQueue:
Type: AWS::SQS::Queue
AddPermission:
Type: AWS::IAM::ManagedPolicy
Properties:
PolicyDocument:
Version: 2012-10-17
Statement:
- Sid: 'PermissionBoundaryForLogGroup'
Effect: 'Allow'
Action:
- 'logs:CreateLogGroup'
Resource:
- !Sub 'arn:aws:logs:${AWS::Region}:${AWS::AccountId}:log-group:*'
- Sid: 'AllowReadSQSMessages'
Effect: 'Allow'
Action:
- 'sqs:*'
Resource: '*'
虽然这会奏效,但请确保您了解自己在做什么。权限边界将阻止不属于它的任何其他权限。例如,SAM 会自动为 CW 日志创建必要的权限。这些是
- 日志:创建日志组
- 日志:CreateLogStream
- 日志:PutLogEvents
您只允许 logs:CreateLogGroup
在您的权限范围内,因此您的函数将无法将任何内容记录到 CloudWatch。