CloudFormation 疑难解答 - AWS CloudFormation

CloudFormation 疑难解答

使用 CloudFormation 时,您可能会在创建、更新或删除 CloudFormation 堆栈时遇到问题。以下部分可帮助您解决您可能遇到的一些常见问题。

有关 CloudFormation 的一般性问题,请参阅 AWS CloudFormation 常见问题。您还可以在 AWS CloudFormation 论坛上搜索答案和发布问题。

问题排查指南

如果 CloudFormation 创建、更新或删除堆栈失败,则可通过查看错误消息或日志来帮助详细了解问题。以下任务描述了解决 CloudFormation 问题的通用方法。有关特定的错误和解决方案的信息,请参阅纠正错误部分。

  • 使用 CloudFormation 控制台查看堆栈的状态。在控制台中,您可以在创建、更新或删除堆栈时查看堆栈事件的列表。从该列表中,找到失败事件,然后查看该事件的状态原因。状态原因可能包含来自 CloudFormation 或特定服务的,有助于您排查问题的错误消息。有关查看堆栈事件的更多信息,请参阅 从 CloudFormation 控制台查看 CloudFormation 堆栈信息

  • 对于 Amazon EC2 问题,请查看 cloud-init 和 cfn 日志。这些日志是在 Amazon EC2 实例上的 /var/log/ 目录中发布的。这些日志会捕获 CloudFormation 设置实例时的进程和命令输出。对于 Windows,请查看 %ProgramFiles%\Amazon\EC2ConfigService 中的 EC2Configure 服务、%ProgramData%\Amazon\EC2-Windows\Launch\Logs 中的 EC2 Launch、%ProgramData%\Amazon\EC2Launch\log 中的 EC2 Launch v2 和 C:\cfn\log 中的 cfn 日志。

    您也可以配置 CloudFormation 模板,以将日志发布到 Amazon CloudWatch,从而在 AWS Management Console中显示日志,无需连接到 Amazon EC2 实例。有关更多信息,请参阅应用程序管理博客中的 View CloudFormation logs in the console

纠正错误

遇到以下与 CloudFormation 堆栈有关的错误时,您可以使用以下解决方案来帮助确定问题的根源并解决问题。

删除堆栈失败

要解决此情况,请尝试:

  • 一些资源必须为空才能进行删除。例如,必须先删除 Amazon S3 存储桶中的所有对象或删除 Amazon EC2 安全组中的所有实例,然后才能删除该存储桶或安全组。

  • 确保您具有删除堆栈中的资源所需的 IAM 权限。除 CloudFormation 权限之外,您必须有权使用相关基础服务,例如 Amazon S3 或 Amazon EC2。

  • 如果堆栈因 CloudFormation 无法删除资源而处于 DELETE_FAILED 状态,请使用 RetainResources 参数重新运行删除操作,并指定 CloudFormation 无法删除的资源。CloudFormation 将删除该堆栈,但不会删除保留的资源。如果无法删除某个资源 (如包含您希望保留的对象的 S3 存储桶),但仍需要删除堆栈,则保留资源很有用。

    在您删除堆栈之后,您可以使用其关联的 AWS 服务手动删除保留的资源。

    或者,您可以考虑将 FORCE_DELETE_STACK 选项与 DeletionMode 参数一起使用。有关更多信息,请参阅 DeleteStack

  • 无法删除已启用终止保护的堆栈。如果您尝试删除已启用终止保护的堆栈,则删除操作会失败,并且堆栈及其状态将保持不变。请在堆栈上禁用终止保护,然后再重新执行删除操作。

    这包括根堆栈启用终止保护的嵌套堆栈。请在根堆栈上停用终止保护,然后再重新执行删除操作。强烈建议您不要直接删除嵌套堆栈,而是只在删除根堆栈及其所有资源时作为其一部分进行删除。

    有关更多信息,请参阅 堆栈删除保护

  • 对于所有其他问题,如果您拥有 AWS Support,则可创建一个 AWS Support 案例。请参阅 联系 支持

依赖性错误

要纠正依赖性错误,请将一个 DependsOn 属性添加到依赖您模板中的其他资源的资源。在某些情况下,您必须显式声明依赖项,以便 CloudFormation 能够按正确的顺序创建或删除资源。例如,如果您使用 Internet 网关在同一个堆栈中创建一个弹性 IP 和一个 VPC,则该弹性 IP 必须依赖 Internet 网关连接。有关更多信息,请参阅 DependsOn 属性

AWS Config 和 AWS Systems Manager 冲突

AWS Config 和 AWS Systems Manager 可以自动执行基础设施管理任务,但这些任务可能会导致与 CloudFormation 堆栈的部署发生冲突。请执行以下操作以避免任何潜在的冲突:

  • 检查相关 AWS 账户和 AWS 区域中的 AWS Config 和 Systems Manager 配置。

  • 检查是否存在可能会在 CloudFormation 部署期间触发的活动规则或自动化文档。这些都可能会导致冲突或与部署发生冲突的资源依赖项。

  • 检查 CloudFormation 模板中是否存在由 AWS Config 和 Systems Manager 管理的任何资源。检查是否存在潜在的重叠或相互依赖项,并考虑调整模板或自动化配置以避免冲突。

  • 在 CloudFormation 部署期间暂时禁用或暂停任何相关 AWS Config 规则或 Systems Manager 自动化。不过要记住在成功部署后恢复原始配置,以确保所需的自动化水平和合规性。

  • 检查 CloudFormation 日志和错误消息,了解有关提及 AWS Config 和 Systems Manager 相关问题的项,以帮助查明冲突的根源。

有关 AWS Config 规则的详细信息,请参阅 Evaluating Resources with AWS Config 规则

有关 Systems Manager 自动化的详细信息,请参阅 AWS Systems Manager 自动化

传递列表时解析参数出错

在使用 AWS Command Line Interface 或 CloudFormation 传入列表时,请在每个逗号的前面添加一个转义字符 (\)。下面的示例说明如何在使用 AWS CLI 时指定输入参数。

ParameterKey=CIDR,ParameterValue='10.10.0.0/16\,10.10.0.0/24\,10.10.1.0/24'

IAM 权限不足

在使用 CloudFormation 堆栈时,您不仅需要有权使用 CloudFormation,还必须有权使用模板中描述的基础服务。例如,如果您正在创建 Amazon S3 存储桶或启动 Amazon EC2 实例,则需要拥有对 Amazon S3 或 Amazon EC2 的权限。检查您的 IAM 策略并确认您具有必要的权限,然后才能使用 CloudFormation 堆栈。有关更多信息,请参阅使用 AWS Identity and Access Management 控制访问权限

无效的值或不受支持的资源属性

在您创建或更新 CloudFormation 堆栈时,堆栈会因无效的输入参数、不受支持的资源属性名称或不受支持的资源属性值而失败。对于输入参数,请验证资源是否存在。例如,在您指定 Amazon EC2 密钥对或 VPC ID 时,资源必须存在于您从中创建或更新堆栈的账户和区域中。您可以使用 AWS 特定的参数类型来确保使用有效值。

对于资源属性名称和值,请更新您的模板以使用有效的名称和值。有关所有资源及其属性名称的列表,请参阅AWS 资源和属性类型参考

超出配额

确认您未达到资源配额。例如,您可以启动的默认最大 Amazon EC2 按需型实例数为 5 个。如果尝试创建的 Amazon EC2 按需型实例的数目超出账户配额,则实例创建将失败,并且您会收到错误 Status=start_failed。要按服务查看默认 AWS 限额,请参阅 AWS 一般参考 中的 AWS service quotas

有关 CloudFormation 配额和调整策略,请参阅 了解 CloudFormation 配额

此外,如果在更新期间要替换某个资源,则 CloudFormation 会首先创建新资源,然后再删除旧资源。此替换可使您的账户超出资源配额,这将导致更新失败。您可以删除超额的资源或请求提高配额

嵌套堆栈陷入 UPDATE_COMPLETE_CLEANUP_IN_PROGRESSUPDATE_ROLLBACK_COMPLETE_CLEANUP_IN_PROGRESSUPDATE_ROLLBACK_IN_PROGRESS 状态

一个嵌套堆栈无法回滚。由于嵌套堆栈之间可能存在资源依赖关系,因此在所有嵌套堆栈完成更新或回滚之前,CloudFormation 不会开始清理嵌套堆栈资源。当某个嵌套堆栈回滚失败时,无论其他嵌套堆栈处于何种状态,CloudFormation 都会取消所有操作。如果一个嵌套堆栈已完成更新或回滚,但由于另一嵌套堆栈回滚失败而导致该堆栈未能收到 CloudFormation 发出的开始清理的信号,则该堆栈会处于 UPDATE_COMPLETE_CLEANUP_IN_PROGRESSUPDATE_ROLLBACK_COMPLETE_CLEANUP_IN_PROGRESS 状态。如果一个嵌套堆栈无法更新,但未收到开始回滚的信号,则该堆栈会处于 UPDATE_ROLLBACK_IN_PROGRESS 状态。

嵌套堆栈可能因为曾在 CloudFormation 外部进行更改而无法回滚,此时堆栈模板无法准确反映堆栈的状态。如果嵌入堆栈中的自动扩缩组在创建或更新时的资源信号超时期间不足,那么该嵌套堆栈也可能无法回滚。

要修复堆栈,请联系 AWS Support

无需执行更新

要更新 CloudFormation 堆栈,您必须向 CloudFormation 提交模板或参数值更改。但是,CloudFormation 不会将某些模板更改视为更新,例如对删除策略、更新策略、条件声明或输出声明所做的更改。如果您需要做出此类更改而不进行任何其他更改,则可为任何资源添加或修改元数据属性。元数据属性可以是任意值,因为 CloudFormation 不会解释其内容。

资源在创建、更新或删除堆栈操作期间无法稳定工作

资源因操作超出 CloudFormation 超时期限或 AWS 服务已中断而未响应。对于服务中断,检查相关 AWS 服务是否正在运行,然后重试堆栈操作。

如果 AWS 服务已成功运行,请检查您的堆栈是否包含下列资源之一:

  • AWS::AutoScaling::AutoScalingGroup,用于创建、更新和删除操作

  • AWS::CertificateManager::Certificate,用于创建操作

  • AWS::CloudFormation::Stack,用于创建、更新和删除操作

  • AWS::ElasticSearch::Domain,用于更新操作

  • AWS::RDS::DBCluster,用于创建和更新操作

  • AWS::RDS::DBInstance,用于创建、更新和删除操作

  • AWS::Redshift::Cluster,用于更新操作

这些资源的操作时间可能会超过默认的超时期间。超时期间取决于您使用的资源和凭证。要延长超时期间,请在执行堆栈操作时指定服务角色。如果您已使用服务角色或您的堆栈包含未列出的资源,请联系 AWS Support

如果您的堆栈处于 UPDATE_ROLLBACK_FAILED 状态,请参阅更新回滚失败

VPC 中不存在安全组

确认您指定的 VPC 中存在安全组。如果安全组存在,请确保指定安全组 ID 而非安全组名称。例如,AWS::EC2::SecurityGroupIngress 资源具有 SourceSecurityGroupNameSourceSecurityGroupId 属性。对于 VPC 安全组,您必须使用 SourceSecurityGroupId 属性并指定安全组 ID。

更新回滚失败

关联资源无法回到初始状态,这会导致失败回滚(UPDATE_ROLLBACK_FAILED 状态)。例如,您可能有一个堆栈正在回滚到已在 CloudFormation 之外删除的旧数据库实例。由于并不知道该数据库已被删除,因此 CloudFormation 假定该数据库实例仍然存在并尝试回滚到该实例,从而导致更新回滚失败。

您可以手动修复错误并继续执行回滚操作,具体视故障原因而定。通过继续执行回滚操作,您可以使堆栈回到工作状态 (UPDATE_ROLLBACK_COMPLETE 状态),然后尝试再次更新堆栈。对于导致更新回滚失败的常见错误,下表列出了解决方案:

  • 未收到所需数量的信号

    使用 signal-resource 命令向等待信号的资源手动发送所需数量的成功信号,然后继续回滚更新。例如,在更新回滚期间,自动扩缩组中的实例可能未在指定的超时时间内发送成功信号。请向此自动扩缩组手动发送成功信号。当您继续执行更新回滚操作时,CloudFormation 会收到您的信号并继续执行回滚操作。

  • 在 CloudFormation 之外更改了资源

    手动同步资源,使其与初始堆栈模板匹配,然后继续回滚更新。例如,假设您手动删除了 CloudFormation 尝试回滚到的资源,则必须手动创建与原堆栈中的名称和属性均相同的资源。

  • 权限不足

    检查您是否拥有充足的 IAM 权限来修改资源,然后继续回滚更新。例如,您的 IAM policy 也许允许您创建 S3 存储桶,但不允许您修改存储桶。请向您的策略中添加修改操作。

  • 安全令牌无效

    CloudFormation 需要一组新的凭证。无需做出任何更改。继续回滚更新,这会刷新凭证。

  • 限制错误

    删除您不需要的资源或请求提高配额,然后继续回滚更新。例如,如果您的账户有 5 个 EC2 按需型实例的配额而更新回滚超出了此配额,则回滚操作会失败。

  • 资源不稳定

    资源因操作可能超出 CloudFormation 超时值或 AWS 服务中断而未响应。无需做出任何更改。在资源操作完成或 AWS 服务恢复运行后,继续回滚更新。

要继续回滚更新,可以使用 CloudFormation 控制台或 AWS 命令行界面(AWS CLI)。有关更多信息,请参阅 继续回滚更新

如果这些解决方案都不起作用,您可以跳过 CloudFormation 无法成功回滚的资源。有关更多信息,请参阅《AWS CloudFormation API 参考》中有关 ContinueUpdateRollback 操作的 ResourcesToSkip 参数。CloudFormation 将指定资源的状态设置为 UPDATE_COMPLETE 并继续回滚堆栈。回滚完成后,已跳过资源的状态将与堆栈模板中资源的状态不一致。在执行另一个堆栈更新之前,您必须修改资源或更新堆栈以便让堆栈互相保持一致。如果您没有这样做,后续堆栈更新可能失败并使您的堆栈无法恢复。

等待条件未收到来自 Amazon EC2 实例的所需数目的信号

要解决此情况,请尝试:

  • 确保您使用的 AMI 已安装 CloudFormation 帮助程序脚本。如果 AMI 不包含帮助程序脚本,您也可以将这些脚本下载到您的实例。有关更多信息,请参阅 CloudFormation 帮助程序脚本参考

  • 确认已对该实例成功运行 cfn-signal 命令。您可以查看日志 (例如,/var/log/cloud-init.log/var/log/cfn-init.log) 来帮助调试实例启动。您可以通过登录实例来检索日志,但必须禁用失败时回滚选项,否则 CloudFormation 会在创建堆栈失败后删除实例。您还可以向 Amazon CloudWatch 发布日志。对于 Windows,您可以查看 C:\cfn\log 中的 cfn 日志和 %ProgramFiles%\Amazon\EC2ConfigService 中的 EC2Config 服务日志。

  • 确认实例已连接到 Internet。如果实例在 VPC 中,则实例应能通过 NAT 设备 (在私有子网中时) 或通过 Internet 网关 (在公有子网中时) 连接到 Internet。要测试实例的 Internet 连接,可尝试访问公有网页,例如 http://aws.amazon.com。例如,您可以对实例运行以下命令。它应返回 HTTP 200 状态代码。

    curl -I https://aws.amazon.com

    有关配置 NAT 设备的信息,请参阅《Amazon VPC 用户指南》中的 NAT

资源已从堆栈中移除但未删除

在堆栈更新期间,CloudFormation 已从堆栈中移除了资源,但没有删除该资源。该资源仍然存在,但无法再通过 CloudFormation 进行访问。在以下情况下,可能会在堆栈更新过程中发生这种情况:

  • CloudFormation 需要替换现有资源,所以它首先创建一个新资源,然后尝试删除旧资源。

  • 您已从堆栈模板中移除资源,因此 CloudFormation 尝试从堆栈中删除该资源。

但是,在某些情况下,CloudFormation 可能无法删除资源。例如,在用户不具有删除给定类型的资源的权限时。

CloudFormation 尝试删除旧资源三次。如果 CloudFormation 无法删除旧资源,其会将旧资源从堆栈中移除并继续更新堆栈。堆栈更新完成后,CloudFormation 会发出 UPDATE_COMPLETE 堆栈事件,但同时会包含一个 StatusReason,以说明无法删除一个或多个资源。CloudFormation 还会针对特定资源发布一个 DELETE_FAILED 事件,以及相应的 StatusReason,以详细说明 CloudFormation 未能删除资源的原因。

要解决这种情况,请使用基础服务的控制台或 API 直接删除资源。

联系 支持

如果您拥有 AWS Support,则可在 https://console.aws.amazon.com/support/home#/ 创建一个技术支持案例。在联系支持人员之前,请收集以下信息:

  • 堆栈 ID。您可以在 CloudFormation 控制台概述选项卡上找到堆栈 ID。有关更多信息,请参阅 从 CloudFormation 控制台查看 CloudFormation 堆栈信息

    重要

    请勿在 CloudFormation 外部更改堆栈。在 CloudFormation 外部更改堆栈可能使其处于不可恢复的状态。

  • 任何堆栈错误消息。有关查看堆栈错误消息的信息,请参阅问题排查指南部分。

  • 对于 Amazon EC2 问题,请收集 cloud-init 和 cfn 日志。这些日志是在 Amazon EC2 实例上的 /var/log/ 目录中发布的。这些日志在设置实例时捕获流程和命令输出。对于 Windows,收集 %ProgramFiles%\Amazon\EC2ConfigServiceC:\cfn\log 中的 EC2Configure 服务和 cfn 日志。

您还可以在 CloudFormation 论坛上搜索答案和发布问题。