mcpField
T
terraform

terraform

github.com/iliaal云与 DevOps45148 次安装5 天前更新
代码仓库

关于 terraform

terraform 是面向 Terraform 与 OpenTofu 基础设施代码任务的技能,涵盖配置组织、状态安全、资源重构和测试。它提供从变更规划到验证的操作规范。

主要功能

  1. 01组织配置文件与模块
  2. 02保护状态与凭据
  3. 03安全重构资源地址
  4. 04规划资源迭代与版本约束
  5. 05验证配置并运行测试

适用场景

  1. 01整理基础设施模块
  2. 02审查资源变更计划
  3. 03排查状态漂移或锁定
  4. 04测试配置而不创建真实基础设施

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/iliaal/ai-skills --skill terraform

安装后在 Claude Code 中输入/terraform确认已加载。

附带文件references/native-test-patterns.mdSPEC.md

详细介绍

Terraform 和 OpenTofu

工作规则

  • 重构时保留状态和资源地址;检查计划,确认没有意外替换。
  • 将效果已验证的本地测试或模拟测试,与访问真实服务或创建计费基础设施的测试分开。计划模式仍可能读取真实数据源;模拟应用可以在不创建基础设施的情况下运行。

文件组织与命名

文件用途
terraform.tfTerraform 和提供商版本要求
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 中经过验证的选择方案。

任务相关参考资料

在实现或审查相应行为前,请阅读相关参考资料:

评论

支持 Markdown