是否可以在从 CloudFormation 模板创建时触发 lambda

Posted

技术标签:

【中文标题】是否可以在从 CloudFormation 模板创建时触发 lambda【英文标题】:Is it possible to trigger a lambda on creation from CloudFormation template 【发布时间】:2017-05-12 01:17:51 【问题描述】:

我尝试使用 cloudformation 创建一组 lambda。我希望 lambda 在创建后被触发。我在各种博客上看到创建s3sns 的触发器,但似乎没有一个选项可以在创建后触发lambda。有什么选择吗?

【问题讨论】:

【参考方案1】:

改进 Kyr 的答案,因为它缺少两个重要的东西:

如何将参数传递给您调用的 Lambda 如何处理 Stack 上的 UPDATE 和 DELETE(他的解决方案会导致 CloudFormation 在删除时崩溃)

这里是修改和改进的代码:

  LambdaInvoker:
      DependsOn: ## important, add stuff here you need to existe BEFORE the lambda is called
      Type: AWS::Lambda::Function
      Properties:
        FunctionName: YourLambdaName
        Description: 'Lambda invoke wrapper for Custom CFN actions'
        Code:
          ZipFile: !Sub |
            import boto3, json
            import cfnresponse

            def handler(event, context):
                print('EVENT:')
                print(event)

                if event['RequestType'] == "Create":
                  lambda_client = boto3.client('lambda')
                  
                  cfn_event = 
                    "param1" : "$Param1",
                    "param2" : "$Param2"
                  

                  lambda_client.invoke(
                      FunctionName='scm-custom-cfn-actions',
                      InvocationType='Event',
                      Payload=json.dumps(cfn_event)
                  )

                responseValue = 120
                responseData = 
                responseData['Data'] = responseValue
                cfnresponse.send(event, context, cfnresponse.SUCCESS, 
                  responseData, 'scm-cfn-customresource-id')

        Handler: index.handler
        Role: YourLambdaRoleARN
        Runtime: python3.7
        Timeout: 5

【讨论】:

【参考方案2】:

我知道这有点旧 - 但解决方案也可以使用 CommandRunner 作为模板中的资源类型。

https://aws.amazon.com/blogs/mt/running-bash-commands-in-aws-cloudformation-templates/.

您几乎可以运行任何 shell 命令。将 DependsOn 属性添加到您的 CommandRunner 类型并运行 shell 脚本:

aws lambda 调用 --function-name my-function --invocation-type RequestRespone --payload ' "name": "Bob" '

【讨论】:

【参考方案3】:

由 yl.

下面的效果很好!

它调用 lambda 作为部署的一部分:

LambdaFunction2:
    Type: AWS::Lambda::Function
    Properties:
      FunctionName: caller
      Code:
        ZipFile: |
      
          import boto3, json
          
          import cfnresponse

          def handler(event, context):
              print('EVENT:[]'.format(event))
              lambda_client = boto3.client('lambda')
              test_event = '"name":"test1"'
              lambda_client.invoke(
                  FunctionName='target1',
                  InvocationType='Event',
                  Payload=test_event,
              )
              responseValue = 120
              responseData = 
              responseData['Data'] = responseValue
              cfnresponse.send(event, context, cfnresponse.SUCCESS, responseData)
              
      Handler: index.handler
      Role:
        arn:aws:iam::11111111111:role/mylambda-role
      Runtime: python3.7
      Timeout: 60

Primerinvoke:
  Type: AWS::CloudFormation::CustomResource
  DependsOn: LambdaFunction2
  Version: "1.0"
  Properties:
    ServiceToken: !GetAtt LambdaFunction2.Arn

【讨论】:

在code属性中定义了函数,为什么还要有handler属性? 知道了,效果很好【参考方案4】:

以下模板应调用 lambda:

    "InvokeLambda" : 
        "Type": "Custom::InvokeLambda",
        "Version" : "1.0",
        "Properties" : 
        "ServiceToken": 
              "Fn::GetAtt": ["InitFunction","Arn"]
            
          
    ,

【讨论】:

【参考方案5】:

是的,这是可能的。这里有几个选项:

    手动create an SNS Topic。将AWS::SNS::Subscription 添加到您的堆栈中,lambda 函数为Endpoint,SNS 主题为TopicArn。在堆栈创建/更新时,配置要发送到此 SNS 主题的堆栈事件通知。

    (有关使用 AWS 控制台创建堆栈时如何执行此操作的文档,请参阅 Setting AWS CloudFormation Stack Options,如果使用 AWS CLI 或其他 AWS 开发工具包创建/更新堆栈,请使用 --notification-arns 等等效选项。 )

    添加一个 Custom Resource 引用要在创建时调用的 Lambda 函数。

    如果您需要在创建某些特定资源之后调用 Lambda 函数,请在自定义资源上添加 DependsOn attribute,以确保在函数创建之前首先创建该资源调用。 为了成功创建自定义资源(并且不会导致堆栈失败/回滚),您需要调整 Lambda 函数以支持 CloudFormation 请求/响应格式(请参阅Custom Resource Reference)。李> 此选项将在 stack status 仍为 CREATE_IN_PROGRESS 时调用 Lambda 函数,因为自定义资源是堆栈本身的一部分。 当堆栈(和关联的自定义资源)被删除时,也会再次调用 Lambda 函数。这需要由您的 Lambda 函数正确处理,否则您的堆栈可能会卡在 DELETE_FAILED 状态。

    将 Lambda 函数引用添加到 Stack Output,然后编写一个简单的脚本来执行堆栈创建,然后手动调用 Lambda 函数。

【讨论】:

查看此内容以通过 SAM docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/… 创建 SNS 主题。 ***.com/questions/45553456/… (2)的有趣参考(使用无服务器框架):github.com/serverless/serverless/issues/4483 Custom Resource 不能用于在堆栈创建完成 (CREATE_COMPLETE) 后调用 lambda。当堆栈“即将”创建/更新/删除时调用 lambda。 @Abhilashk 正确,因为在这种情况下自定义资源是堆栈的一部分。我已经更新了答案中的选项 2 以使其更清楚。【参考方案6】:

适合寻找类似解决方法的人。

CloudWatch 能够捕获 CloudFormation 的 API 调用,即“CreateStack”、“UpdateStack”和“DeleteStack”,“Create_complete”或“Complete_Rollback”等堆栈状态无法捕获,这意味着此类状态更改无法触发拉姆达。

解决方法是 SNS,堆栈可以向 SNS 发送通知(创建堆栈时预先设置)并且 SNS 可以选择触发 lambda,但是您不能选择特定状态。因此,lambda 函数负责找出事件的“消息”内容中的状态。大家,只是编码。

【讨论】:

【参考方案7】:

您可以选择通知 SNS 主题,并且可以构建一个侦听该主题的 lambda,因此工作流程将是:Cloudformation 启动 -> SNS 主题 -> Lambda。

【讨论】:

我能否通过 SNS 通知我的 lambda 从 cloudformation 创建。我基本上希望我的 lambda 在我的 cloudformation 状态更改为 CREATE_COMPLETE 的那一刻运行。

以上是关于是否可以在从 CloudFormation 模板创建时触发 lambda的主要内容,如果未能解决你的问题,请参考以下文章

是否有定义了多个 CacheBehaviors 的示例 cloudformation 模板?

从 CloudFormation 模板中的 DropDownList 中选择多个值

如何使用 CloudFormation 模板更新现有 AWS API Gateway

AWS > CloudFormation 模板 - 您可以在上传之前对其进行测试吗?

是否可以在 Terraform 中执行 CloudFormation 文件?

CloudFormation 模板的保留字?