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

Amazon CloudFormation 最佳实践

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

缩短反馈循环以提高传输速度

采用实践和工具,以帮助您缩短使用 CloudFormation 模板描述的基础架构的反馈循环。这包括在工作站中对模板执行早期检查和测试;执行此操作时,甚至在向源代码存储库提交贡献之前,您就有机会发现潜在的语法和配置问题。及早发现此类问题有助于防止这些问题进入正式的生命周期环境,例如开发、质量保证和生产。这种早期测试、快速失效机制方法的好处是减少返工等待时间、减少潜在影响区域,并提高您对成功进行配置操作的信心。

帮助您进行快速失效机制实践的工具选择包括 Amazon CloudFormation Linter(cfn-lint)和 TaskCat 命令行工具。cfn-lint 工具让您能够根据 Amazon CloudFormation 资源规范验证 CloudFormation 模板。这包括检查资源属性的有效值以及最佳实践。cfn-lint 的插件可用于许多代码编辑器;这让您能够在编辑器中可视化问题并获得直接的 linter 反馈。您也可以选择将 cfn-lint 集成到源代码存储库的配置中,以便您可以在提交贡献时执行模板验证。有关更多信息,请参阅 Git pre-commit validation of Amazon CloudFormation templates with cfn-lint。执行初始检查并修复了 cfn-lint 可能出现的任何问题后,您就可以使用 TaskCat 在您选择的 Amazon 区域以编程方式创建堆栈来测试模板。TaskCat 还会生成报告,其中包含您选择的每个区域的通过/未通过等级。

有关如何使用这两种工具缩短反馈循环的分步实作演练,请参阅 Amazon CloudFormation Workshop 中的 Linting and Testing lab

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

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

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

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

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

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

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

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

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

验证所有资源类型的配额

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

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

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

使用模块重复使用资源配置

随着您的基础设施的发展,常见模式可合并以便声明每个模板中的相同组件。模块是一种供您以透明、易管理和可重复的方式打包资源配置以便跨堆栈模板实现包含的方法。模块可以将常见服务配置和最佳实践封装为模块化、可自定义的构建基块,供您包含在堆栈模板中。

这些构建块可以用于单个资源,例如定义 Amazon Elastic Compute Cloud (Amazon EC2) 实例的最佳实践,也可以用于多个资源,以定义应用程序架构的通用模式。这些构建块可以嵌套到其他模块中,因此您可以将最佳实践堆叠到更高级别的构建块中。CloudFormation 模块在 CloudFormation 注册表中可用,因此您可以像使用本机资源一样使用它们。使用 CloudFormation 模块时,模块模板会扩展到使用模板中,这样您就可以使用 RefFn::GetAtt 来访问模块内的资源。有关更多信息,请参阅模块

使用 Amazon 特定的参数类型

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

使用参数约束

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

使用伪参数来提高可移植性

您可以在模板中使用伪参数作为内部函数的参数,例如 RefFn::Sub。伪参数是 CloudFormation 预定义的参数。请您不要在您的模板中声明它们。在内部函数中使用伪参数会提高堆栈模板在区域和账户之间的可移植性。

例如,假设您想要创建一个模板,在该模板中,您需要为给定的资源属性指定另一个现有资源的 Amazon 资源名称(ARN)。在这种情况下,现有资源是具有以下 ARN 的 Amazon Systems Manager Parameter Store 资源:arn:aws:ssm:us-east-1:111122223333:parameter/MySampleParameter。您将需要根据您的目标 Amazon 分区、区域和账户 ID 调整 ARN 格式。您可以使用 AWS::PartitionAWS::RegionAWS::AccountId 伪参数来提高模板的可移植性,而不用对这些值进行硬编码。在这种情况下,以下示例向您展示如何将 ARN 中的元素与 CloudFormation 连接:!Sub 'arn:${AWS::Partition}:ssm:${AWS::Region}:${AWS::AccountId}:parameter/MySampleParameter

另举一例,假设您想要使用 演练:引用另一个 Amazon CloudFormation 堆栈中的资源输出 来引用另一个 CloudFormation 堆栈中的资源输出。在此示例中,假设您已为您的 VPC 创建一个子网,然后导出其 ID 以便与相同账户和区域中的其他堆栈一起使用。在另一个堆栈中,您在描述 Amazon EC2 实例时引用子网 ID 的导出值。

对于每个账户和区域,堆栈导出必须是唯一的。因此,在这种情况下,您可以使用 AWS::StackName 伪参数为您的导出创建前缀。由于每个账户和区域的堆栈名称也必须是唯一的,因此使用此伪参数作为前缀可以提高具有唯一导出名称的可能性,同时还推广了在导出值的堆栈之间采用可重复使用的方法。或者,您可以使用您自己选择的前缀。

有关使用 Export 输出字段和 Fn::ImportValue 内置函数的详细示例,请参阅 演练:引用另一个 Amazon CloudFormation 堆栈中的资源输出

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

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

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

使用最新的帮助程序脚本

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

yum install -y aws-cfn-bootstrap

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

在使用模板前先验证模板

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

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

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

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

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

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

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

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

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

更新堆栈之前创建更改集

更改集允许您在实施之前查看对堆栈提议的更改可能会如何影响正在运行的资源。在您运行更改集之前,CloudFormation 不会对您的堆栈进行任何更改,从而允许您决定是继续进行提议的更改还是创建另一个更改集。

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

使用堆栈策略

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

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

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

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

定期更新您的 Amazon EC2 实例

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