
一、背景
在云资源管理领域,基础设施即代码(IaC)凭借其可重复性、可审计性和高效性,已成为主流的管理方式。通过 IaC 工具(如 Terraform),我们可以将云资源的配置以代码形式定义,实现资源的自动化部署与管控。
然而,在实际操作中,常常会出现之前利用 IaC 管控的云资源发生部分属性变更的情况,且其资源 ID 未发生变更。例如,一个 EC2 实例的名称、规格等属性被手动修改,这就导致了资源的实际状态与 IaC 代码定义的期望状态出现偏差,即属性偏移。这种偏移可能会破坏 IaC 管理的一致性和可靠性,给资源管理带来一系列问题,如配置混乱、部署故障、审计困难等,因此需要一套完善的方案来修正这种偏移。
二、解决方案
2.1 非 ForceNew 属性
在 IaC 管控体系中,当怀疑资源发生属性偏移时,首要步骤是执行terraform plan命令。该命令会对比 IaC 代码中定义的资源属性与实际云资源的属性,找出存在差异的部分,其中黄颜色标识的即为引发资源变更的属性。
举个具体的例子,假设代码中定义的 instance_name 为 "tf-vault-server-dev",但由于人为的手工操作,云平台页面上该实例的名称被修改为 "tf-vault-server-dev-1"。此时运行tf plan,系统会检测到这一差异,并提示将实例的名称修正为与代码一致的 "tf-vault-server-dev"。
实际实例名称

代码中实例名称

基于上述检测结果,我们有两种处理方式:
如果经过评估,认为手动更新的内容更符合当前业务需求,需要保持手动更新的状态,那么就需要修改 IaC 代码,将代码中的 "vault-server-dev" 修改为 "vault-server-dev-1",使代码与手动修改后的实际属性保持一致。修改完成后,再次执行terraform plan,此时应该看不到属性更新的提示。但需要注意的是,此时 Terraform 的 state 文件中记录的名称仍然是历史的 "vault-server-dev",为了保证 state 文件与实际资源状态的一致性,需要手动执行terraform refresh命令来更新 state 文件。
如果确定要保持资源状态与 IaC 代码的一致性,以代码定义为准,那么直接执行terraform apply命令即可。该命令会将代码中定义的属性应用到云资源上,从而使云资源的实际状态、IaC 代码以及 state 文件三者保持一致。
2.2 ForceNew 属性
ForceNew 属性是一类特殊的属性,当这类属性发生变更时,会触发资源的重新创建。例如,cam_role_name 属性,当实例的该属性发生变更后,Terraform 会提示 "forces replacement",意味着需要重新创建该实例。此外,与该实例相关联的其他附件资源,如 null_resource 资源,由于实例的重建,也会重新执行相应的脚本操作。

对于 ForceNew 属性引发的属性偏移,处理思路与非 ForceNew 属性类似,但需要特别关注资源重建可能带来的影响。如果希望保留手动修改的属性值,那么需要修改 IaC 代码,使其与手动修改后的属性一致,然后执行terraform refresh命令刷新 state 文件,确保 state 文件能够准确反映资源的当前状态。如果决定以 IaC 代码的定义为准,那么直接执行terraform apply命令,此时系统会按照代码重新创建资源,以保证资源状态与代码的一致性。
三、注意事项
3.1 不同属性的变更影响及处理考量
- ForceNew 属性:当资源的 ForceNew 属性在业务操作中发生变更后,在 Terraform 中会触发资源的重新创建,这必然会导致资源 ID 发生变化。资源的重建可能会对业务造成较大影响,如服务中断、数据迁移等。因此,在处理 ForceNew 属性的变更时,需要充分评估其对业务的影响范围和程度,制定详细的业务中断预案和数据迁移方案,选择合适的业务低峰期进行操作,以将影响降到最低。
- 非 ForceNew 但会引起资源重启的属性:例如 instance_type(实例规格),当业务将实例的规格修改后,重新执行 IaC 代码时,会导致实例重启。实例重启可能会造成服务的短暂中断,因此针对这类属性的变化,需要考虑真实业务场景中的实际切换窗口期,确保在不影响核心业务运行的时间段内进行操作。
- 非 ForceNew 且不会引起资源重启的属性:像标签、名称等属性,对其进行修改时,实例无需重启,可以直接进行变更,影响相对可控。这类属性的修改通常不需要等到特定的业务切换窗口期,可在合适的时间及时处理,以保证资源状态与代码的一致性。
3.2 部分资源属性变更无法检测的问题
在实际操作中,会出现部分资源属性变更后,Terraform 无法检测到的情况。例如,在测试中发现,当在云平台页面将实例的镜像由 centos 修改为 tencentos 后,执行terraform plan命令时,系统无法检测到这一变更。经分析,判断这可能是腾讯云 provider 存在的 bug 导致的。
一般来说,ForceNew 资源属性的变更往往涉及到资源在物理存储上的类型变更,或者涉及到系统级别的一些操作配置等,这类变更通常会被 Terraform 检测到。而对于一些非核心的、provider 未完全适配的属性变更,可能会出现检测不到的情况。这就要求我们在日常管理中,不仅要依赖工具的检测,还需要定期进行人工核查,确保资源属性的变更都能被及时发现和处理。
四、总结
当 IaC 管控的云资源出现部署属性与 IaC 代码发生偏移的情况时,我们需要根据实际业务需求和资源属性的特点,确定最终以哪一方的状态为准。在这个过程中,尤其需要注意 ForceNew 属性,因其变更会导致云资源重建,可能对业务造成较大影响,所以必须充分考虑对业务的影响范围和程度,制定相应的修复措施和选择合适的操作时间窗口。
从长远来看,为了保证 IaC 管理的有效性和可靠性,我们应尽可能以 IaC 代码作为统一的变更操作唯一入口,减少或避免对 IaC 管控的资源进行手动操作。这样可以最大限度地保证资源配置的一致性、可追溯性和可重复性,降低因人为操作导致的属性偏移风险,提高云资源管理的效率和质量。同时,对于工具无法检测到的属性变更问题,要加强人工核查和与云服务提供商的沟通,推动问题的解决,不断完善 IaC 管理体系。