amazon-web-services - 为什么自定义资源未能在 AWS Cloudformation 中按预期时间稳定?
问题描述
我想要一个使用 CloudFormation 创建一个新的自定义资源来获得当前日期减去 X 天的结果,当我创建 lambda 函数时,我得到错误:
资源未能在预期时间内稳定下来。
我的代码是:
AWSTemplateFormatVersion: 2010-09-09
Parameters:
Environment:
Description: Environment
Type: String
Default: dev
AllowedValues:
- dev
- test
- prod
- sbx
DaysToSubstract:
Description: Days To Substract to calculate dates to ingest with RedshiftLoader
Type: Number
Default: 1
Resources:
lambdaDateRedshiftLoader:
Type: 'AWS::Lambda::Function'
DependsOn:
- lambdaDateRedshiftLoaderRole
Properties:
Code:
ZipFile: !Sub |
from datetime import date, timedelta
import cfnresponse
def lambda_handler(event, context):
current_delta = date.today() - timedelta(days=event['DaysToSubstract'])
current_delta_str = current_delta.strftime("%Y-%m-%d")
responseData['Dates'] = current_delta_str
cfnresponse.send(event, context, cfnresponse.SUCCESS, responseData)
Environment:
Variables:
DaysToSubstract: !Sub '${DaysToSubstract}'
Description: >-
Calculate yesterday date to obtain start and end date to load the data
with RedshiftLoader
Handler: index.lambda_handler
MemorySize: 128
Role: !GetAtt lambdaDateRedshiftLoaderRole.Arn
Runtime: python3.7
Timeout: 30
lambdaDateRedshiftLoaderRole:
Type: 'AWS::IAM::Role'
Properties:
RoleName: !Sub 'a3m${Environment}-datesRL-lambda-role'
AssumeRolePolicyDocument:
Version: 2012-10-17
Statement:
- Action:
- 'sts:AssumeRole'
Effect: Allow
Principal:
Service:
- lambda.amazonaws.com
Path: /service-role/
Policies:
- PolicyName: !Sub 'a3m${Environment}-lambda-datesRL-lambda-logs-policy'
PolicyDocument:
Version: 2012-10-17
Statement:
- Action:
- 'logs:CreateLogGroup'
- 'logs:CreateLogStream'
- 'logs:PutLogEvents'
Effect: Allow
Resource:
- !Sub >-
arn:aws:logs:eu-west-1:${AWS::AccountId}:log-group:/aws/lambda/lambda-datesRL-uyc:*
lambdaRL:
Type: 'Custom::Value'
Properties:
ServiceToken: !GetAtt lambdaDateRedshiftLoader.Arn
Outputs:
LambdaFunctionOutput:
Value: !GetAtt lambdaRL.Dates
Description: Return Value of Lambda Function (Date minus x days)
我在输出中使用cfnresponse
和SUCCESS
使用!GetAtt lambdaRL.Dates
。
先感谢您
解决方案
您的 Lambda 函数出现错误,因此它从来没有机会调用cfnresponse.send()
。这意味着 CloudFormation 一直在等待响应。
这是 Lambda 函数的更新版本:
from datetime import date, timedelta
import cfnresponse, os
def lambda_handler(event, context):
current_delta = date.today() - timedelta(days=int(os.environ['DaysToSubtract']))
current_delta_str = current_delta.strftime("%Y-%m-%d")
responseData = {}
responseData['Dates'] = current_delta_str
cfnresponse.send(event, context, cfnresponse.SUCCESS, responseData)
问题是:
- 环境变量是通过的
os.environ()
,而不是event()
- 该
DaysToSubtract
值以 astring
而非 a 的形式出现int
,因此该timedelta()
功能失败(小心...拼写Substract
vsSubtract
) responseData
字典未初始化,因此出现NameError: name 'responseData' is not defined
错误
我强烈建议您先在控制台中开发 Lambda 函数。然后,一旦它们开始工作,就将它们移动到 CloudFormation 模板中。这使调试变得容易得多。
哦,还请注意,自定义资源在堆栈被创建、更新和删除时被调用。这可能会导致一些意想不到的行为,尤其是在Delete
操作期间。插入if
语句以仅在Create
阶段运行代码通常是一个好主意,方法是使用:
if event['RequestType'] == 'Create':
推荐阅读
- python - 如何在 python 中使用 uhf rfid 模块?
- r - 如何在大数据上运行层次聚类 hclust?
- sql - 如何将“EVERYTHING”作为参数传递给 BigQuery SQL 中的 WHERE 子句?
- git - 从轨道核对本地 Git 分支的最佳实践?
- javascript - 将异步响应转换为标准 Javascript 对象
- scheme - 在文字之前匹配任意数量的模式变量的方案语法规则?
- python - 如何优化用其他栅格区域平均值替换栅格 nan 值的 Python 循环
- java - 将多个整数值混淆为固定长度值并读回
- regex - 如何让 Google 表格搜索范围并返回“部分重复”的所有行
- python - Seaborn barplot - 没有估计器参数的列值