Is it possible to trigger a lambda on creation fro

2020-02-04 08:14发布

问题:

I tried creating a set of lambdas using cloudformation. I want the lambdas to get triggered once they are created. I saw at various blogs to create a trigger to s3 or sns but none seems to be a option to trigger lambda once it has been created. Any options?

回答1:

Yes, it is possible. Here are a few options:

  1. Manually create an SNS Topic. Add an AWS::SNS::Subscription to your stack with the lambda function as the Endpoint and the SNS topic as the TopicArn. On stack creation/update, configure Stack Event Notifications to be sent to this SNS topic.

    • (See Setting AWS CloudFormation Stack Options for documentation on how to do this when using the AWS Console to create your stack, or use the equivalent option like --notification-arns if creating/updating your stack using the AWS CLI or other AWS SDK.)
  2. Add a Custom Resource referencing a Lambda function to be called on creation.

    • If you need the Lambda function to be called after some specific Resource is created, add a DependsOn attribute on the Custom Resource referencing the Resource you want to make sure is created first before the function is called.
    • In order for the Custom Resource to create successfully (and not cause a failure/rollback in your stack), you will need to adapt your Lambda function to support the CloudFormation request/response format (see Custom Resource Reference).
    • This option will call the Lambda function while the stack status is still CREATE_IN_PROGRESS, because the Custom Resource is part of the stack itself.
    • The Lambda function will also be called again when the stack (and associated Custom Resource) is deleted. This will need to be handled by your Lambda function correctly, or your stack could get stuck in the DELETE_FAILED state.
  3. Add the Lambda function reference to a Stack Output, then write a simple script that performs the stack creation and then manually invokes the Lambda function afterwards.



回答2:

For who looking the similar workaround.

CloudWatch is able to capture API calls of CloudFormation, which is "CreateStack", "UpdateStack" and "DeleteStack", stack states like "Create_complete" or "Complete_Rollback" are uncapturable, which means such state changes not be able to trigger lambda.

The workaround is SNS, stacks are able to send notifications to SNS (In advance settings when you creating stack) and SNS can choose to trigger lambda, however, you can't choose for specific states. So, lambda function takes the job to find out what state in "Message" content of an event. Everyone, just coding.



回答3:

by yl.

The following just works great !

It invokes a lambda as a part of deployment:

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


回答4:

You have the option to notify to a SNS topic, and you may build a lambda that listens to the topic, so the workflow would be: Cloudformation launch -> SNS Topic -> Lambda.



回答5:

The following template should invoke the lambda :

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