Lambda 支持的自定义资源 cf 模板 returns 'CREATE_FAILED'

Lambda backed custom resource cf template returns 'CREATE_FAILED'

下面的 lambda 函数是将 SNS 主题关联到现有目录,然后是自定义资源以调用 lambda 函数本身。我看到 lambda 创建成功,'Register_event_topic' 也完成了。但是,堆栈在一段时间后失败,主要是因为 'custom resource failed to stabilize in expected time';如何确保堆栈不出错?

AWSTemplateFormatVersion: '2010-09-09'
    #creating lambda function to register_event_topic
    Description: Lambda function to register event topic with existing directory ID
    Parameters:
      RoleName:
        Type: String
        Description: "IAM Role used for Lambda execution"
        Default: "arn:aws:iam::<<Accountnumber>>:role/LambdaExecutionRole"
      EnvVariable:
        Type: String
        Description: "The Environment variable set for the lambda func"
        Default: "ESdirsvcSNS"
    Resources:
      REGISTEREVENTTOPIC:
        Type: 'AWS::Lambda::Function'
        Properties:
          FunctionName: dirsvc_snstopic_lambda
          Handler: index.lambda_handler
          Runtime: python3.6
          Description: Lambda func code to assoc dirID with created SNS topic
          Code:
            ZipFile: |
              import boto3
              import os
              import logging
              dsclient = boto3.client('ds')
              def lambda_handler(event, context):
                response = dsclient.describe_directories()
                directoryList = []
                print(response)
                for directoryList in response['DirectoryDescriptions']:
                    listTopics = dsclient.describe_event_topics(
                      DirectoryId=directoryList['DirectoryId']
                    )
                    eventTopics = listTopics['EventTopics']
                    topiclength = len(eventTopics)
                    if topiclength == 0:
                      response = dsclient.register_event_topic(
                          DirectoryId=directoryList['DirectoryId'],
                          TopicName= (os.environ['MONITORING_TOPIC_NAME'])
                      )  
                    print(listTopics)
          Timeout: 60
          Environment:
            Variables:
              MONITORING_TOPIC_NAME: !Ref EnvVariable
          Role: !Ref RoleName

      InvokeLambda:
        Type: Custom::InvokeLambda
        Properties:
          ServiceToken: !GetAtt REGISTEREVENTTOPIC.Arn
          ReservedConcurrentExecutions: 1

唉,编写自定义资源并不像您最初想象的那么简单。相反,必须将特殊代码添加到 post 返回到 URL 的响应。

您可以在以下网站提供的示例 Zip 文件中看到:Walkthrough: Looking Up Amazon Machine Image IDs - AWS CloudFormation

来自 Custom Resources - AWS CloudFormation 文档:

The custom resource provider processes the AWS CloudFormation request and returns a response of SUCCESS or FAILED to the pre-signed URL. The custom resource provider provides the response in a JSON-formatted file and uploads it to the pre-signed S3 URL.

这是由于 CloudFormation 的异步行为。它不只是调用 Lambda 函数然后等待响应。相反,它会触发 Lambda 函数,该函数必须回调并触发 CloudFormation 中的下一步。

您的 lambda 不支持自定义资源生命周期

In a Lambda backed custom resource, you implement your logic to support creation, update and deletion of the resource. These indications are sent from CloudFormation via the event and give you information about the stack process.

此外,您还应该return将您的状态返回到 CloudFormation

CloudFormation expects to get a response from your Lambda function after you're done with your logic. It will not continue with the deployment process if it doesn’t get a response, or at least until a 1 hour(!) timeout is reached. It can cost you a lot of time and frustration.

你可以阅读更多here