

# 使用偏移检测功能检测堆栈和资源的非托管配置更改
<a name="using-cfn-stack-drift"></a>

即使您通过 CloudFormation 管理您的资源，用户也可以在 CloudFormation之外更改这些资源。用户可以使用创建资源的底层服务直接编辑资源。例如，您可以使用 Amazon EC2 控制台来更新作为 CloudFormation 堆栈的一部分创建的服务器实例。有些更改可能是偶然的，而有些更改可能会故意响应对时间敏感的操作事件。无论如何，在 CloudFormation 之外进行的更改会导致堆栈更新或删除操作变得复杂。您可以使用偏差检测来识别在 CloudFormation 管理之外进行配置更改的堆栈资源。然后，您可以采取纠正措施，使堆栈资源再次与其在堆栈模板中的定义同步，例如直接更新偏离的资源，以便它们与其模板定义一致。解决偏差有助于确保配置一致性和成功的堆栈操作。

**Topics**
+ [什么是偏差？](#what-is-drift)
+ [偏差检测状态代码](#drift-status-codes)
+ [检测偏差时的注意事项](#drift-considerations)
+ [在整个 CloudFormation 堆栈上检测偏差](detect-drift-stack.md)
+ [在单个堆栈资源上检测偏差](detect-drift-resource.md)
+ [通过导入操作消除偏差](resource-import-resolve-drift.md)

## 什么是偏差？
<a name="what-is-drift"></a>

通过偏离检测，您可以检测堆栈的实际配置是否与其预期配置不同或已经*偏离*。使用 CloudFormation 可在整个堆栈上或在堆栈内的单个资源上检测偏差。如果某个资源的任何实际属性值与预期的属性值不同，则认为该资源已偏离。这包括是否已删除属性或资源。如果堆栈的一个或多个资源已偏离，则认为堆栈已偏离。

为了确定资源是否已偏离，CloudFormation 确定预期的资源属性值（如堆栈模板中所定义）以及任何指定为模板参数的值。然后 CloudFormation 将这些预期值与堆栈中当前存在的资源属性的实际值进行比较。如果资源的一个或多个属性已被删除或其值已更改，则认为该资源已偏离。

CloudFormation 生成有关已偏离的堆栈中每个资源的详细信息。

CloudFormation 在那些支持偏差检测的 Amazon 资源上检测偏差。不支持偏差检测的资源会被分配 NOT\$1CHECKED 的偏差状态。有关支持偏差检测的 Amazon 资源的列表，请参阅 [资源类型支持](resource-import-supported-resources.md)。

此外，CloudFormation 还支持对*可预置*的私有资源类型（即其预置类型为 `FULLY_MUTABLE` 或 `IMMUTABLE`）进行偏差检测。要对私有资源类型的资源执行偏差检测，您在账户中注册的资源类型的默认版本必须可预置。有关资源预置类型的更多信息，请参阅《Amazon CloudFormation API Reference》**中 [https://docs.amazonaws.cn/AWSCloudFormation/latest/APIReference/API_DescribeType.html](https://docs.amazonaws.cn/AWSCloudFormation/latest/APIReference/API_DescribeType.html) 操作的 `ProvisioningType` 参数和《Amazon CLI Command Reference》**中 [https://docs.amazonaws.cn/cli/latest/reference/cloudformation/describe-type.html](https://docs.amazonaws.cn/cli/latest/reference/cloudformation/describe-type.html) 命令的参数。有关私有资源的更多信息，请参阅 [通过 CloudFormation 注册表管理扩展](registry.md)。

您可以在具有以下状态的堆栈上执行偏差检测：`CREATE_COMPLETE`、`UPDATE_COMPLETE`、`UPDATE_ROLLBACK_COMPLETE` 和 `UPDATE_ROLLBACK_FAILED`。

当在堆栈上检测偏差时，CloudFormation 不在任何属于该堆栈的嵌套堆栈上检测偏差。有关更多信息，请参阅 [使用嵌套堆栈将模板拆分为可重复使用的部分](using-cfn-nested-stacks.md)。相反，您可以直接在嵌套堆栈上启动偏差检测操作。

**注意**  
CloudFormation 仅通过堆栈模板或通过指定模板参数来确定显式设置的属性值的偏差。这不包括资源属性的默认值。要使 CloudFormation 跟踪资源属性以确定偏差，请显式设置属性值，即使您将其设置为默认值也是如此。

## 偏差检测状态代码
<a name="drift-status-codes"></a>

本节中的表描述了偏差检测使用的各种状态类型：
+ **偏差检测操作状态**描述偏差操作的当前状态。
+ **偏差状态** 

  对于堆栈集，它根据属于堆栈集的堆栈实例的偏差状态以描述堆栈集的总体偏差状态。

  对于堆栈实例，它根据堆栈实例的关联堆栈的偏差状态以描述堆栈实例的偏差状态。

  对于堆栈，它根据堆栈资源的偏差状态以描述堆栈的总体偏差状态。
+ **资源偏差状态**描述单个资源的偏差状态。

下表列出了 CloudFormation 分配给堆栈偏差检测操作的状态代码。


| 偏差检测操作状态 | 说明 | 
| --- | --- | 
|  `DETECTION_COMPLETE`  |  已经对支持偏差检测的堆栈中的所有资源成功完成了堆栈偏差检测操作。  | 
|  `DETECTION_FAILED`  |  堆栈偏差检测操作对于堆栈中的至少一个资源失败。结果将可用于 CloudFormation 在其上成功完成偏差检测的资源。  | 
|  `DETECTION_IN_PROGRESS`  |  堆栈偏差检测操作目前正在进行中。  | 

下表列出了 CloudFormation 分配给堆栈的偏差状态代码。


| 偏差状态 | 说明 | 
| --- | --- | 
|  `DRIFTED`  |  对于堆栈：堆栈与其预期模板配置不同或*已偏离*。如果堆栈的一个或多个资源已偏离，则认为堆栈已偏离。 对于堆栈实例：如果与堆栈实例关联的堆栈已偏离，则认为该实例已偏离。 对于堆栈集：如果一个或多个堆栈实例已偏离，则认为堆栈集已偏离。  | 
|  `NOT_CHECKED`  |  CloudFormation 尚未检查堆栈、堆栈集或堆栈实例是否与其预期模板配置不同。  | 
|  `IN_SYNC`  |  每个受支持资源的当前配置与其预期的模板配置相匹配。没有支持偏差检测的资源的堆栈、堆栈集或堆栈实例也具有 IN\$1SYNC 状态。  | 

下表列出了 CloudFormation 分配给堆栈资源的偏差代码。


| 资源偏差状态 | 说明 | 
| --- | --- | 
|  `DELETED`  |  资源与预期的模板配置不同，因为资源已被删除。  | 
|  `MODIFIED`  |  资源与预期的模板配置不同。  | 
|  `NOT_CHECKED`  |  CloudFormation 没有检查资源是否与预期的模板配置不同。  | 
|  `IN_SYNC`  |  资源的当前配置与其预期的模板配置相匹配。  | 

下表列出了 CloudFormation 分配给与预期模板配置不同的资源属性的差异类型状态代码。


| 属性差异类型 | 说明 | 
| --- | --- | 
|  `ADD`  |  已将值添加到数据类型为数组或列表的资源属性。  | 
|  `REMOVE`  |  属性已从当前资源配置中删除。  | 
|  `NOT_EQUAL`  |  当前属性值与堆栈模板中定义的预期值不同。  | 

## 检测偏差时的注意事项
<a name="drift-considerations"></a>

为了在堆栈上成功执行偏差检测，用户必须具有以下权限：
+ 支持在堆栈中包含的偏差检测的每个资源的读取权限。例如，如果堆栈包含 `AWS::EC2::Instance` 资源，则您必须具有 `ec2:DescribeInstances` 权限才能在堆栈上执行偏差检测。
+ `cloudformation:DetectStackDrift`
+ `cloudformation:DetectStackResourceDrift`
+ `cloudformation:BatchDescribeTypeConfigurations`

有关在 CloudFormation 中设置权限的更多信息，请参阅 [使用 Amazon Identity and Access Management 控制 CloudFormation 访问权限](control-access-with-iam.md)。

在某些边缘情况下，CloudFormation 可能无法始终返回准确的偏差结果。您应该了解这些边缘情况，以便正确解释您的偏差检测结果。
+ 在某些情况下，属性数组中包含的对象将报告为偏差，而实际上它们是从负责该资源的底层服务提供给属性的默认值。
+ 某些资源与相关资源具有附件关系，使得资源可以实际附加或删除在相同或另一模板中定义的另一资源的属性值。例如，如果 `AWS::EC2::SecurityGroupIngress` 和 `AWS::EC2::SecurityGroupEgress` 资源也可用于连接和删除 `AWS::EC2::SecurityGroup` 资源中的值。在这些情况下，CloudFormation 在执行偏差比较之前分析附件的堆栈模板。但是，CloudFormation 无法跨堆栈执行此分析，因此可能不会返回准确的偏差结果，其中附加的资源驻留在不同的堆栈中。

  支持偏差检测并允许或要求其他资源中的附件的资源包括：    
[\[See the AWS documentation website for more details\]](http://docs.amazonaws.cn/AWSCloudFormation/latest/UserGuide/using-cfn-stack-drift.html)
+ CloudFormation 不对任何资源的 `KMSKeyId` 属性执行偏差检测。由于 Amazon KMS 密钥可以由多个别名引用，因此 CloudFormation 无法保证此属性有一致准确的偏差结果。
+ 您可以在堆栈模板中指定某些资源属性，就其本质而言，CloudFormation 无法将其与生成的堆栈资源中的属性进行比较。因此，这些属性不能包括在偏差检测结果中。这些属性可分为两大类：
  + CloudFormation 无法在堆栈模板中映射回初始资源属性值的属性值。

    例如，CloudFormation 无法将 Lambda 函数的源代码映射回 [https://docs.amazonaws.cn/AWSCloudFormation/latest/TemplateReference/aws-resource-lambda-function.html](https://docs.amazonaws.cn/AWSCloudFormation/latest/TemplateReference/aws-resource-lambda-function.html) 资源的 [https://docs.amazonaws.cn/AWSCloudFormation/latest/TemplateReference/aws-properties-lambda-function-code.html](https://docs.amazonaws.cn/AWSCloudFormation/latest/TemplateReference/aws-properties-lambda-function-code.html) 属性类型，因此 CloudFormation 无法将其包括在偏差检测结果中。
  + 负责资源的服务不返回的属性值。

    某些属性值被有意设计成永远不会由资源所属的服务返回。这些属性值往往包含机密信息，例如密码或其他不应泄露的敏感数据。例如，IAM 服务永远不会返回 [https://docs.amazonaws.cn/AWSCloudFormation/latest/TemplateReference/aws-properties-iam-user-loginprofile.html](https://docs.amazonaws.cn/AWSCloudFormation/latest/TemplateReference/aws-properties-iam-user-loginprofile.html) 属性类型的 `Password` 属性值，因此 CloudFormation 不能将其包含在偏差检测结果中。
  + 数组中的对象实际上可能是服务默认值，而不是在手动添加的偏差。
+ 如果您遇到任何误报，请使用 CloudFormation 控制台中的反馈链接将您的评论发送给我们，或通过 [Amazon Web Services re:Post](https://repost.aws/) 与我们联系。
+ 某些属性可能有相等但不完全相同的输入值。为避免误报，应确保预期配置与实际配置相匹配。
  + 例如，资源属性的预期配置可能为 1024MB，而同一资源属性的实际配置可能为 1GB。1024MB 和 1GB 相等但不完全相同。

    当在此资源属性上运行偏差检测时，它将发出偏差结果信号。

    为避免误报，请将资源属性的预期配置更改为 1024MB，然后运行偏差检测。