Terraform 命令速查表 - Terraform 基础设施即代码常用命令大全

用 Terraform 的节奏是固定的:plan 看差异、apply 落库、destroy 谨慎使用。理解这套流程的关键在于状态文件——它记录着资源与现实世界的对应关系,是整套工具的事实来源。状态丢了会导致下次 plan 想重建所有资源,状态与现实不一致则会引发误删,所以团队协作必须配远程后端并开启锁机制。本表按核心工作流、状态管理、变量与输出、模块、远程后端、高级功能、调试与排障分组。实际写代码时还有几条铁律:敏感值走变量或敏感标记而不是硬编码,state 文件含凭据不可入库,terraform fmt 让 diff 更干净。排障时 state list 与 state show 是第一步,refresh-only 则是修正状态偏差的最小手段。

系统与运维·共 53 条命令·最后更新 2026-07-21
terraformiacinfrastructuredevops云原生

典型使用场景

面向负责云上基础设施即代码的工程师。日常节奏是 `init → plan → apply` 三步,但真正吃掉时间的是另外几件事,本表重点覆盖它们:状态管理——`state list`/`show`/`mv`/`rm`/`import` 是排查「资源漂移」和「配置与实际不符」的主力工具,`taint`/`untaint` 控制强制重建;远程后端——S3 存状态、DynamoDB 做状态锁,是团队协作与并发 apply 的前提;`count` 与 `for_each` 两种批量创建方式的取舍;以及 `terraform console`、`TF_LOG` 调试表达式和输出日志。`workspace` 则用来隔离 staging 与 prod 的状态。

核心工作流 Core Workflow 7

terraform init
初始化工作目录,下载 Provider 和模块
terraform plan
预览变更,显示将创建/修改/销毁的资源
terraform apply
执行变更,应用基础设施修改
terraform destroy
销毁所有由配置管理的基础设施
terraform fmt
格式化 .tf 文件为标准格式
terraform validate
验证配置文件语法和内部一致性
terraform apply -auto-approve
自动批准执行(CI/CD 使用)

状态管理 State Management 9

terraform state list
列出状态文件中所有资源
terraform state show <resource>
查看指定资源的详细状态
terraform state mv <src> <dst>
移动资源在状态中的地址
terraform state rm <resource>
从状态中移除资源(不销毁实际资源)
terraform state pull
拉取远程状态到本地 stdout
terraform state push
推送本地状态到远程后端
terraform import <address> <id>
将已有资源导入 Terraform 管理
terraform taint <resource>
标记资源为"损坏",下次 apply 会重建
terraform untaint <resource>
取消资源的"损坏"标记

变量与输出 Variables & Outputs 8

variable "region" {\n type = string\n default = "us-east-1"\n}
定义变量(类型、默认值)
var.region
引用已定义的变量
TF_VAR_region=us-west-2
通过环境变量设置变量
terraform plan -var="region=us-west-2"
通过命令行参数设置变量
output "ip" {\n value = aws_instance.web.public_ip\n}
定义输出值
terraform output
查看所有输出值
terraform output -json
以 JSON 格式查看输出值
locals {\n name = "${var.prefix}-web"\n}
本地局部变量,简化表达式

模块使用 Modules 6

module "vpc" {\n source = "terraform-aws-modules/vpc/aws"\n version = "5.0.0"\n}
引用 Registry 模块,指定版本
module "vpc" {\n source = "./modules/vpc"\n}
引用本地模块(相对路径)
module "vpc" {\n source = "git::https://example.com/vpc.git"\n}
引用 Git 仓库中的模块
module.vpc.vpc_id
引用模块的输出值
terraform init -upgrade
升级模块至最新允许版本
terraform get
下载和更新模块

远程后端 Remote Backends 6

terraform {\n backend "s3" {\n bucket = "my-tf-state"\n key = "prod/terraform.tfstate"\n region = "us-east-1"\n }\n}
S3 后端存储状态文件
terraform {\n backend "s3" {\n dynamodb_table = "tf-lock"\n }\n}
DynamoDB 状态锁防并发
data "terraform_remote_state" "db" {\n backend = "s3"\n config = {\n bucket = "shared-state"\n key = "db/terraform.tfstate"\n }\n}
跨配置读取远程状态
data.terraform_remote_state.db.outputs.db_endpoint
引用远程状态的输出值
terraform init -reconfigure
重新配置后端(迁移状态)
terraform init -migrate-state
将状态文件迁移到新后端

高级功能 Advanced Features 9

terraform workspace new staging
创建新的工作空间
terraform workspace list
列出所有工作空间
terraform workspace select staging
切换到指定工作空间
resource "aws_instance" "web" {\n for_each = var.subnets\n}
for_each 通过集合批量创建资源
resource "aws_instance" "web" {\n count = var.instance_count\n}
count 通过计数批量创建资源
depends_on = [aws_s3_bucket.data]
显式依赖,确保创建顺序
lifecycle {\n create_before_destroy = true\n}
生命周期策略:先创建后销毁
lifecycle {\n prevent_destroy = true\n}
生命周期策略:防止意外销毁
lifecycle {\n ignore_changes = [tags]\n}
生命周期策略:忽略特定属性变更

调试与排障 Debugging 8

terraform console
交互式控制台,测试表达式
terraform graph | dot -Tpng > graph.png
生成资源依赖关系图
terraform show
查看当前状态的可读输出
terraform show -json
JSON 格式输出状态,方便 jq 处理
TF_LOG=DEBUG terraform apply
开启 DEBUG 级别日志输出
TF_LOG=TRACE terraform plan
TRACE 级别日志,最详细信息
TF_LOG_PATH=./tf.log terraform apply
将日志输出到指定文件
export TF_LOG=WARN
设置日志级别(TRACE/DEBUG/INFO/WARN/ERROR)

参数矩阵

参数作用示例
init初始化工作目录,下载 Provider 与模块terraform init
init -upgrade升级模块到当前允许的最新版本terraform init -upgrade
init -reconfigure重新配置后端(迁移状态)terraform init -reconfigure
init -migrate-state把状态文件迁移到新后端terraform init -migrate-state
plan -var="k=v"命令行传入变量值terraform plan -var="region=us-west-2"
apply -auto-approve跳过人工确认,CI 场景使用terraform apply -auto-approve
validate / fmt校验配置一致性 / 统一代码格式terraform fmt
state list / show列出状态中的资源 / 查看单个资源详情terraform state list
state mv <src> <dst>移动资源在状态中的地址terraform state mv aws_instance.a aws_instance.b
state rm <res>只从状态移除,不销毁真实资源terraform state rm aws_s3_bucket.old
import <addr> <id>把已有资源纳管进 Terraformterraform import aws_instance.web i-0123456789
taint / untaint <res>标记损坏下次重建 / 取消标记terraform taint aws_instance.web
output / output -json查看输出值 / 以 JSON 形式查看terraform output -json
workspace new/select/list创建 / 切换 / 列出工作空间terraform workspace select staging
count / for_each按计数或按集合批量创建资源count = var.instance_count
console交互式控制台,测试表达式terraform console
TF_LOG / TF_LOG_PATH设置日志级别(TRACE/DEBUG/INFO/WARN/ERROR)与输出路径TF_LOG_PATH=./tf.log terraform apply

易错点与避坑指南

现象apply 报 state 已被占用 / 锁超时,多人同时操作时互相阻塞

原因远程后端没有配置状态锁,或只用了 S3 而没加锁表。

处置在 backend "s3" 里补 `dynamodb_table = "tf-lock"`,然后 `terraform init -migrate-state`。

现象plan 里出现大量并非本次改动造成的差异

原因远端资源被人手工改过,本地 state 与实际出现漂移。

处置先用 `terraform state list` 和 `terraform state show <资源>` 确认,再 `terraform apply` 让状态与配置重新对齐;重大差异先 `terraform plan -out` 存档审阅。

现象换了资源名后 Terraform 想「销毁旧的 + 创建新的」,而旧资源不能删

原因资源的地址变了,Terraform 无法判断二者是同一个东西。

处置用 `terraform state mv <旧地址> <新地址>` 把资源在新地址下认领,不要靠复制配置硬改。

现象资源已经手工删掉,apply 却在报创建冲突

原因state 里仍记录着这个已不存在的资源。

处置用 `terraform state rm <资源>` 从状态中摘除(该命令不删真实资源),再重新 apply。

现象输出里暴露数据库密码、密钥等敏感信息

原因state 文件本身就包含资源的全部属性,包括敏感字段;把它提交到 Git 就会扩散。

处置把敏感值放进 variable 且不设 default,通过环境变量或 CI secret 注入;state 目录加入 .gitignore,并开启远程后端加密。

现象CI 里 apply 卡在等待确认,流水线超时

原因没有加自动批准标志,命令停在交互确认。

处置在非交互环境一律使用 `terraform apply -auto-approve`,并确保流水线已经完成 `init` 与 `plan` 审阅环节。

现象把 count 改成 for_each(或反过来)后 Terraform 要销毁并重建整批资源

原因两者的资源地址形式不同,切换即等于换了身份。

处置在切换前用 `terraform state mv` 尽量迁移已有资源地址,或接受重建代价时先评估停机窗口。

排障路径

  1. 1确认本地状态里到底有哪些资源

    terraform state list

    输出的资源地址是排查「缺失资源 / 多余资源」的第一手依据。

  2. 2查看单个资源的实际状态属性

    terraform state show aws_instance.web

    用于对比配置与真实资源差异,定位漂移来源。

  3. 3把状态输出成 JSON 供 grep/jq 分析

    terraform show -json

    适合在脚本里统计资源数量、比对 ID,或与 plan 结果做差异对比。

  4. 4交互式验证表达式是否算对

    terraform console

    输入 var.region、local.name 之类表达式,直接看求值结果,比改完 plan 再试快得多。

  5. 5打开详细日志并落盘

    TF_LOG=DEBUG TF_LOG_PATH=./tf.log terraform plan

    日志里能看到 Provider 实际发出的 API 请求与响应,是排查「资源外部系统改不了」的关键。

  6. 6用代码格式检查暴露潜在语法问题

    terraform fmt -check -diff

    CI 中作为门禁使用,输出差异即为不符合规范的文件片段。

命令示例

先 plan 看清差异再 apply

terraform plan -out=tfplan terraform show tfplan

plan -out 存成文件后可以 terraform show tfplan 复核,再 terraform apply tfplan 执行同一份计划,保证执行的就是你审过的那版。

输出

  # aws_instance.web will be updated in-place
  ~ resource "aws_instance" "web" {
      ~ instance_type = "t2.micro" -> "t3.medium"
    }

Plan: 0 to add, 1 to change, 0 to destroy.

漂移检测:现实与状态不一致时

terraform plan -detailed-exitcode echo $?

退出码 0=无变更、1=有错误、2=有变更且非破坏性。这个约定让它能直接用在 CI 里做基础设施漂移检测。

输出

2

状态与现实脱节时让 Terraform 忘记资源

terraform state rm aws_instance.web terraform plan

state rm 只改状态不动真实资源,plan 随即显示要重建——这正是「删掉重建」而非误删。直接用 destroy 会真删掉机器。

输出

  # aws_instance.web will be created
  + resource "aws_instance" "web" {
      + id = "i-0abc123"
    }

Plan: 1 to add, 0 to change, 0 to destroy.

常见坑与注意事项

  • apply 前必须先看 plan;对含 destroy 的计划不加 -auto-approve,确认无误再执行。
  • 状态文件含敏感信息且不应提交 Git,生产环境必须配置远程后端并启用状态锁。
  • terraform destroy 会删除所有受管资源,包括数据库;只想删单个资源应改用 -target 或从配置移除。
  • for_each 的键变更会导致整个资源销毁重建;键要设计成稳定不变的标识。
  • 切 workspace 前务必 terraform workspace show 确认当前环境,prod 与 staging 用错会出事。
  • state rm 让人工创建的资源被 plan 判定为缺失从而重建;用于扶正漂移而非掩盖问题。

提示

  • terraform plan 永远不会修改资源,放心使用
  • 将敏感信息放在变量中,不要硬编码在 .tf 文件里
  • 使用 terraform fmt 统一代码格式,团队协作必备
  • state 文件包含敏感信息,切勿提交到 Git
  • 使用 remote backend(如 S3+ DynamoDB)实现团队协作和状态锁
  • terraform state show <资源地址> 可查看单个资源的完整属性,比反复 plan 更快定位差异来源。
  • terraform refresh-only 只同步状态不改实际资源,状态漂移时比 apply 安全但仍需人工核对清单。
  • tfvars 与同名变量后缀对应:terraform.tfvars 自动加载,环境专用值放 terraform.<env>.tfvars 显式指定。

常见问题

terraform plan 和 apply 为什么要分开跑?

plan 只计算并展示差异,不动任何资源;apply 才真正创建、修改或销毁。把 plan 单独跑一遍是把人工确认插进流程的机会,尤其对会触发重建或删除资源的改动。日常可以先 plan 存下输出,apply 时加 plan 指定的文件重放同一份计划,保证执行的正是你审过的那一版。

terraform state rm 和 terraform destroy 有什么区别?

destroy 会真的删除云上资源并从状态移除它;state rm 只是把资源从状态文件中摘掉,云上的实际资源仍在运行。适用场景完全不同:误用变量导致状态与现实不符时用 state rm 让 Terraform 忘记这个资源,从而避免它把资源「删掉重建」;要真正回收资源时才用 destroy。

workspace 应该在什么时候切换?

每个环境一个 workspace(如 staging、prod),用 terraform workspace new staging 创建、select 切换、list 查看。但 workspace 共享同一个后端状态文件,不同 workspace 的资源命名必须自己保证不冲突。更重要的是:workspace 是易错的,务必在每次操作前用 terraform workspace show 确认当前处于哪一个环境。

count 和 for_each 批量创建资源时该选哪个?

count 适用于创建完全相同的资源,只是数量不同;for_each 适用于每个实例配置不同的情况,比如不同子网或不同规格。因为 for_each 的键一旦变更,Terraform 会销毁并重建对应的整个资源,所以键要设计成稳定不变的标识;count 的序号在列表变动时同样会导致索引漂移引发重建。

状态文件应该提交到 Git 吗?

不应该,状态文件记录的是与真实资源的对应关系,包含敏感信息且极易产生冲突合并。正确做法是配置远程后端(backend "s3" 之类)把它放在对象存储或 Terraform Cloud 里,本地只保留配置代码。团队协作时还需要配置状态锁(如 S3 的 DynamoDB 锁或 Terraform Cloud),否则两个人同时 apply 会互相覆盖。

官方参考来源

下方为命令对应的官方权威文档,供你核对最新用法与深入查阅。

由 巧匠 维护

公开更新于 2026年7月21日,内容持续校对官方文档。

联系我们

命令或描述有误?提交反馈、商务合作或产品建议都可发送邮件给我们。

联系我们