【问题标题】:AWS Lambda SNS event is not binding to the correct SNS Topic ARN using Serverless ymlAWS Lambda SNS 事件未使用无服务器 yml 绑定到正确的 SNS 主题 ARN
【发布时间】:2020-07-13 08:04:38
【问题描述】:

我在 serverless.yml 的资源部分中有一个用于 SNS 主题的无服务器资源,如下所示,

resources:
  Resources:
    SNSTopic:
      Type: AWS::SNS::Topic
      Properties:
        DisplayName: SNS Topic
        TopicName: ${self:service}-${self:provider.stage}-Topic 

当我尝试将此 SNS 主题绑定到我的 lambda 事件(如下所示)时,lambda 不会由 SNS 事件触发。当我检查 AWS 控制台以获取该 lambda 函数时,SNS 事件与错误的 ARN 值绑定。

Function:
    handler: src/sample/file.lambdaHandler
    role: s3FullAccessRole
    events: SNSTopic
    Properties:
      Policies:
        - AWSLambdaExecute
        - Statement:
            - Effect: Allow
              Action:
                - 'lambda:InvokeFunction'

我已尝试使用此处提到的所有不同方式更改事件,https://serverless.com/framework/docs/providers/aws/events/sns/。我发现的唯一方法是在 lambda 事件中硬编码 SNS 主题 ARN 值,这不适合我的情况。 非常感谢任何帮助。

【问题讨论】:

    标签: node.js amazon-web-services amazon-sns serverless-framework


    【解决方案1】:

    您实际上可以使用 sns 主题的 arn 自定义创建一个变量

    custom:
      region: ${opt:region, self:provider.region}
      snsTopic: ${self:service}-${self:provider.stage}-Topic 
      snsTopicArn: { "Fn::Join" : ["", ["arn:aws:sns:${self:custom.region}:", { "Ref" : "AWS::AccountId" }, ":${self:custom.snsTopic}" ] ]  }
    

    然后在你需要的地方使用arn。

    或者您可以使用插件https://github.com/silvermine/serverless-plugin-external-sns-events 来基本引用主题名称。

    如果您只有一个 serverless.yml 并且不想拥有单独的 cloudformation 文件,我会使用第一个选项

    编辑:

    要使用 arn,请按照无服务器 https://serverless.com/framework/docs/providers/aws/events/sns#using-a-pre-existing-topic 上的说明进行操作

    functions:
      dispatcher:
        handler: <handler>
        events:
          - sns:
              arn: ${self:custom.snsTopicArn}
    

    由于您在同一个 serverless.yml 上拥有 sns 主题,您甚至可以忽略 snsTopicArn 变量并使用 !Ref 像建议之一那样构建它,这对您来说应该是一个更好的选择:

    functions:
      dispatcher:
        handler: <handler>
        events:
          - sns:
              arn: !Ref SNSTopic
              topicName: ${self:custom.snsTopic}
    

    完整示例:

    service: testsns
    provider:
      name: aws
      runtime: nodejs12.x
      region: eu-west-1
    
    functions:
      hello:
        handler: handler.hello
        events:
          - sns:
              arn: !Ref SuperTopic
              topicName: MyCustomTopic
        Properties:
          Policies:
            - AWSLambdaExecute
            - Statement:
                - Effect: Allow
                  Action:
                    - 'lambda:InvokeFunction'
    resources:
      Resources:
        SuperTopic:
          Type: AWS::SNS::Topic
          Properties:
            TopicName: MyCustomTopic
    

    【讨论】:

    • 尝试了第一个选项,将事件值替换为“事件:-sns: ${self:custom.snsTopicArn}”在无服务器部署时出现此错误“函数中的 sns 事件缺少或无效的 topicName 属性” " 正确的语法是:sns: topic-name-or-arn OR an object with arn and topicName OR topicName and displayName。请查看文档以获取更多信息"
    • 也试过这个,“事件:-sns:arn:${self:custom.snsTopicArn} topicName:${self:custom.snsTopic}”构建部署没有任何错误但是当我检查AWS 控制台中的 lambda 详细信息没有事件绑定到此 lambda,当我检查 SNS 主题的详细信息时,订阅列表为空
    • 正如我之前提到的,我可以让它工作的唯一方法是将 arn 硬编码到 sns 值“events:-sns:arn:aws:sns:us-east-1:xxxxxxxxxID:project-backend -name-topicStage}"
    • 你应该使用这里提到的arn serverless.com/framework/docs/providers/aws/events/…
    • 用无服务器的建议更新了答案
    【解决方案2】:

    终于明白了!

    我最终从 iamRoleStatements 下添加的 serverless.yml 的资源部分中删除了我的 SNS TOPIC 声明,类似这样,

     iamRoleStatements:
        - Effect: Allow
          Action:
            - SNS:Publish
          Resource: { "Fn::Join" : ["", ["arn:aws:sns:${self:provider.region}:", { "Ref" : "AWS::AccountId" }, ":${self:custom.mySnsTopic}" ] ]  }
    

    并在自定义部分添加变量

    custom:  
      mySnsTopic: "${self:service}-${self:provider.stage}-sns-consume"
      mySnsTopicArn: { "Fn::Join" : ["", ["arn:aws:sns:${self:provider.region}:", { "Ref" : "AWS::AccountId" }, ":${self:custom.mySnsTopic}" ] ]  }
    
    

    然后将其映射到 lambda 函数事件

    Function:
        handler: src/sample/file.lambdaHandler
        role: s3FullAccessRole
        events: ${self:custom.mySnsTopicArn}
        Properties:
          Policies:
            - AWSLambdaExecute
    

    供参考link

    【讨论】:

      猜你喜欢
      • 2019-05-21
      • 2017-12-01
      • 2020-02-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-05-14
      • 1970-01-01
      相关资源
      最近更新 更多