3. Terraform Plan:plan命令原理、plan输出解读、plan与真实状态对比

terraform plan 是 Terraform 工作流中最重要的“预检”步骤。它通过对比当前配置(.tf 文件)与上一次记录的状态(terraform.tfstate),生成一份详细的执行计划。这份计划不会对基础设施做任何实际变更,而是让运维人员提前看到“将要创建、更新或删除哪些资源”。在漂移检测场景中,plan 是发现漂移的第一道防线。

3.1 plan 命令执行原理

terraform plan 的执行流程分为三个阶段:

  1. 刷新(Refresh):Terraform 调用各 Provider 的 API,查询当前真实基础设施的状态,并与本地 state 文件进行比对。这一步默认自动执行,可通过 -refresh=false 跳过。
  2. 计算差异(Diff):将刷新后的真实状态与配置代码(.tf 文件)中的期望状态进行逐字段对比,生成变更集合。
  3. 生成计划(Plan):将变更集合整理为可读的计划输出,包含资源地址、操作类型(create/update/delete)、属性变化详情。
关键点:plan 本身不修改任何资源,也不修改 state 文件。它只是一个“预演”结果。如果 plan 检测到真实状态与 state 不一致(即漂移),会在输出中以 ~ 或 -/+ 标记。
Terraform Plan 执行流程 terraform plan 执行流程 配置代码 (.tf) State 文件 真实基础设施 差异计算引擎 执行计划输出

3.2 plan 输出解读

一个典型的 terraform plan 输出包含以下关键部分:

输出区域 说明 示例
资源地址 被变更资源的完整模块路径 aws_instance.web[0]
操作符号 + 创建,~ 更新,- 删除,-/+ 销毁重建 ~ 表示属性级更新
属性变更 显示旧值和新值的对比 instance_type: "t2.micro" → "t3.medium"
摘要统计 末尾汇总:Plan: X to add, Y to change, Z to destroy Plan: 1 to add, 2 to change, 0 to destroy
实战技巧:使用 terraform plan -out=plan.tfplan 将计划保存为二进制文件,后续可用 terraform apply plan.tfplan 精确执行该计划,避免因代码或状态变化导致计划不一致。

3.2.1 操作符号详解

  • + (create):资源在配置中存在,但 state 和真实基础设施中都不存在,需要新建。
  • ~ (update in-place):资源存在,但某些属性发生变化,且 Terraform 支持原地更新(如修改标签、调整实例类型)。
  • - (destroy):资源在 state 中存在,但配置中已被移除,需要删除。
  • -/+ (destroy and recreate):资源需要销毁后重建,通常因为修改了不可变属性(如 AWS 安全组规则、磁盘大小)。

3.3 plan 与真实状态对比:漂移检测

漂移(Drift)是指真实基础设施的状态与 Terraform state 文件记录的状态不一致。plan 命令通过刷新步骤自动检测漂移。以下是一个典型的漂移检测场景:

# 假设 state 中记录 aws_instance.web 的 instance_type 为 t2.micro
# 但有人在 AWS 控制台手动修改为 t3.medium

$ terraform plan

aws_instance.web: Refreshing state... [id=i-0abcd1234efgh5678]

Terraform will perform the following actions:

  # aws_instance.web will be updated in-place
  ~ resource "aws_instance" "web" {
        id               = "i-0abcd1234efgh5678"
      ~ instance_type    = "t3.medium" -> "t2.micro"
        tags             = {
            "Name" = "web-server"
        }
        # (10 unchanged attributes hidden)
    }

Plan: 0 to add, 1 to change, 0 to destroy.

上述输出中,~ instance_type = "t3.medium" → "t2.micro" 明确指示:真实基础设施当前是 t3.medium(漂移后的值),而配置期望是 t2.micro。Terraform 计划通过一次原地更新将实例类型改回 t2.micro。

注意:plan 只能检测到 Terraform 管理的资源属性。如果漂移发生在 Terraform 未管理的属性上(如通过其他工具添加的标签),plan 不会报告。此外,某些资源属性(如 AWS 自动生成的 ARN)即使发生漂移,Terraform 也可能忽略。
Plan 与真实状态对比:漂移检测 Plan 与真实状态对比:漂移检测 State 记录 instance_type = "t2.micro" ami = "ami-123" 真实基础设施 instance_type = "t3.medium" ami = "ami-123" Plan 检测结果 ~ instance_type "t3.medium" → "t2.micro" 漂移检测逻辑 State 与真实基础设施不一致 → Plan 标记为 ~ 更新 Plan 会生成将真实状态“拉回”配置期望的变更操作

3.4 常用 plan 参数与最佳实践

参数 用途 漂移检测场景
-refresh=false 跳过刷新步骤,仅对比配置与 state 不推荐用于漂移检测,会遗漏真实状态变化
-target=resource 仅对指定资源生成计划 缩小漂移排查范围,快速验证特定资源
-var-file 指定变量文件 确保变量值与预期一致,避免因变量错误导致误报漂移
-out=plan.tfplan 保存计划为二进制文件 用于审计或后续精确执行,防止计划被覆盖
漂移检测最佳实践:在 CI/CD 流水线中,每次部署前自动执行 terraform plan -detailed-exitcode。该命令返回码含义:0=无变更,1=错误,2=有变更。结合返回码 2 可以自动触发漂移告警,无需人工逐行阅读输出。