【问题标题】:Triggering a lambda from SNS using cloud-formation?使用云形成从 SNS 触发 lambda?
【发布时间】:2018-07-31 15:01:22
【问题描述】:

使用云形成从 SNS 触发 lambda?

【问题讨论】:

    标签: amazon-web-services aws-lambda amazon-cloudformation amazon-sns


    【解决方案1】:

    我们所做的是我们不将 sns 指向一个不合格的 lambda,而是将它指向一个 lambda 别名。基本上,创建一个 lambda,然后创建一个别名,使用 sns 指向 lambda-alias。

    当您有新的 lambda 代码时(您的 ci/cd 可以执行以下操作),更新 lambda 函数代码,创建一个新的 lambda 版本,并将您的别名重新指向新版本。这样,您的 sns 就不必随着新的 lambda 代码删除而发生变化。

    Resources: 
      AwsServerlessExpressFunction:
        Type: AWS::Serverless::Function
        Properties:
          FunctionName: mylambda
          Description: mylambda 
          Runtime: nodejs8.10
          Handler: index.handler
          MemorySize: 512
          Timeout: 60
          Role: !Ref LambdaExecutionRoleArn
    
      AwsServerlessExpressFunctionAlias:
        Type: AWS::Lambda::Alias
        Properties:
          FunctionName: !Ref AwsServerlessExpressFunction
          FunctionVersion: '$LATEST'
          Name: live
    
      SNSTopic: 
        Type: AWS::SNS::Topic
        Properties: 
          DisplayName: mysnstopic
          TopicName: mysnstopic
          Subscription:  
          - 
            Endpoint: !Ref AwsServerlessExpressFunctionAlias
            Protocol: lambda
    
      LambdaInvokePermission: 
        Type: AWS::Lambda::Permission
        Properties: 
          Action: lambda:InvokeFunction
          Principal: sns.amazonaws.com
          SourceArn:  !Ref SNSTopic 
          FunctionName: !Ref AwsServerlessExpressFunctionAlias
    

    【讨论】:

    • 如果您使用 cloudformation 更新您的堆栈,每次更新都会同时更新 sns 和 lambda。在这种情况下,我认为没有必要使用 Lambda 别名?
    【解决方案2】:

    不要忘记添加LambdaFunctionPermission 以允许使用 SNS 主题。

    这是 yaml 中 Cloud Formation 模板的资源部分:

    Resources:
      SNSTopic: 
        Type: AWS::SNS::Topic
        Properties: 
          DisplayName: sns-topic-for-lambda
          TopicName: sns-topic-for-lambda
          Subscription:  
          - Endpoint: !GetAtt LambdaFunction.Arn
            Protocol: lambda
    
      LambdaFunctionPermission:
        Type: AWS::Lambda::Permission
        Properties:
          Action: lambda:InvokeFunction
          FunctionName: !GetAtt LambdaFunction.Arn
          Principal: sns.amazonaws.com
    
      LambdaFunction:
        Type: AWS::Lambda::Function
        Properties:
        ...
    

    【讨论】:

      【解决方案3】:

      您可以使用事件来设置触发器。

        lambda:
          Type: 'AWS::Serverless::Function'
          Properties:
            Handler: 
            ------
            Events:
              SNS1:
                Type: SNS
                Properties:
                  Topic:
                    Ref: SNSTopic1
        SNSTopic1:
          Type: 'AWS::SNS::Topic'
      

      参考:参考:https://docs.aws.amazon.com/lambda/latest/dg/serverless_app.html#serverless_app_resources

      【讨论】:

      • 这应该是主题 ARN 而不是参考。 github.com/awslabs/serverless-application-model/blob/master/…
      • ref 用于引用变量。
      • 我知道,但如果您浏览了该链接,您会发现主题“ARN”是必需的。不过,只需检查“Ref”和“Fn::GetAtt”是否都返回主题的 ARN。所以它仍然适用于 SNS 主题,但 ref 并不等于每个资源的 ARN。 docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/…
      • 想法是将ARN作为参数传递,因为它是一种静态资源,这只是一个例子。由您决定使用它。
      • 您可以使用 Fn:GetAtt 将 ARN 作为参数传递,Ref: 和 Fn:GetAtt 会根据资源产生不同的值。正如我之前提到的,在 SNS 主题的情况下,Ref: 和 Fn:GetAtt 都提供相同的值,因此在这种情况下它可以工作,但是当需要 ARN 时,Ref 不会对所有资源都有效。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-12-01
      • 2020-05-09
      • 2021-05-14
      • 1970-01-01
      • 1970-01-01
      • 2021-10-25
      • 2020-01-21
      相关资源
      最近更新 更多