Lambda 支持的自定义资源 cf 模板返回“CREATE_FAILED”

CMR*_*R H 5 aws-cloudformation aws-lambda

下面的 lambda 函数是将一个 SNS 主题关联到现有目录,然后是一个自定义资源来调用 lambda func 本身。我看到 lambda 创建成功,“Register_event_topic”也完成了。但是,堆栈在一段时间后失败,主要是因为“自定义资源未能在预期时间内稳定”;如何确保堆栈不会出错?

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
Run Code Online (Sandbox Code Playgroud)

Joh*_*ein 6

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

您可以在以下提供的示例 Zip 文件中看到这一点:演练:查找 Amazon 机器映像 ID - AWS CloudFormation

来自自定义资源 - AWS CloudFormation文档:

自定义资源提供商处理 AWS CloudFormation 请求并返回预签名 URL的响应SUCCESSFAILED对预签名 URL的响应。自定义资源提供程序以 JSON 格式的文件提供响应,并将其上传到预签名的 S3 URL。

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


Bar*_*rtz 5

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

\n\n
\n

在 Lambda 支持的自定义资源中,您可以实现逻辑来支持资源的创建、更新和删除。这些指示是通过事件从 CloudFormation 发送的,并为您提供有关堆栈进程的信息。

\n
\n\n

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

\n\n
\n

CloudFormation 希望在您完成逻辑后从您的 Lambda 函数获得响应。如果未得到响应,或者至少在达到 1 小时(!)超时之前,它将不会继续部署过程。它可能会花费您大量的时间和挫败感。

\n
\n\n

你可以在这里阅读更多

\n