一份声明的蓝图被应用到集群上。

基础设施即代码是变更日志,不是魔法

声明式基础设施,就是把「应该存在什么」写下来,让工具去算怎么到达。命令式脚本发出一串 API 调用,它并不知道已经存在什么;跑两次就会得到两份,或者在中途失败。声明式配置描述的是终态,差异由工具负责。 但价值并不在文件本身,而在文件产出的 diff,以及让 diff 成为可能的状态。状态是从配置地址到真实资源的映射,也是唯一知道「你拥有什么」的东西。基础设施即代码出问题的地方,几乎都落在这个映射上。 计划是 diff,apply 是变更 Terraform 先把真实资源读回状态(refresh),再与配置比较,把差异打印成执行计划:将要创建、修改或删除什么。执行前先审计划,才让「批准」成为真实的事,因为计划是关于 provider API 会做什么的精确陈述,而不是对意图的描述。 计划的可信度取决于 refresh 的可信度:如果某个资源读不回来,计划就会把「更新」误判成「创建」。把计划存成 plan 文件再交给 apply,可以保证执行的就是被审过的那一份,而不是重新算一遍的近似结果。 可重复运行是承诺的另一半。第一次 apply 之后,状态记下了两个资源及其属性,第二次 plan 什么都不打印。这份幂等性正是工作流可以重跑的原因,而它值得被测量,而不是被假定。 状态是映射,不是配置 状态记录每个地址拥有哪个真实资源。没有它,工具分不清「创建」和「接管」,而失败的样子不是一条费解的错误,而是被遗弃的基础设施。在资源照常运行的情况下删掉状态文件,下一次 plan 会提议把两个资源都创建一遍;apply 随即报 already exists,而那些真实资源已经无人管理——还在跑、还在计费、没有任何东西追踪它们。恢复方式是对每个地址手工执行 terraform import。 所以状态必须放在带版本控制的远程后端里,也必须加锁。两个 apply 都读到 serial 3,就会都写 serial 4,其中一个创建的资源会从状态里彻底消失;持有锁之后,第二个 apply 会等待、重读,再写 serial 5。锁让「读—决定—写」变安全,而不是让最后写的人赢。远程后端还让状态可被审计:谁在什么时候改了哪个地址,都留在版本历史里。 ...

十一月 13, 2026 · 1 分钟 · XB Field Notes