对于 AWS CloudFormation 中的 Windows Amazon Elastic Compute Cloud (Amazon EC2) 实例,我收到错误消息: “Failed to receive X resource signal(s) within the specified duration(未能在指定持续时间内接收 X 个资源信号)”。
简短描述
当 CloudFormation 没有收到使用内置 ResourceSignal 指定 CreationPolicy 属性的资源的成功信号时,就会出现此错误。该错误可能发生在 Amazon EC2 实例、自动扩缩组或等待条件上。
**注意:**以下解决方案仅适用于使用 Windows 实例创建的 CloudFormation 堆栈。对于 Linux 实例,请参阅如何解决 AWS CloudFormation 中的“Failed to receive X resource signal(s) within the specified duration(未能在指定持续时间内接收 X 个资源信号)”错误?
解决方法
根据您的用例,按照以下故障排除步骤解决问题。
注意:要防止堆栈回滚,请在 CloudFormation 控制台中为堆栈故障选项选择保留成功预调配的资源。当您选择此选项时,失败的实例只有在您删除堆栈后才会终止。
cfn-bootstrap MSI 软件包未安装在 AWS CloudFormation 堆栈的一个或多个实例上
要确认 cfn-signal 脚本已安装在配置为向堆栈发送信号的实例上,请完成以下步骤:
- 使用 RDP 连接到您的 Windows 实例。
- 确认 cfn 帮助程序脚本包已安装。在 Windows PowerShell 中运行以下命令:
Get-Package -name aws-cfn-bootstrap
**重要事项:**默认情况下,CloudFormation 帮助程序脚本安装在 Amazon Windows 亚马逊机器映像 (AMI) 上。要安装帮助程序脚本,请参阅 CloudFormation 帮助程序脚本参考。
AWS CloudFormation 模板有语法错误或值不正确
要查找错误和不正确的值,请完成以下步骤:
- 在代码编辑器中,打开堆栈的 CloudFormation 模板。然后,找到 UserData 属性部分。
- 检查语法错误、空格缺失、拼写错误和其他拼写错误。
- 确认堆栈、资源和 AWS 区域属性的值正确无误。
**注意:**检查 UserData 属性中包含的引导脚本中是否存在语法错误或不正确的值。该脚本调用 cfn-signal。
如果您在 cfn-init 命令中发出信号,请在 cfn-init 日志中查找有关该信号的信息。要在 cloud-init 或 cfn-init 日志中搜索错误,请使用 RDP 连接到您的实例。然后,使用关键字“error”或“failure”在以下日志中搜索详细的错误或失败消息:
C:\cfn\log\cfn-init.log
C:\cfn\log\cfn-init-cmd.log
C:\cfn\log\cfn-wire.log
CreationPolicy 属性的 timeout 属性非常低
timeout 属性的值由 CreationPolicy 属性定义。在 cfn-signal 脚本向 CloudFormation 资源发送信号之前,确认该值足够高,可以运行任务。
要检查 timeout 属性值并比较信令和资源故障时间戳,请完成以下步骤:
-
在代码编辑器中,打开堆栈的 CloudFormation 模板以查找 timeout 属性值。
**注意:**timeout 属性值是 CloudFormation 在信号返回错误之前等待信号的最大时间。
-
要估计何时激活 cfn-signal 脚本,请使用 RDP 连接到实例。然后,运行以下命令:
C:\cfn\log\cfn-init.log
比较文件中记录的开始和结束时间戳,以估算引导所需的时间。根据需要修改超时值。您可以指定的最大时间为 12 小时。
当 SUCCESS 信号发送到 CloudFormation 资源时,日志文件会显示时间戳。
示例:
2019-01-11 12:46:40,101 [DEBUG] Signaling resource EC2Instance in stack XXXX with unique ID i-045a536a3dfc8ccad and status SUCCESS
-
打开 CloudFormation 控制台。
-
选择 Events(事件)视图。
-
选择 Status reason(状态原因)。展开事件行,其状态原因为“Failed to receive X resource signal(s) within the specified duration(未能在指定持续时间内接收 X 个资源信号)。”
-
将信令时间戳与资源故障时间戳进行比较。
**注意:**为了成功完成,脚本必须在创建实例或无法创建实例之前发送信号。
cfn-signal 不是从 Amazon EC2 实例发送的
验证 CloudFormation 收到的信号是否来自实例。查看 C:\cfn\log\cfn-wire.log 上提供的 cfn wire 日志。如果响应不是 200,则您的实例与 CloudFormation 的端点之间可能存在连接问题。
如果您在实例中配置了重启并在 UserData 部分设置了 cfn-signal,则可能无法发送信号。这是因为 UserData 只运行一次。有关详细信息,请参阅在我的 Amazon EC2 Windows 实例完成引导之前,如何阻止该实例发回信号 CREATE_COMPLETE?
当您从不是您的实例的地方发送信号时,使用 SignalResource API。例如,您可以使用 AWS Lambda 函数调用 SignalResource API,然后将信号发送到堆栈。如果您遇到错误,请使用 CloudWatch Logs 检查您的 Lambda 日志,以了解信号未发送到堆栈的原因。