AWS CloudFormation 最佳实践 - AWS CloudFormation
AWS 文档中描述的 AWS 服务或功能可能因区域而异。要查看适用于中国区域的差异,请参阅中国的 AWS 服务入门

本文属于机器翻译版本。若本译文内容与英语原文存在差异,则一律以英文原文为准。

AWS CloudFormation 最佳实践

最佳实践是一些建议,可帮助您在整个工作流程中更高效、更安全地使用 AWS CloudFormation。了解如何执行以下操作:计划和组织您的堆栈,创建描述您的资源以及在这些资源上运行的软件应用程序的模板,以及管理您的堆栈及其资源。以下最佳实践基于来自当前 AWS CloudFormation 客户的实际经验。

按生命周期和所有权组织您的堆栈

使用 AWS 资源的生命周期和所有权帮助您决定每个堆栈应包含的资源。最初,您可将所有资源置于一个堆栈中,但当您堆栈的规模增大和范围扩大时,管理一个堆栈将是一项麻烦且耗时的工作。通过使用常见的生命周期和所有权对资源进行分组,所有者可使用自己的流程和计划来更改其资源集而不会影响其他资源。

例如,假设开发人员和工程师团队拥有一个托管于负载均衡器后面的自动缩放实例的网站。由于该网站具有自己的生命周期并由网站团队维护,因此您可以为网站及其资源创建一个堆栈。现在假设该网站还使用后端数据库,其中数据库位于由数据库管理员所有和维护的单独堆栈中。当网站团队或数据库团队需要更新其资源时,他们可以这样做而不会影响彼此的堆栈。如果所有资源位于一个堆栈中,则协调和传达更新会很难。

有关组织堆栈的其他指导,您可以使用两个常见框架:多层架构和面向服务的架构 (SOA)。

分层架构将堆栈组织到相互堆放的多个水平层上,其中每个层都依赖于其正下方的层。每个层可包含一个或多个堆栈,但在每个层中,您的堆栈应具有带类似的生命周期和所有权的 AWS 资源。

利用面向服务的架构,可以将大型业务问题组织到可管理的部分中。每个部分均为一个服务,该服务具有清楚定义的用途并代表一个独立的功能单元。您可以将这些服务映射到一个堆栈,其中每个堆栈均拥有自己的生命周期和所有者。可将所有这些服务 (堆栈) 关联在一起,使其能够互相交互。

使用跨堆栈引用来导出共享资源

在根据生命周期和所有权安排您的 AWS 资源时,建议您构建堆栈来使用其他堆栈中的资源。您可以对值进行硬编码,或者使用输入参数传递资源名称和 ID。但是,这些方法使得模板难以重复使用,或者会增加堆栈的运行开销。相反,使用跨堆栈引用则可以从堆栈导出资源,这样其他堆栈可以使用它们。通过使用 Fn::ImportValue 函数调用导出的资源,堆栈可以使用这些资源。

例如,您可能拥有一个网络堆栈,它包含一个 VPC、一个安全组和一个子网。建议所有公有 Web 应用程序都能使用这些资源。通过导出资源,可以允许带公有 Web 应用程序的所有堆栈使用这些资源。有关更多信息,请参阅 演练:引用另一个 AWS CloudFormation 堆栈中的资源输出

验证所有资源类型的配额

在启动堆栈前,请确保您能创建所需的所有资源而不会达到 AWS 账户限制。如果您达到限制,则 AWS CloudFormation 将无法成功创建堆栈,直到您增加配额或删除超额资源。每项服务均可具有不同的限制,您在启动堆栈前应了解这些限制。例如,默认情况下,您只能在 AWS 账户中为每个区域启动 200 个 AWS CloudFormation 堆栈。有关限制以及如何增加默认限制的更多信息,请参阅 AWS General Reference 中的 AWS 服务限制

重复使用模板以在多个环境中复制堆栈

在设置您的堆栈和资源后,您可以重复使用您的模板以便在多个环境中复制您的基础结构。例如,您可以创建用于开发、测试和生产的环境,以便在应用更改前先对其进行测试。要使模板可重用,可使用参数、映射和条件部分,以便能在创建堆栈时对其进行自定义。例如,对于您的开发环境,您可以指定相对于生产环境来说成本更低的实例类型,但所有其他配置和设置保持不变。有关参数、映射和条件的更多信息,请参阅模板剖析

使用嵌套堆栈来重复使用常见模板模式

随着您的基础设施的发展,常见模式可合并以便声明每个模板中的相同组件。您可以分离这些常见组件并为其创建专用模板。这样一来,您可以混合和匹配不同的模板,但使用嵌套堆栈来创建单个统一堆栈。嵌套堆栈是可创建其他堆栈的堆栈。要创建嵌套堆栈,可使用您的模板中的 AWS::CloudFormation::Stack 资源来引用其他模板。

例如,假如您拥有用于大多数堆栈的负载均衡器配置。您可以为负载均衡器创建专用模板,而不是将相同的配置复制并粘贴到您的模板中。然后,您只需使用 AWS::CloudFormation::Stack 资源从其他模板中引用该模板。如果更新负载均衡器模板,引用该模板的任何堆栈将使用更新过的负载均衡器 (仅当您更新该堆栈后)。除了简化更新之外,该方法还允许您使用导出来创建和维护您可能不一定熟悉的组件。您只需引用其模板。

使用 AWS 特定的参数类型

如果您的模板需要输入现有的 AWS 特定的值(例如,现有的 Amazon Virtual Private Cloud ID 或 Amazon EC2 密钥对名称),请使用 AWS 特定的参数类型。例如,您可以将参数指定为 AWS::EC2::KeyPair::KeyName 类型,这会使用位于您的 AWS 账户以及从中创建堆栈的区域中的现有密钥对名称。在创建堆栈之前,AWS CloudFormation 可以快速验证 AWS 特定的参数类型的值。此外,如果您使用 AWS CloudFormation 控制台,则 AWS CloudFormation 会显示有效值的下拉列表,因此您无需查找或记住正确的 VPC ID 或密钥对名称。有关更多信息,请参阅 参数

使用参数约束

利用约束,您可以描述允许的输入值,以便 AWS CloudFormation 在创建堆栈之前捕获任何无效值。可以设置约束,例如最小长度、最大长度和允许的模式。例如,您可以对数据库用户名值设置约束,使其最小长度必须为 8 个字符且仅包含字母数字字符。有关更多信息,请参阅 参数

使用 AWS::CloudFormation::Init 在 Amazon EC2 实例上部署软件应用程序

在启动堆栈时,您可以在 Amazon EC2 实例上安装和配置软件应用程序,方式是使用 cfn-init 帮助程序脚本和 AWS::CloudFormation::Init 资源。通过使用 AWS::CloudFormation::Init,您可以描述所需的配置而不是为程序步骤编写脚本。您还可以更新配置,而无需重新创建实例。如果您的配置出现问题,AWS CloudFormation 会生成可用于调查问题的日志。

在您的模板中,在 AWS::CloudFormation::Init 资源中指定安装和配置状态。有关说明如何使用 cfn-init 和 AWS::CloudFormation::Init 的演练,请参阅 使用 AWS CloudFormation 在 Amazon EC2 上部署应用程序

使用最新的帮助程序脚本

帮助程序脚本将定期进行更新。在调用帮助程序脚本之前,请务必在您的模板的 UserData 属性中包括以下命令,以确保您的启动实例获得最新的帮助程序脚本:

yum install -y aws-cfn-bootstrap

有关获取最新的帮助程序脚本的更多信息,请参阅CloudFormation 帮助程序脚本参考

在使用模板前先验证模板

在使用模板创建或更新堆栈之前,可以先使用 AWS CloudFormation 验证模板。在 AWS CloudFormation 创建任何资源之前,验证模板可帮助您捕获语法错误和一些语义错误,例如循环依赖性。如果您使用 AWS CloudFormation 控制台,该控制台会在您指定输入参数后自动验证模板。对于 AWS CLI 或 AWS CloudFormation API,请使用 aws cloudformation validate-template 命令或 ValidateTemplate 操作。

在验证期间,AWS CloudFormation 首先检查模板是否是有效的 JSON。如果不是,AWS CloudFormation 会检查模板是否是有效的 YAML。如果两种检查都失败,AWS CloudFormation 会返回模板验证错误。

验证模板的组织策略合规性

您还可以验证模板是否符合组织策略准则。AWS CloudFormation Guard (cfn-guard) 是一种开源命令行界面 (CLI) 工具,它提供了策略即代码语言来定义规则,检查所需和禁止的资源配置。然后,您可以根据这些规则验证模板。例如,管理员可以创建规则以确保用户始终创建加密的 Amazon S3 存储桶。

您可以在编辑模板时本地使用 cfn-guard,也可以自动将其用作 CI/CD 管道的一部分,以停止非合规资源的部署。

此外,cfn-guard 还包括一个功能 rulegen,使您能够从现有兼容的 CloudFormation 模板中提取规则。

有关更多信息,请参阅 GitHub 上的 cfn-guard 存储库。

通过 AWS CloudFormation 管理所有堆栈资源

在启动堆栈后,使用 AWS CloudFormation 控制台APIAWS CLI 更新您堆栈中的资源。请勿在 AWS CloudFormation 外部更改堆栈资源。这样做会使您的堆栈模板和堆栈资源的当前状态不匹配,从而在您更新或删除堆栈时导致出现错误。有关更多信息,请参阅 演练:更新堆栈

更新堆栈之前创建更改集

使用更改集,您可以在实施之前查看建议的堆栈更改可能会对运行的资源产生何种影响。在您实际运行更改集之前,AWS CloudFormation 不会对堆栈进行任何更改,从而使您能够决定是继续实施建议的更改,还是创建其他更改集。

使用更改集来检查更改可能对您正在运行的资源造成的影响,特别是关键资源。例如,如果您更改 Amazon RDS 数据库实例的名称,AWS CloudFormation 将创建新的数据库并删除旧数据库;除非您已进行备份,否则,将会丢失旧数据库中的数据。如果您生成更改集,就可以看到更改将替换您的数据库。这可以帮助您在更新堆栈之前进行规划。有关更多信息,请参阅 使用更改集更新堆栈

使用堆栈策略

堆栈策略可帮助避免关键堆栈资源进行可能导致资源中断甚至被替换的非有意更新。堆栈策略是一个 JSON 文档,该文档描述可对指定资源执行哪些更新操作。只要创建具有重要资源的堆栈,就要指定堆栈策略。

在堆栈更新过程中,您必须显式指定要更新的受保护的资源;否则,不会更改受保护的资源。有关更多信息,请参阅 防止更新堆栈资源

使用代码审查和修订控制来管理您的模板

您的堆栈模板描述您的 AWS 资源的配置,例如它们的属性值。要查看更改并保留资源的准确历史记录,请使用代码审查和修订控制。这些方法可帮助您跟踪不同版本的模板之间的更改,以帮助您跟踪对您的堆栈资源所做的更改。此外,通过保留历史记录,您始终能将堆栈恢复为特定版本的模板。

定期更新您的 Amazon EC2 Linux 实例

在使用 AWS CloudFormation 创建的所有 Amazon EC2 Linux 实例和 Amazon EC2 Linux 实例上,可以定期运行 yum update 命令以更新 RPM 程序包。这可确保您获得最新的修复和安全更新。