我在 Terraform 中犯的错误,免得你也犯
Source: Dev.to
我已经专业使用 Terraform 4 年了,同时这段时间里我也犯了不少 Terraform 错误。下面列出的是那些真正让我付出时间、金钱或失眠代价的错误,以及我从每一次错误中学到的经验。
错误 1:为所有内容使用一个巨大的状态文件
当我刚开始时,把所有内容放在同一个状态文件中感觉很优雅——唯一的真相来源,易于理解。
然而,单个模块中的一个错误导致整个状态文件在 apply 时无法使用。两位工程师尝试同时执行 apply,结果遇到了 state‑lock 冲突。状态文件体积膨胀至 50 MB,计划执行时间也开始飙升至 8 分钟。
我现在的做法
使用 每个服务每个环境一个状态文件。虽然会增加一些设置工作量,但操作安全性提升显著。
错误 2:将密钥存储在变量中
我知道,这显然很糟糕,但我还是这么做了。
我在一个新项目中进展很快,需要将数据库密码传递给应用程序配置,并且想着以后再修复。这个密码在 tfvars 文件中存放了 8 个月,而该文件在我注意到之前已经提交到 Git 里 3 个月。
我现在的做法
将密钥存储在 AWS Secrets Manager 或 Parameter Store 中。Terraform 读取密钥的 ARN,而不是密钥的实际值。
错误 3:将 Terraform 用于配置管理
Terraform 用于供应基础设施;它并非为配置管理而设计。
我编写了 Terraform 资源,通过 remote-exec 和 user_data 在 EC2 实例上安装软件包、写入配置文件并管理服务。它在服务器因手动更改而产生漂移之前运行正常。Terraform 认为配置是正确的,但服务器的实际状态并不一致。
我现在的做法
保持 严格分离:Terraform 负责供应;Ansible(或其他配置管理工具)负责配置。绝不让两者的职责重叠。
错误 4:忽视冲击半径
在项目的早期,我有一个根级别的模块同时管理 VPC、子网、安全组、RDS、ECS 集群以及应用服务。
应用服务配置中的一个拼写错误导致 Terraform 在所有资源之间评估依赖关系。计划中显示了我本不打算触碰的资源的更改。我慌了,运行 terraform apply -target,引入了更多漂移,随后花了 4 小时 修复它,导致 20 分钟 的不必要停机。
我现在的做法
为基础设施层创建 独立的模块,并在它们之间设定明确的接口。对应用配置的更改不会意外影响网络资源。
Mistake 5: Not Planning for Terraform State Migration
当你的状态结构不再适用时,需要使用 terraform state mv 命令在状态文件之间迁移资源——每个资源对应一次迁移。对于拥有 200 多个资源的情况,这将是一个大型项目;如果操作失误,可能导致资源孤立或产生重复。
What I do now
设计状态结构时要面向项目在 12 个月 后的状态,而不是仅仅考虑当前。提前采用更细粒度的状态要比以后再把单体状态拆分容易得多。
错误 6:手动工作区管理
我使用 Terraform 工作区来管理预发布(staging)和生产(production)环境,认为不同的工作区等同于不同的状态,从而对应不同的环境。
问题在于:没有任何机制阻止你在错误的工作区运行 terraform apply。我曾经在生产环境而不是预发布环境执行了破坏性更改,导致了短暂的停机,本可以避免。
我现在的做法
使用 为不同环境准备的独立目录。目录结构可以清晰地表明你正在操作哪个环境。
所有这些背后的模式
每一次我在 Terraform 上犯的错误,都源于追求短期优化。单一的状态文件比多个更容易设置;用户数据比设置 Ansible 更快;工作区比单独的目录开销更小。
短期的便利总是伴随着长期的代价。
Terraform 是一个用于管理基础设施的工具,其生命周期会超出任何单个工程师的参与时间。为此进行设计。
我正在构建 Step2Dev,让正确的 Terraform 实践成为默认,而非例外。更多请访问 。
哪个 Terraform 错误给你造成的损失最大?在评论中告诉我们。