1

两天多来,我一直在尝试使用无服务器框架部署 CloudFormation 堆栈。问题是,作为堆栈的一部分,我有一个 RDS 集群以及一个自定义资源,它依赖于 Lambda 函数(用 Python 编写)来初始化一些数据库表。

serverless.yml 文件中此自定义资源的详细信息如下:

rdsMigration:
  Type: Custom::DatabaseMigration
  DependsOn: rdsCluster
  Properties:
    ServiceToken: !GetAtt MigrateDatabaseLambdaFunction.Arn
    Version: 1.0

使用 部署时sls deploy,集群和 lambda 函数已正确创建,但该过程卡在创建rdsMigration资源上。

在 Lambda 代码中,我一直小心翼翼地在所有可能的情况下生成响应,包括异常。然而,这似乎不是问题。

显然,该函数没有被调用......有点,因为即使图表看起来也很奇怪:

监控 Lambda 函数

您可以看到没有调用,但是大约下午 5:15,“错误计数和成功率”中有一个红点,这是开始创建资源的时间。此外,没有绿点,您可以在图例中看到警告,该警告声称“由于非数字值(NaN、-Infinite、+Infinite)而删除了一个或多个数据点”。这怎么可能?我认为这不是标准行为,因为其他 Lambda 函数(必须使用 API Gateway 端点调用)不会显示这个奇怪的图表。

此外,CloudWatch 中没有日志流。它完全是空的,好像从未调用过该函数(似乎是这种情况,除了在资源创建时出现的奇怪的“红点”)。

最后,如果我使用“AWS CloudFormation 创建请求”模板运行测试用例,该函数会正常运行,它会创建我期望用于数据库的初始表(并非总是如此,但这是另一回事)并返回响应。

你知道这里发生了什么吗?最糟糕的是,我需要在两次测试之间等待两个小时,因为 CFN 堆栈在创建和销毁步骤期间会卡住,直到发生超时。

谢谢!

4

2 回答 2

1

问题在于您的 lambda 函数。您必须将 SUCCESS 或 FAILURE 信号发送回 CFN。由于您的 lambda 函数未发送任何信号,因此它等待超时(2 小时)并且 Cloudformation 失败

1.The custom resource provider processes the AWS CloudFormation request and 
  returns a response of SUCCESS or FAILED to the pre-signed URL. AWS 
  CloudFormation waits and listens for a response in the pre-signed URL location. 

2.After getting a SUCCESS response, AWS CloudFormation proceeds with the stack 
  operation. If a FAILURE or no response is returned, the operation fails.

请在您的 lambda 函数中使用 cfnresponse 模块将 SUCCESS/FAILURE 信号发送回您的 Cloudformation

有关更多详细信息: https ://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/cfn-lambda-function-code-cfnresponsemodule.html

于 2020-05-05T17:58:17.273 回答
1

我终于设法找到了解决这个问题的方法,尽管它没有用我在问题中解释的图表来解释奇怪的行为。

我的问题与 Abhinaya 在她的回复中建议的类似。由于编程错误,Lambda 函数未正确发送信号。本质上,我从文档中获取了代码(Python 3 的代码,从末尾开始的第二个片段),显然我错误地删除了用于检索ResponseURL. 当然,那是失败的。

关于这一点的附带评论:使用 Python 的cfnresponse库甚至我在文档中链接的代码片段时要小心。它依赖于哪些已被弃用并且在最新版本botocore.vendored中不再存在。botocore因此,如果您的代码依赖于该库的新版本(如我的情况),它将失败。一个简单的解决方案是botocore.vendored.requestsrequests库替换。

尽管如此,还是有一些我无法理解的奇怪行为。在创建时,Lambda 函数没有向 CloudWatch 记录任何内容,并且我在问题中解释的图表中存在这种奇怪的行为。但是,这只发生在创建时。如果函数是手动调用的,或者是作为删除过程的一部分调用的(删除 CFN 堆栈时),那么它会写入 CloudWatch。因此,问题显然只发生在第一次调用中。

最好的。

于 2020-05-06T10:10:09.033 回答