关于 terraform
terraform 是面向 Terraform 与 OpenTofu 基础设施代码任务的技能,涵盖配置组织、状态安全、资源重构和测试。它提供从变更规划到验证的操作规范。
主要功能
- 01组织配置文件与模块
- 02保护状态与凭据
- 03安全重构资源地址
- 04规划资源迭代与版本约束
- 05验证配置并运行测试
适用场景
- 01整理基础设施模块
- 02审查资源变更计划
- 03排查状态漂移或锁定
- 04测试配置而不创建真实基础设施
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ iliaal/ ai-skills --skill terraform安装后在 Claude Code 中输入/terraform确认已加载。
附带文件references/native-test-patterns.mdSPEC.md
详细介绍
Terraform 和 OpenTofu
工作规则
- 重构时保留状态和资源地址;检查计划,确认没有意外替换。
- 将效果已验证的本地测试或模拟测试,与访问真实服务或创建计费基础设施的测试分开。计划模式仍可能读取真实数据源;模拟应用可以在不创建基础设施的情况下运行。
文件组织与命名
| 文件 | 用途 |
|---|---|
terraform.tf | Terraform 和提供商版本要求 |
providers.tf | 提供商配置 |
main.tf | 主要资源和数据源 |
variables.tf | 输入变量(按字母顺序排列) |
outputs.tf | 输出值(按字母顺序排列) |
locals.tf | 局部值 |
- 使用小写字母和下划线:
web_api,不要用webAPI或web-api - 使用描述性名词,不包含资源类型:
aws_instance.web_api,不要用aws_instance.web_api_instance - 使用单数,不要用复数
- 对单例资源(每个模块中该类型仅有一个)使用
this - 使用体现上下文的变量前缀:
vpc_cidr_block,不要用cidr
块顺序
资源: count/for_each(后空一行)→ 参数 → 嵌套块 → tags → depends_on → lifecycle(最后)
变量: description → type → default → validation → nullable
每个变量都需要 type 和 description。每个输出都需要 description。将机密标记为 sensitive = true。
模块结构
| 类型 | 范围 | 示例 |
|---|---|---|
| 资源模块 | 单个逻辑组 | VPC + 子网、SG + 规则 |
| 基础设施模块 | 一组资源模块 | 单个区域的网络 + 计算 |
| 组合 | 完整基础设施 | 跨区域/账户 |
module-name/
├── main.tf, variables.tf, outputs.tf, versions.tf
├── examples/
│ ├── minimal/
│ └── complete/
└── tests/
└── defaults.tftest.hcl
保持模块精简(单一职责)。examples/ 既可用作文档,也可用作集成测试夹具。所有已发布模块都采用语义化版本控制。
count 与 for_each
| 场景 | 使用方式 |
|---|---|
| 布尔开关(创建或跳过) | count = condition ? 1 : 0 |
| 可能重新排序的命名/键控项 | for_each = toset(list) 或 map |
| 数量固定且完全相同的副本 | count = N |
默认使用 for_each:从 count 列表中移除中间项会导致之后的所有资源重新创建。仅在布尔条件或确实完全相同的副本场景下使用 count。
版本固定
| 组件 | 策略 | 示例 |
|---|---|---|
| Terraform | 固定次版本 | required_version = "~> 1.9.0" |
| 提供商 | 固定主版本 | version = "~> 5.0" |
| 模块(生产环境) | 固定精确版本 | version = "5.1.2" |
| 模块(开发环境) | 允许补丁版本更新 | version = "~> 5.1.0" |
重要的现代功能:moved 块(1.1+)、带默认值的 optional()(1.3+)、原生测试(1.6+)、模拟提供商(1.7+)、跨变量验证(1.9+)、只写参数(1.11+)。
Stacks(HCP;请确认当前发布状态):将多个配置编排为一个部署单元。评估其是否适用于多环境模式。
状态与安全
- 使用带锁的远程后端:S3(设置
use_lockfile = true,版本 1.10+)、Azure Blob、GCS 或 Terraform Cloud。共享基础设施切勿使用本地状态。基于 DynamoDB 的 S3 锁定(dynamodb_table)已弃用,计划移除;建议使用use_lockfile。迁移现有表期间可以同时设置两者。 - 仅适用于 OpenTofu:
terraform { encryption { key_provider "pbkdf2" "k" {...} method "aes_gcm" "m" { keys = key_provider.pbkdf2.k } state { method = method.aes_gcm.m } plan { method = method.aes_gcm.m } } }可在客户端加密状态和计划文件(也可通过TF_ENCRYPTION实现)。推出时添加fallback { method = method.unencrypted.x },以确保仍能加载现有明文状态;重命名密钥提供程序或方法时,切勿省略fallback块。OpenTofu 还允许在backend {}参数以及模块的source/version中使用var.*/local.*(在init时解析;不能引用状态或提供程序函数);同样的 HCL 在 Terraform 中会报硬错误(“A backend block cannot refer to named values”)。 - 对静态存储的状态进行加密。切勿提交
.tfstate、.terraform/或*.tfplan。始终提交.terraform.lock.hcl。 - 在提供程序上设置
default_tags,以确保资源标签一致。 - 对所有存储进行静态加密。默认使用私有网络;公共访问需明确启用。
- 安全组遵循最小权限原则。没有明确理由时,不得允许
0.0.0.0/0入站。 - 切勿将凭据硬编码;使用 assume_role、OIDC 或密钥管理服务。
- 提交前:先自动格式化(
terraform fmt -recursive会改写文件),再验证(terraform validate && tflint && trivy config .) - 重构资源名称或模块时,使用包含
from和to地址的moved块,避免先销毁再重建。保留历史迁移记录,供下游升级使用;仅在所有受影响的状态都已迁移后,或作为明确标注为不兼容的模块版本发布时,才移除这些记录。 lifecycle { ignore_changes = [attr] }仅抑制更新;配置更改后的首次计划中,它会用先前的状态值替换配置值,且不存在“首次应用”例外。评审者容易忽略两个后果:(1)对于已配置的资源,配置中的字面值永远不会写入;由于ignore_changes会在评估替换之前清除差异,ForceNew也永远不会触发。因此,将已提交的值改为占位符,只会清除仓库中的值,而远程值仍然有效;(2)创建时不适用ignore_changes,因此之后任何-replace、污点标记、state rm后重新添加或手动删除操作,都会用占位符重新写入原先通过其他途径设置的值。应仅在配置中保留容器资源,并完全通过其他途径配置该值;或者在操作手册中说明每种替换路径的恢复步骤。
故障排除
- 状态锁卡住:运行
terraform force-unlock <ID>,但仅在确认没有其他操作正在运行后执行 - 资源漂移:运行
terraform plan -refresh-only检测,运行terraform apply -refresh-only接受 - 替换已标记为污点的资源:运行
terraform apply -replace=ADDR(不要使用已弃用的terraform taint) - 导入现有资源:使用
import块(1.5+)进行声明式导入,或运行terraform import ADDR ID
依赖管理
使用 locals 和 try() 控制删除顺序,无需显式指定 depends_on:
locals {
vpc_id = try(aws_vpc_ipv4_cidr_block_association.this[0].vpc_id, aws_vpc.this.id, "")
}
这样会强制 Terraform 先销毁子网,再销毁 CIDR 关联,从而避免删除错误。
- 使用
cidrsubnet(var.vpc_cidr, 8, count.index)计算子网 CIDR;切勿硬编码子网 - 多区域:使用
provider "aws" { alias = "eu_west_1" },并在模块块中设置providers = { aws = aws.eu_west_1 }
验证
在宣布完成前运行:
terraform fmt -check && terraform validate && tflint && trivy config .
所有命令都必须通过,且无任何错误。选择测试文件前,检查提供程序、数据源、配置器和外部命令。完成检查中应包含安全的计划测试和完全模拟的应用测试。真实服务或基础设施测试应受任务授权和成本边界约束。传入相对于根目录的测试文件名,例如 terraform test -filter=tests/vpc_unit_test.tftest.hcl,并验证目标文件至少成功运行过一次;仅凭退出代码,可能会误将未选择任何测试的未知筛选器视为通过。请使用 native-test-patterns.md 中经过验证的选择方案。
任务相关参考资料
在实现或审查相应行为前,请阅读相关参考资料:
- 对于原生计划/应用测试、夹具排序或 CI 测试选择: native-test-patterns.md。