

# CloudFormation 最佳实践
<a name="best-practices"></a>

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

**计划和组织**  
+ [缩短反馈循环以提高开发速度](#shortenfeedbackloop)
+ [按生命周期和所有权组织您的堆栈](#organizingstacks)
+ [使用跨堆栈引用返回另一个堆栈导出的输出值](#cross-stack)
+ [使用 Amazon CloudFormation StackSets 进行多账户和多区域部署](#stack-sets)
+ [重复使用模板以在多个环境中复制堆栈](#reuse)
+ [验证所有资源类型的配额](#limits)
+ [使用模块重复使用资源配置](#modules-reuse)
+ [采用基础设施即代码实践](#infrastructure-as-code)

**创建模板**  
+ [不要在模板中嵌入凭证](#credentials)
+ [使用 Amazon 特定的参数类型](#parmtypes)
+ [使用参数约束](#parmconstraints)
+ [使用伪参数来提高可移植性](#pseudoparameters)
+ [使用 `AWS::CloudFormation::Init` 在 Amazon EC2 实例上部署软件应用程序](#cfninit)
+ [使用最新的帮助程序脚本](#helper-scripts)
+ [在使用模板前先验证模板](#validate)
+ [使用 YAML 或 JSON 进行模板编写](#use-yaml-json)
+ [实施全面的标记策略](#resource-tags)
+ [利用模板宏进行高级转换](#template-macros-advanced-transformations)

**管理堆栈**  
+ [通过 CloudFormation 管理所有堆栈资源](#donttouch)
+ [更新堆栈之前创建更改集](#cfn-best-practices-changesets)
+ [使用堆栈策略保护资源](#stackpolicy)
+ [使用 Amazon CloudTrail 记录 CloudFormation 调用](#cloudtrail-logging)
+ [使用代码审查和修订控制来管理您的模板](#code)
+ [定期更新您的 Amazon EC2 实例](#update-ec2-linux)
+ [定期使用偏移检测](#drift-detection)
+ [配置回滚触发器以实现自动恢复](#rollback-triggers)
+ [实施有效的堆栈重构策略](#stack-refactoring-bp)
+ [使用 CloudFormation Hooks 进行生命周期管理](#cloudformation-hooks)

**编写工具**  
+ [使用 IaC 生成器从现有资源创建模板](#iac-generator)
+ [使用 Amazon 基础设施编辑器进行可视化模板设计](#infrastructure-composer)
+ [考虑对复杂的基础设施使用 Amazon Cloud Development Kit (Amazon CDK)](#cdk-integration)

**安全与合规**  
+ [使用 IAM 控制访问](#use-iam-permissions-to-control-access)
+ [采用最低权限原则](#least-privilege)
+ [保护敏感参数](#secure-parameters)
+ [通过 Amazon CloudFormation Guard 实施策略即代码](#cfn-guard)

## 缩短反馈循环以提高开发速度
<a name="shortenfeedbackloop"></a>

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

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

有关如何使用这两种工具缩短反馈循环的分步实作演练，请参阅 [Amazon CloudFormation Workshop](https://catalog.workshops.aws/cfn101/en-US) 中的 [Linting and Testing lab](https://catalog.workshops.aws/cfn101/en-US/basics/templates/linting-and-testing)。

## 按生命周期和所有权组织您的堆栈
<a name="organizingstacks"></a>

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

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

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

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

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

## 使用跨堆栈引用返回另一个堆栈导出的输出值
<a name="cross-stack"></a>

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

例如，您可能拥有一个网络堆栈，它包含一个 VPC、一个安全组和一个子网。建议所有公有 Web 应用程序都能使用这些资源。通过导出资源，可以允许带公有 Web 应用程序的所有堆栈使用这些资源。有关更多信息，请参阅 [获取从已部署的 CloudFormation 堆栈导出的输出](using-cfn-stack-exports.md)。

## 使用 Amazon CloudFormation StackSets 进行多账户和多区域部署
<a name="stack-sets"></a>

Amazon CloudFormation StackSets 通过让您在单个操作中跨多个账户和区域创建、更新或删除堆栈来扩展堆栈的功能。使用 StackSets 在整个组织内部署通用基础设施组件、​​合规性控制或共享服务。

使用 StackSets 时，请通过 Amazon Organizations 实现服务托管权限，以简化权限管理。通过这种方法，您可以将 StackSets 部署到组织内的账户，而无需在每个账户中手动配置 IAM 角色。

有关 StackSets 的更多信息，请参阅 [StackSets 概念](https://docs.amazonaws.cn/AWSCloudFormation/latest/UserGuide/stacksets-concepts.html)。

## 验证所有资源类型的配额
<a name="limits"></a>

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

## 重复使用模板以在多个环境中复制堆栈
<a name="reuse"></a>

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

## 使用模块重复使用资源配置
<a name="modules-reuse"></a>

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

这些构建块可以用于单个资源，例如定义 Amazon Elastic Compute Cloud (Amazon EC2) 实例的最佳实践，也可以用于多个资源，以定义应用程序架构的通用模式。这些构建块可以嵌套到其他模块中，因此您可以将最佳实践堆叠到更高级别的构建块中。CloudFormation 模块在 [CloudFormation 注册表](registry.md)中可用，因此您可以像使用本机资源一样使用它们。使用 CloudFormation 模块时，模块模板会扩展到使用模板中，这样您就可以使用 [Ref](https://docs.amazonaws.cn/AWSCloudFormation/latest/TemplateReference/intrinsic-function-reference-ref.html) 或 [Fn::GetAtt](https://docs.amazonaws.cn/AWSCloudFormation/latest/TemplateReference/intrinsic-function-reference-getatt.html) 来访问模块内的资源。有关更多信息，请参阅 [使用 CloudFormation 模块创建可跨模板包含的可重复使用的资源配置](modules.md)。

## 采用基础设施即代码实践
<a name="infrastructure-as-code"></a>

通过实施基础设施即代码 (IaC) 实践，将 CloudFormation 模板视为代码。将模板存储在版本控制系统中，实施代码审查，并使用自动化测试来验证更改。此方法可确保一致性、改善协作，并为基础设施更改提供审计跟踪记录。

考虑为基础设施代码实施 CI/CD 管道，以自动测试和部署 CloudFormation 模板。Amazon CodePipeline、Amazon CodeBuild 和 Amazon CodeDeploy 等工具可用于为基础设施部署创建自动化工作流。

有关实施 IaC 最佳实践的更多信息，请参阅 [Using Amazon CloudFormation as an IaC tool](https://docs.amazonaws.cn/prescriptive-guidance/latest/choose-iac-tool/cloudformation.html)。

有关使用 CloudFormation 进行持续交付的更多信息，请参阅[利用 CodePipeline 进行持续交付](https://docs.amazonaws.cn/AWSCloudFormation/latest/UserGuide/continuous-delivery-codepipeline.html)。

## 不要在模板中嵌入凭证
<a name="credentials"></a>

我们建议您在堆栈模板中使用*动态引用*，而不是在 CloudFormation 模板中嵌入敏感信息。

动态引用提供了一种简洁、功能强大的方法，用于引用在其他服务（例如 Amazon Systems Manager Parameter Store 或 Amazon Secrets Manager）中存储和管理的外部值。当您使用动态引用时，CloudFormation 会在堆栈和更改集合操作期间根据需要检索指定引用的值，并将值传递到相应的资源。但是，CloudFormation 从不存储实际引用值。有关更多信息，请参阅[使用动态引用以指定模板值](https://docs.amazonaws.cn/AWSCloudFormation/latest/UserGuide/dynamic-references.html)。

[Amazon Secrets Manager](https://docs.amazonaws.cn/secretsmanager/latest/userguide/intro.html) 帮助您安全地加密、存储和检索数据库和其他服务的凭证。[Amazon Systems Manager Parameter Store](https://docs.amazonaws.cn/systems-manager/latest/userguide/systems-manager-parameter-store.html) 提供安全的分层存储，用于配置数据管理。

有关定义模板参数的信息，请参阅[CloudFormation 模板 Parameters 语法](parameters-section-structure.md)。

## 使用 Amazon 特定的参数类型
<a name="parmtypes"></a>

如果您的模板需要输入现有的 Amazon 特定的值（例如，现有的 Amazon Virtual Private Cloud ID 或 Amazon EC2 密钥对名称），请使用 Amazon 特定的参数类型。例如，您可以将参数指定为类型 `AWS::EC2::KeyPair::KeyName`，这将使用位于 Amazon Web Services 账户和从中创建堆栈的区域中的现有密钥对名称。CloudFormation 可在创建堆栈之前快速验证 Amazon 特定参数类型的值。此外，如果您使用 CloudFormation 控制台，则 CloudFormation 会显示有效值的下拉列表，因此您无需查找或记住正确的 VPC ID 或密钥对名称。有关更多信息，请参阅 [使用 CloudFormation 提供的参数类型在运行时指定现有资源](cloudformation-supplied-parameter-types.md)。

## 使用参数约束
<a name="parmconstraints"></a>

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

## 使用伪参数来提高可移植性
<a name="pseudoparameters"></a>

您可以在模板中使用[伪参数](pseudo-parameter-reference.md)作为[内部函数](https://docs.amazonaws.cn/AWSCloudFormation/latest/TemplateReference/intrinsic-function-reference.html)的参数，例如 `Ref` 和 `Fn::Sub`。伪参数是 CloudFormation 预定义的参数。请您不要在您的模板中声明它们。在内置函数中使用伪参数可提高堆栈模板在区域和账户之间的可移植性。

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

另举一例，假设您想要跨多个堆栈共享资源或配置。在此示例中，假设您已为您的 VPC 创建一个[子网](https://docs.amazonaws.cn/vpc/latest/userguide/configure-subnets.html)，然后导出其 ID 以便与相同 Amazon Web Services 账户和区域中的其他堆栈一起使用。在另一个堆栈中，您在描述 Amazon EC2 实例时引用子网 ID 的导出值。有关使用 `Export` 输出字段和 `Fn::ImportValue` 内置函数的详细示例，请参阅 [引用其他 CloudFormation 堆栈中的资源输出](walkthrough-crossstackref.md)。

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

## 使用 `AWS::CloudFormation::Init` 在 Amazon EC2 实例上部署软件应用程序
<a name="cfninit"></a>

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

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

## 使用最新的帮助程序脚本
<a name="helper-scripts"></a>

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

```
yum install -y aws-cfn-bootstrap
```

有关获取最新帮助程序脚本的更多信息，请参阅《Amazon CloudFormation 模板参考指南》**中的 [CloudFormation 帮助程序脚本参考](https://docs.amazonaws.cn/AWSCloudFormation/latest/TemplateReference/cfn-helper-scripts-reference.html)。

## 在使用模板前先验证模板
<a name="validate"></a>

在使用模板创建或更新堆栈之前，可以先使用 CloudFormation 验证模板。在 CloudFormation 创建任何资源之前，验证模板可帮助您捕获语法错误和一些语义错误，例如循环依赖性。如果您使用 CloudFormation 控制台，该控制台会在您指定输入参数后自动验证模板。对于 Amazon CLI 或 CloudFormation API，请使用 [https://docs.amazonaws.cn/cli/latest/reference/cloudformation/validate-template.html](https://docs.amazonaws.cn/cli/latest/reference/cloudformation/validate-template.html) CLI 命令或 [https://docs.amazonaws.cn/AWSCloudFormation/latest/APIReference/API_ValidateTemplate.html](https://docs.amazonaws.cn/AWSCloudFormation/latest/APIReference/API_ValidateTemplate.html) API 操作。

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

### 验证模板的组织策略合规性
<a name="validate-compliance"></a>

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

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

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

有关更多信息，请参阅 GitHub 上的 [cfn-guard](https://github.com/aws-cloudformation/cloudformation-guard) 存储库。

## 使用 YAML 或 JSON 进行模板编写
<a name="use-yaml-json"></a>

CloudFormation 支持 YAML 和 JSON 格式的模板。每种都有其优点，具体选择取决于特定需求：

在以下情况下使用 YAML
+ 优先考虑可读性和可维护性
+ 希望包括注释来记录模板
+ 正在处理带有嵌套结构的复杂模板
+ 希望使用 YAML 特有的功能（如锚点和别名）来减少重复

在以下情况下使用 JSON：
+ 需要与支持 JSON 格式的工具或系统集成
+ 正在使用编程模板生成或操作
+ 需要严格的数据验证

由于 YAML 的可读性和注释支持，通常建议用于手动模板编写。它对于复杂的模板特别有用，其中基于缩进的结构有助于可视化资源层次结构。JSON 在自动化工作流中或使用需要 JSON 输入的 API 时具有优势。当需要确保严格遵守特定结构时，它也是有益的。无论您选择哪种格式，都应专注于创建结构良好、有据可查且易于维护的模板。如果使用 YAML，请利用其锚点和别名等功能来减少重复并提高可维护性。

## 实施全面的标记策略
<a name="resource-tags"></a>

为 CloudFormation 模板创建的所有资源实施一致的标记策略。标签有助于资源组织、成本分配、访问控制以及自动化。考虑包括环境、所有者、成本中心、应用程序和目的的标签。

使用 `AWS::CloudFormation::Stack` 资源的 `Tags` 属性将标签应用于堆栈中所有支持的资源。您还可以使用许多资源类型可用的 `TagSpecifications` 属性在资源创建期间应用标签。

有关标记的更多信息，请参阅[资源标记](https://docs.amazonaws.cn/AWSCloudFormation/latest/TemplateReference/aws-properties-resource-tags.html)。

## 利用模板宏进行高级转换
<a name="template-macros-advanced-transformations"></a>

CloudFormation 宏使您能够对模板执行自定义处理，从查找和替换操作等简单操作到生成额外资源的复杂转换。使用宏来扩展 CloudFormation 模板的功能并在整个组织中实施可重复使用的模式。

Amazon Serverless Application Model是一个简化无服务器应用程序开发的宏示例。请考虑为组织特定的模式和要求创建自定义宏。

有关在模板中使用宏的更多信息，请参阅 [CloudFormation 宏概述](https://docs.amazonaws.cn/AWSCloudFormation/latest/UserGuide/template-macros-overview.html)。

## 通过 CloudFormation 管理所有堆栈资源
<a name="donttouch"></a>

在启动堆栈后，使用 CloudFormation [控制台](https://console.amazonaws.cn/cloudformation/home)、[API](https://docs.amazonaws.cn/AWSCloudFormation/latest/APIReference/) 或 [Amazon CLI](https://docs.amazonaws.cn/cli/latest/reference/cloudformation/index.html) 更新您堆栈中的资源。请勿在 CloudFormation 外部更改堆栈资源。这样做会使您的堆栈模板和堆栈资源的当前状态不匹配，从而在您更新或删除堆栈时导致出现错误。这就是所谓的偏差。如果对 CloudFormation 模板之外的资源进行了更改，并且您更新了堆栈，则直接对该资源所做的更改将被丢弃，并且资源配置将恢复为模板中的配置。

有关偏移的更多信息，请参阅[什么是偏差？](using-cfn-stack-drift.md#what-is-drift)。

有关更新堆栈的更多信息，请参阅[更新 CloudFormation 堆栈](updating.stacks.walkthrough.md)。

## 更新堆栈之前创建更改集
<a name="cfn-best-practices-changesets"></a>

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

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

## 使用堆栈策略保护资源
<a name="stackpolicy"></a>

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

在堆栈更新过程中，您必须显式指定要更新的受保护的资源；否则，不会更改受保护的资源。有关更多信息，请参阅 [防止更新堆栈资源](protect-stack-resources.md)。

## 使用 Amazon CloudTrail 记录 CloudFormation 调用
<a name="cloudtrail-logging"></a>

Amazon CloudTrail 跟踪在您的 Amazon Web Services 账户中进行 CloudFormation API 调用的任何人。当任何人使用 CloudFormation API、CloudFormation 控制台、后端控制台或 CloudFormation Amazon CLI 命令时，系统将会记录 API 调用。启用日志记录并指定用于存储日志的 Amazon S3 存储桶。这样一来，在需要时，您可以审核在您的账户中发起 CloudFormation 调用的人员。

有关更多信息，请参阅 [使用 Amazon CloudTrail 记录 Amazon CloudFormation API 调用](cfn-api-logging-cloudtrail.md)。

## 使用代码审查和修订控制来管理您的模板
<a name="code"></a>

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

## 定期更新您的 Amazon EC2 实例
<a name="update-ec2-linux"></a>

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

## 定期使用偏移检测
<a name="drift-detection"></a>

定期使用 CloudFormation 偏移检测功能来识别在 CloudFormation 管理范围之外已修改的资源。检测和解决偏移有助于维护基础设施即代码方法的完整性，并确保模板准确反映已部署资源的状态。

考虑将自动偏移检测作为运营流程的一部分实施。您可以使用由 Amazon EventBridge 规则触发的 Amazon Lambda 函数定期检查偏移，并在检测到差异时通知您的团队。

有关偏移的更多信息，请参阅[使用偏移检测功能检测堆栈和资源的非托管配置更改](https://docs.amazonaws.cn/AWSCloudFormation/latest/UserGuide/using-cfn-stack-drift.html)。

## 配置回滚触发器以实现自动恢复
<a name="rollback-triggers"></a>

使用回滚触发器指定 CloudFormation 在堆栈创建和更新操作期间应监控的 Amazon CloudWatch 警报。如果任何指定的警报进入 `ALARM` 状态，CloudFormation 将自动回滚整个堆栈操作，从而帮助确保基础设施保持稳定状态。

为关键指标（例如应用程序错误率、系统资源利用率或指示应用程序和基础设施运行状况的自定义业务指标）配置回滚触发器。

有关回滚触发器的更多信息，请参阅[在突破警报阈值时回滚堆栈](https://docs.amazonaws.cn/AWSCloudFormation/latest/UserGuide/using-cfn-rollback-triggers.html)。

## 实施有效的堆栈重构策略
<a name="stack-refactoring-bp"></a>

随着基础设施的发展，您可能需要重构 CloudFormation 堆栈来提高可维护性、降低复杂性或适应不断变化的需求。堆栈重构涉及重构模板和资源，同时保留其外部行为和功能。堆栈重构通过以下方式与 CloudFormation 一起使用是有益的：
+ *拆分整体堆栈*：将大型、复杂的堆栈分解为按生命周期或所有权组织的更小、更易于管理的堆栈
+ *整合相关资源*：将来自多个堆栈的相关资源组合成一个单一的、有凝聚力的堆栈，以简化管理
+ *提取可重用组件*：将常见模式移入模块或嵌套堆栈，以促进重用和一致性
+ *改进资源组织*：重构堆栈内的资源，以更好地反映它们之间的关系和依赖项

有关重构 CloudFormation 堆栈的更多信息，请参阅[堆栈重构](stack-refactoring.md)。

## 使用 CloudFormation Hooks 进行生命周期管理
<a name="cloudformation-hooks"></a>

CloudFormation Hooks 提供的代码可在预置之前主动检查 Amazon 资源配置，并执行复杂的验证检查。Hooks 会检查资源、堆栈和更改集是否符合组织的安全、运营和成本优化需求。它们会在资源预置之前发出警告，或者根据配置方式导致操作失败并完全停止。违规行为和警告会记录在 Amazon CloudWatch 中，以便您了解不合规的部署。

有关 Hooks 的这些最佳实践的更多信息，请参阅 [Amazon CloudFormation Hooks concepts](https://docs.amazonaws.cn/cloudformation-cli/latest/hooks-userguide/hooks-concepts.html)。

有关 Hooks 可以为 CloudFormation 资源做什么的更多信息，请参阅 [What are Amazon CloudFormation Hooks?](https://docs.amazonaws.cn/cloudformation-cli/latest/hooks-userguide/what-is-cloudformation-hooks.html)

## 使用 IaC 生成器从现有资源创建模板
<a name="iac-generator"></a>

CloudFormation IaC（基础设施即代码）生成器可帮助您利用现有 Amazon 资源创建 CloudFormation 模板。当您需要复制现有基础设施、记录手动创建的资源或将以前未管理的资源纳入 CloudFormation 管理时，此功能特别有用。IaC 生成器可通过以下方式创建 CloudFormation 模板：
+ *加速模板创建*：从现有资源生成模板，而不是从头开始编写
+ *一致的基础设施*：使用生成的模板作为起点，确保新环境与现有环境匹配
+ *迁移到基础设施即代码*：逐步将手动创建的资源纳入 CloudFormation 管理
+ *文档*：以模板形式创建现有基础设施的记录

有关 IaC 生成器的更多信息，请参阅[使用 IaC 生成器为现有资源生成模板](https://docs.amazonaws.cn/AWSCloudFormation/latest/UserGuide/generate-IaC.html)。

## 使用 Amazon 基础设施编辑器进行可视化模板设计
<a name="infrastructure-composer"></a>

Amazon 基础设施编辑器是一款可视化设计工具，可帮助您使用拖放界面创建、可视化和修改 CloudFormation 模板。在以下情况下使用 CloudFormation 时，该工具尤其有用：
+ *架构规划*：实施前设计和验证基础设施架构
+ *模板现代化*：可视化现有模板，了解其结构并发现改进机会
+ *培训和入职*：通过可视化学习帮助新团队成员理解 CloudFormation 概念和 Amazon 服务关系
+ *利益相关者沟通*：使用清晰的可视化表示向非技术利益相关者展示基础设施设计
+ *合规性审查*：使用可视化图表促进基础设施设计的安全性和合规性审查
+ *合规性审查*：使用可视化图表促进基础设施设计的安全性和合规性审查

有关基础设施编辑器的更多信息，请参阅 [What is Amazon 基础设施编辑器?](https://docs.amazonaws.cn/infrastructure-composer/latest/dg/what-is-composer.html)。

## 考虑对复杂的基础设施使用 Amazon Cloud Development Kit (Amazon CDK)
<a name="cdk-integration"></a>

对于复杂的基础设施需求，请考虑使用 CDK，通过熟悉的编程语言（如 TypeScript、Python、Java 和 .NET）来定义云资源。Amazon CDK 会根据您的代码生成 CloudFormation 模板，让您能够充分利用 CloudFormation 的全部功能，同时使用首选语言的抽象和编程结构。

Amazon CDK 提供高级构造，封装最佳实践并简化常见基础设施模式的定义。这可以显著减少定义基础设施所需的代码量，同时确保遵循最佳实践。

有关 CDK 的更多信息，请参阅 [Amazon Cloud Development Kit (Amazon CDK)](https://docs.amazonaws.cn/cdk/api/v2/)。

## 使用 IAM 控制访问
<a name="use-iam-permissions-to-control-access"></a>

IAM 是一项可用于管理 Amazon 中的用户及其权限的 Amazon 服务。您可以将 IAM 与 CloudFormation 结合使用来指定用户可以执行哪些 CloudFormation 操作，例如查看堆栈模板、创建堆栈或删除堆栈。此外，管理 CloudFormation 堆栈的任何人都需要具备对这些堆栈中的资源执行操作的权限。例如，如果用户想使用 CloudFormation 启动、更新或终止 Amazon EC2 实例，则他们必须拥有调用相关 Amazon EC2 操作的权限。

在大多数情况下，用户需要完全访问权限来管理模板中的所有资源。CloudFormation 可代表用户发出调用，来创建、修改和删除这些资源。要分隔用户和 CloudFormation 服务之间的权限，请使用服务角色。CloudFormation 使用服务角色的策略发出调用，而不是通过用户的策略。有关更多信息，请参阅 [Amazon CloudFormation 服务角色](using-iam-servicerole.md)。

## 采用最低权限原则
<a name="least-privilege"></a>

在为 CloudFormation 服务角色或模板创建的资源配置 IAM 角色时，请始终遵循最低权限原则。仅授予预期功能所需的权限，并尽可能避免使用通配符权限。

使用 IAM Access Analyzer 查看向 CloudFormation 服务角色授予的权限，并确定可移除的未使用权限。定期审查和更新 IAM 策略，以确保它们符合您的安全要求。

## 保护敏感参数
<a name="secure-parameters"></a>

对于密码、API 密钥和其他机密等敏感信息，请使用 Amazon Systems Manager Parameter Store 或 Amazon Secrets Manager，而不是将其直接嵌入模板中。请在模板中使用动态引用，以便在堆栈操作期间安全地检索这些值。

在模板中使用参数时，请将敏感参数的 `NoEcho` 属性设置为 `true`，以防止其值显示在控制台、API 响应或 CLI 输出中。请注意，如果将值传递给可能记录该值的其他服务或资源，`NoEcho` 不会阻止记录该值。

有关将 Amazon Systems Manager Parameter Store 与 CloudFormation 结合使用的更多信息，请参阅[获取 Amazon Systems Manager Parameter Store 中的纯文本值](https://docs.amazonaws.cn/AWSCloudFormation/latest/UserGuide/dynamic-references-ssm.html)。

有关使用 `NoEcho` 属性的更多信息，请参阅 [CloudFormation 模板 Parameters 语法](https://docs.amazonaws.cn/AWSCloudFormation/latest/UserGuide/parameters-section-structure.html#parameters-section-structure-properties)。

有关将 Amazon Secrets Manager 与 CloudFormation 结合使用的更多信息，请参阅 [Create Amazon Secrets Manager secrets in Amazon CloudFormation](https://docs.amazonaws.cn/secretsmanager/latest/userguide/cloudformation.html)。

## 通过 Amazon CloudFormation Guard 实施策略即代码
<a name="cfn-guard"></a>

Amazon CloudFormation Guard (`cfn-guard`) 是一款开源策略即代码工具，可让您为 CloudFormation 模板定义和强制执行规则。使用 `cfn-guard` 可确保模板符合组织策略、安全最佳实践和治理要求。

将 `cfn-guard` 集成到 CI/CD 管道中，以便在部署之前根据策略规则自动验证模板。这有助于防止不合规资源部署到环境中，并向开发人员提供有关策略违规行为的早期反馈。

有关 Guard 的更多信息，请参阅 [What is Amazon CloudFormation Guard?](https://docs.amazonaws.cn/cfn-guard/latest/ug/what-is-guard.html)