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
下面的 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
orFAILED
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