3. Terraform Plan:plan命令原理、plan输出解读、plan与真实状态对比
terraform plan 是 Terraform 工作流中最重要的“预检”步骤。它通过对比当前配置(.tf 文件)与上一次记录的状态(terraform.tfstate),生成一份详细的执行计划。这份计划不会对基础设施做任何实际变更,而是让运维人员提前看到“将要创建、更新或删除哪些资源”。在漂移检测场景中,plan 是发现漂移的第一道防线。
3.1 plan 命令执行原理
terraform plan 的执行流程分为三个阶段:
- 刷新(Refresh):Terraform 调用各 Provider 的 API,查询当前真实基础设施的状态,并与本地 state 文件进行比对。这一步默认自动执行,可通过
-refresh=false跳过。 - 计算差异(Diff):将刷新后的真实状态与配置代码(.tf 文件)中的期望状态进行逐字段对比,生成变更集合。
- 生成计划(Plan):将变更集合整理为可读的计划输出,包含资源地址、操作类型(create/update/delete)、属性变化详情。
关键点:plan 本身不修改任何资源,也不修改 state 文件。它只是一个“预演”结果。如果 plan 检测到真实状态与 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 也可能忽略。
3.4 常用 plan 参数与最佳实践
| 参数 | 用途 | 漂移检测场景 |
|---|---|---|
-refresh=false |
跳过刷新步骤,仅对比配置与 state | 不推荐用于漂移检测,会遗漏真实状态变化 |
-target=resource |
仅对指定资源生成计划 | 缩小漂移排查范围,快速验证特定资源 |
-var-file |
指定变量文件 | 确保变量值与预期一致,避免因变量错误导致误报漂移 |
-out=plan.tfplan |
保存计划为二进制文件 | 用于审计或后续精确执行,防止计划被覆盖 |
漂移检测最佳实践:在 CI/CD 流水线中,每次部署前自动执行
terraform plan -detailed-exitcode。该命令返回码含义:0=无变更,1=错误,2=有变更。结合返回码 2 可以自动触发漂移告警,无需人工逐行阅读输出。