Hang Zhengyang

Terraform 基础路线(整体机制详解)

本文不是命令手册,而是解释 Terraform 作为声明式 IaC 引擎如何工作,并结合当前 terraform/ 目录给出可观测映射。

0. Terraform 的本质

Terraform 可以看作一个“状态驱动的声明式收敛器”:

  • 你写的是目标状态(desired state),不是步骤脚本。
  • Terraform 读取当前状态(state + provider refresh)。
  • 计算差异(plan)。
  • 调用 provider API 执行变更(apply)。
  • 更新状态快照(state)。

因此,Terraform 不等价于“脚本自动化”,更接近“资源图执行器 + 状态机”。

1. 核心对象模型(高密度)

  • Configuration (HCL):期望状态描述。
  • Provider:连接外部系统的驱动适配层(本目录为 hashicorp/local)。
  • Resource:受管对象声明(本目录为 local_file.learning_record)。
  • Data Source:只读查询对象(本目录未使用)。
  • Module:配置复用边界(目录级边界)。
  • Variable / Local / Output:输入、派生、输出接口。
  • State:Terraform 对受管对象当前态的权威记录。
  • Plan File (tfplan):一次冻结后的执行提案。

2. 文件层职责(对应当前目录)

  • main.tf:provider 约束 + 核心资源声明。
  • variables.tf:输入合同(project/environment/owner/output_file)。
  • locals.tf:重复表达式收敛(common_tags)。
  • outputs.tf:执行后对外暴露关键结果(生成文件路径)。
  • dev.tfvars / stage.tfvars:环境化参数覆盖层。
  • README.md:操作入口与最小执行路径。

要点:文件名只是组织方式,Terraform 实际把同目录 .tf 合并成一个 root module 解析。

3. 执行生命周期(从 init 到 destroy)

3.1 terraform init

  • 解析 required_providers 约束。
  • 下载 provider 插件并生成/校验 lock 信息。
  • 建立本地工作目录(.terraform/)。

这是“运行时装配阶段”,不是资源变更阶段。

3.2 terraform validate

  • 做静态语法与引用校验。
  • 不会创建资源,不依赖目标系统状态。

这是“编译期检查阶段”。

3.3 terraform plan

  • 先 refresh:向 provider 查询现实对象状态。
  • 结合 state + 配置计算动作图(create/update/delete/no-op)。
  • 可输出 tfplan 冻结执行意图,避免“plan/apply 口径漂移”。

这是“决策阶段”。

3.4 terraform apply

  • 按依赖图(DAG)执行动作。
  • 支持并行执行互不依赖节点。
  • 执行后更新 state。

这是“变更落地阶段”。

3.5 terraform destroy

  • 反向计算并执行删除动作。
  • 本质仍是一次 plan+apply,只是目标状态为“无资源”。

这是“回收阶段”。

4. 依赖图(DAG)是如何形成的

Terraform 依赖不是按文件顺序,而是按引用关系推导:

  • local_file.learning_record 依赖 var.* 与 local.common_tags。
  • 若 A 引用 B 的属性,A 依赖 B。
  • 显式 depends_on 可补充隐式图(本目录未使用)。

这保证了执行顺序由“语义依赖”决定,而非“文本顺序”决定。

5. 状态(state)与漂移(drift)

5.1 state 的作用

  • 记录资源实例 ID 与属性映射。
  • 支撑 plan 的差异计算。
  • 避免每次都从零推断资源身份。

5.2 drift 产生方式

  • 配置变更(HCL/tfvars 更新)。
  • 现实世界变更(手工改资源)。
  • 非幂等字段(例如本目录 timestamp())导致每次评估值变化。

本目录里的 generated_at = timestamp() 是一个刻意的“漂移演示器”:
它帮助理解为什么声明里存在时间函数会导致持续 update。

6. 变量注入优先级(实践向)

常见来源(高到低):

  1. 命令行 -var / -var-file
  2. 环境变量 TF_VAR_*
  3. terraform.tfvars / *.auto.tfvars
  4. variable 的 default

这决定了“谁覆盖谁”,也是环境拆分与 secret 注入设计的基础。

7. 幂等性与可审计性

  • 幂等性:同一配置重复 apply,应收敛到稳定态。
  • 可审计性:plan -out tfplan + apply tfplan 可把“评审内容”与“执行内容”绑定。
  • 可追溯性:state + VCS 记录一起构成变更历史。

工程上,Terraform 的价值不只是“能创建资源”,而是“可重复、可解释、可审计地创建资源”。

8. 常见认知误区

  • “Terraform 是脚本工具”
    -> 不准确。它是状态驱动引擎。

  • “文件名决定执行顺序”
    -> 错。依赖图决定顺序。

  • “plan 只是预览,不重要”
    -> 错。plan 是变更契约,尤其在团队协作和生产发布中。

  • “state 可有可无”
    -> 错。没有 state,Terraform 很难稳定识别资源身份与差异。

9. 当前 terraform/ 目录为什么有价值

虽然这里只管理一个本地文件资源,但它完整暴露 Terraform 的关键机制:

  • provider 生命周期(init)
  • 配置静态校验(validate)
  • 差异推导(plan)
  • 图执行与状态更新(apply)
  • 回收闭环(destroy)
  • 漂移感知(timestamp 演示)

因此它是复杂 IaC(如 terraform-k8s)之前的认知基线,而不是“玩具样例”。