使用云形成从 SNS 触发 lambda?

Posted

技术标签:

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

【问题讨论】:

【参考方案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 不会对所有资源都有效。

以上是关于使用云形成从 SNS 触发 lambda?的主要内容,如果未能解决你的问题,请参考以下文章

AWS SNS子脚本与lambda函数的触发器?

如何通过 http 触发器从 AWS SNS 触发 GCP 云功能(私有)

如何使用AWS Lambda和SNS事件触发Spring Cloud功能的重试

设置SNS主题以在另一个之后触发Lambda Function一条消息

我可以触发 Lambda 函数或 SNS 事件来响应 AppSync GraphQL 突变吗?

从本地机器发布 SNS 消息并测试 Lambda