2. 本地状态管理的局限与风险
Terraform 默认使用本地后端(local backend),把状态文件以明文 JSON 形式保存在执行目录下的 terraform.tfstate 中。理解它的运作机制,是判断何时必须迁移到远程后端的前提。
默认本地后端的运作机制
当配置中没有 backend 块时,Terraform 隐式采用本地后端。其核心行为可以概括为三点:
- 状态落盘位置:状态写入当前工作目录的
terraform.tfstate;每次terraform apply成功后覆盖写入,并在覆盖前生成terraform.tfstate.backup作为上一版本备份。 - 状态锁:本地后端使用文件锁(在支持的系统上通过
.terraform.tfstate.lock.info文件实现),只能防止同一台机器上的并发操作,无法跨主机互斥。 - 资源映射:状态中保存了每个资源实例的地址(如
aws_instance.web)与真实资源 ID 的映射、属性快照、依赖关系以及serial序列号。Terraform 靠这份映射决定“创建、更新还是删除”。
这意味着状态文件不是缓存,而是 Terraform 的“唯一事实来源”。一旦丢失或与真实基础设施不一致,Terraform 就会失去对已有资源的追踪能力。
状态文件丢失与损坏的典型场景
本地状态的风险首先来自它的物理形态——一个普通文件。常见事故包括:
- 误删或目录清理:执行
rm -rf、清理构建产物或切换分支时把terraform.tfstate一并删除。此时再次terraform apply,Terraform 认为所有资源都不存在,会尝试重新创建,导致重复资源或名称冲突。 - 未提交到版本控制:状态文件通常被
.gitignore排除,团队成员各自持有不同副本,无法共享。 - 写入中断导致损坏:apply 过程中进程被 kill、磁盘写满或机器断电,可能留下不完整的 JSON。执行
terraform plan时会报类似Error loading state: unexpected end of JSON input的解析错误。 - 手工编辑出错:有人直接修改 JSON 修正资源 ID,破坏了
serial与lineage的一致性,后续操作会提示状态版本冲突。
terraform apply。优先尝试用 terraform.tfstate.backup 恢复,或对已存在资源执行 terraform import 重新纳管,避免误删线上资源。
敏感信息泄露风险
状态文件是明文的,且会记录资源的全部属性,而不仅是配置中显式写出的字段。典型泄露点包括:
- 数据库初始密码、
random_password生成结果、API Key 等以明文出现在attributes中; - 云厂商返回的访问密钥、连接串、证书私钥;
- 被标记为
sensitive = true的变量,其值在 CLI 输出中被隐藏,但在状态文件中依然明文保存。
因此,把 terraform.tfstate 提交到 Git 仓库、放进共享网盘或随构建产物打包,都等同于泄露凭据。本地后端没有任何加密与访问控制能力,这是它最本质的短板。
团队协作冲突案例
假设两名工程师 A 和 B 各自在本地维护同一套环境的配置:
# 时间线(示例场景)
10:00 A 执行 apply,本地 state serial = 12,新增一台 ec2
10:05 B 基于 serial = 11 的旧 state 执行 apply,新增一个安全组
10:06 B 的 apply 成功,本地 state serial = 12(覆盖式写入)
10:10 A 再次 plan,发现安全组“不存在”,计划将其删除
由于本地后端没有共享存储和跨主机锁,B 的操作完全覆盖了 A 的状态,A 后续的 plan 会把 B 创建的资源视为“计划外资源”并尝试删除。这类冲突在多人协作中几乎必然发生,且排查成本很高。
从本地状态迁移的触发条件
当出现以下任一信号时,就应当考虑迁移到远程后端(如 S3 + DynamoDB、Terraform Cloud、azurerm 等):
| 触发条件 | 说明 |
|---|---|
| 多人协作 | 超过一人需要对同一环境执行 plan/apply |
| 状态含敏感数据 | 需要加密存储与访问审计 |
| 需要状态锁 | 防止并发 apply 造成状态覆盖 |
| CI/CD 自动化 | 流水线需要稳定、可共享的状态来源 |
| 状态文件体积增大 | 本地读写与备份变得不可靠 |
迁移的基本动作是:在配置中加入 backend 块,执行 terraform init,Terraform 会提示是否将现有本地状态复制到远程。确认后本地状态被上传,后续操作即以远程为准。迁移前务必先备份 terraform.tfstate,并确认远程存储已开启版本控制与加密。
总结来看,本地后端适合单人、短周期、无敏感数据的实验场景;一旦进入团队协作或生产环境,它的丢失、泄露与冲突风险就会迅速放大。识别上述触发条件并及时迁移,是状态治理的第一步。