在 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。