如何解决使用Serverless时 "错误验证堆栈策略""不支持的操作"?

问题描述 投票:1回答:2

我正试图编写一个Serverless脚本来创建一个具有S3权限的AWS lambda函数。

然而,我得到的是 Error validating stack policy to be applied after stack update: Unsupported action 'lambda:InvokeFunction' in statement {}.

下面是我的一个片段 serverless.yml 到目前为止。

    service: {{lambda_function_name}}
    # You can pin your service to only deploy with a specific Serverless version
    # frameworkVersion: "=X.X.X"

    provider:
      name: aws
      runtime: nodejs8.10
      role: {{&roleArn}}
      stage: {{stage}}
      region: {{region}}
      vpc:
        securityGroupIds:
          - {{securityGroupId1}}
        subnetIds:
          - {{subnetId1}}
          - {{subnetId2}}
      stackPolicy:
        - Effect: Allow
          Principal:
            Service: "s3.amazonaws.com"
          Action: "lambda:InvokeFunction"
          Condition:
            ArnLike:
              AWS:SourceArn:
                - "arn:aws:s3:::{{bucket}}"

    package:
      include:
        - app.js
        - node_modules/**
        - src/**
        - bin/**
        - tests/** 

请注意,大括号内的值是环境变量。

在我尝试添加权限之前,一切都正常。这里到底出了什么问题?

amazon-web-services aws-lambda amazon-cloudformation serverless-framework
2个回答
1
投票

我的解决方案是创建一个资源。

https:/serverless.comframeworkdocsprovidersawseventss3。

针对我的反对票,我想我会做进一步的解释。

使用serverless,你可以使用纯粹的Cloudformation。我创建了一个自定义资源,以将所需权限添加到我的S3桶中。

# resource to add S3 lambdainvoke permissions
resources:
  Resources:
    # Cloudformation key, can be called anything.
    LambdaPermission:
      Type: "AWS::Lambda::Permission"
      Properties:
        FunctionName:
          "Fn::GetAtt": # grabs function arn
            - AppLambdaFunction
            - Arn
        Principal: "s3.amazonaws.com"
        Action: "lambda:InvokeFunction"
        SourceAccount:
          Ref: AWS::AccountId
        SourceArn: "arn:aws:s3:::bucket-name"

我希望这能帮助任何遇到我同样问题的人。

至于添加触发器,只能通过Cloudformation在尚未存在的桶上完成。

在我的案例中,我的变通方法是简单地在部署中使用 AWS CLI 在现有的 S3 bucket 上添加触发器。

有一个叫serverless-plugin-existing-s3的serverless插件,它的设计是为了允许在现有的S3 bucket上添加触发器,但我发现这个插件有一些错误。这就是为什么我将坚持使用CLI来添加触发器。

https:/github.commatt-filionserverless-external-s3-event。


0
投票

我终于成功地让这个函数实现了以下功能。

  1. 创建一个Lambda函数
  2. 创建一个S3桶
  3. 允许Lambda函数写入S3 bucket。

这里是 serverless.yml 的提取物,做到了这一点。

provider:
  iamRoleStatements:
   - Effect: "Allow"
     Action:
      - "s3:PutObject"
      - "s3:GetObject"
     Resource:
      Fn::Join:
        - ""
        - - Fn::GetAtt:
            - S3BucketMyBucket
            - Arn
          - "/*"

resources:
  Resources:
    S3BucketMyBucket:
      Type: AWS::S3::Bucket
      Properties:
        BucketName: ${self:custom.cfg.s3BucketName}

functions:
  process:
    handler: handler.process
    events:
      - s3:
        bucket: ${self:custom.dre.s3BucketName}
        event: s3:ObjectCreated:*

custom:
  cfg:
    s3BucketName: "mybucket-${opt:stage}"

关键是通过分割 /functions/process/events/s3 变成多个字段(bucketevent),那么它就不会尝试创建S3 bucket。 当所有的内容都列在一行(没有事件)时,它就会尝试创建 bucket,而你最终会遇到命名冲突,因为它试图创建两个名称相同的 bucket(一个来自于 /functions 和一个来自 /resources).

© www.soinside.com 2019 - 2024. All rights reserved.