Можно ли запустить лямбду при создании из шаблона CloudFormation

Я попытался создать набор лямбд с помощью облачной информации. Я хочу, чтобы лямбды запускались после их создания. Я видел в различных блогах, чтобы создать триггер s3 или же sns но ни один из них не может быть опцией lambda как только он был создан. Есть варианты?

7 ответов

Решение

Да, это возможно. Вот несколько вариантов:

  1. Вручную создайте тему SNS. Добавить AWS::SNS::Subscription в ваш стек с лямбда-функцией в качестве Endpoint и тема SNS как TopicArn, При создании / обновлении стека настройте уведомления о событиях стека для отправки в этот раздел SNS.

  2. Добавьте пользовательский ресурс, ссылающийся на функцию Lambda, которая будет вызываться при создании.

    • Если вам нужно, чтобы лямбда-функция вызывалась после создания определенного ресурса, добавьте DependsOn Атрибут в пользовательском ресурсе, ссылающийся на ресурс, который вы хотите удостовериться, сначала создается перед вызовом функции.
    • Чтобы пользовательский ресурс успешно создавался (и не вызывал сбой / откат в вашем стеке), вам нужно будет адаптировать свою функцию Lambda для поддержки формата запроса / ответа CloudFormation (см. Ссылку на пользовательский ресурс).
    • Эта опция будет вызывать функцию Lambda, пока статус стека все еще CREATE_IN_PROGRESS потому что пользовательский ресурс является частью самого стека.
    • Лямбда-функция также будет вызываться снова при удалении стека (и соответствующего пользовательского ресурса). Это должно быть правильно обработано вашей лямбда-функцией, иначе ваш стек может застрять в DELETE_FAILED государство.
  3. Добавьте ссылку на функцию Lambda в вывод стека, затем напишите простой скрипт, который выполняет создание стека, а затем вручную вызывает функцию Lambda.

Пользователя yl.

Следующее просто отлично работает!

Он вызывает лямбду как часть развертывания:

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

Для тех, кто ищет подобный обходной путь.

CloudWatch может захватывать вызовы API CloudFormation, которые представляют собой "CreateStack", "UpdateStack" и "DeleteStack", состояния стека, такие как "Create_complete" или "Complete_Rollback", не могут быть захвачены, что означает, что такие изменения состояния не могут вызвать лямбду.

Обходной путь - SNS, стеки могут отправлять уведомления в SNS (в предварительных настройках при создании стека), а SNS может выбрать для запуска лямбда, однако вы не можете выбрать конкретные состояния. Итак, лямбда-функция берет на себя задачу выяснить, в каком состоянии находится "Сообщение" содержимого события. Все, только кодирование.

Следующий шаблон должен вызывать лямбду:

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

Я знаю, что это немного устарело, но решением также может быть использование CommandRunner в качестве типа ресурса в вашем шаблоне.

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

Вы можете запустить практически любую команду оболочки. Добавьте атрибут DependsOn к вашему типу CommandRunner и запустите сценарий оболочки:

aws lambda invoke --function-name my-function --invocation-type RequestRespone --payload '{ "name": "Bob" }'

Улучшение ответа Кира, потому что в нем отсутствуют две важные вещи:

  • как передать параметры лямбде, которую вы вызываете
  • как обрабатывать 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

У вас есть возможность уведомить тему SNS, и вы можете создать лямбду, которая слушает тему, поэтому рабочий процесс будет следующим: Запуск Cloudformation -> Тема SNS -> Lambda.

Другие вопросы по тегам