前置知识: 云计算

Terraform 状态与模块

3 min入门

Terraform 状态管理:state 命令、导入、工作空间、远程后端与锁,以及模块引用。

状态(state)是什么:terraform.tfstate 是 Terraform 记录「我管理 了哪些真实资源、它们当前属性是什么」的映射表。plan/apply 的全部差异 计算都基于它——状态丢失或损坏,Terraform 就「失忆」,可能对既有资源 做出破坏性变更。因此本文的命令按危险等级记:查看类安全,state rm/ state push/workspace delete 属于高危操作。

状态查看

基本写法:列出状态中所有资源 terraform state list

# 列出当前状态文件中所有资源
terraform state list

基本写法:查看资源详情 terraform state show <资源类型>.<资源名>

# 查看指定资源的状态属性
terraform state show aws_instance.example

基本写法:以人类可读格式查看 terraform show

# 显示整个状态文件
terraform show

基本写法:以 JSON 输出状态 terraform show -json

# 输出 JSON 格式状态便于程序解析
terraform show -json

基本写法:查看所有输出值 terraform output

# 显示所有 output 块的值
terraform output

基本写法:查看单个输出 terraform output <输出名>

# 查看指定输出值
terraform output instance_id

状态管理

基本写法:拉取远程状态 terraform state pull

# 从后端拉取状态到标准输出
terraform state pull

基本写法:推送本地状态 terraform state push <状态文件>

# 推送本地状态文件到远程后端(高危:覆盖远端状态,仅在灾备恢复时使用)
terraform state push terraform.tfstate

警告:state push 会用本地文件覆盖远端状态,push 前先 terraform state pull > backup.tfstate 留底。团队协作中永远不要 用它「同步状态」。


基本写法:从状态中移除资源 terraform state rm <资源类型>.<资源名>

# 移除资源但不销毁实际基础设施
terraform state rm aws_instance.example

基本写法:重命名状态中的资源 terraform state mv <旧地址> <新地址>

# 重命名状态中的资源地址
terraform state mv aws_instance.old aws_instance.new

基本写法:替换资源 terraform apply -replace=<资源类型>.<资源名>

# 强制销毁并重建指定资源
terraform apply -replace=aws_instance.example

基本写法:检测漂移 terraform plan -refresh-only

# 仅刷新状态检测实际漂移
terraform plan -refresh-only

资源导入

基本写法:导入现有资源 terraform import <资源类型>.<资源名> <远程ID>

# 将现有 EC2 实例导入到 Terraform 管理
terraform import aws_instance.example i-1234567890abcdef0

基本写法:声明式导入块

# Terraform 1.5+ 支持的声明式导入
import {
  to = aws_instance.example
  id = "i-1234567890abcdef0"
}

基本写法:生成导入配置 terraform plan -generate-config-out=<文件>

# 为导入的资源生成配置代码
terraform plan -generate-config-out=generated.tf

工作空间

基本写法:列出工作空间 terraform workspace list

# 列出所有工作空间
terraform workspace list

基本写法:创建工作空间 terraform workspace new <工作空间名>

# 创建新的工作空间用于多环境管理
terraform workspace new production

基本写法:切换工作空间 terraform workspace select <工作空间名>

# 切换到指定工作空间
terraform workspace select production

基本写法:查看当前工作空间 terraform workspace show

# 输出当前激活的工作空间名
terraform workspace show

基本写法:删除工作空间 terraform workspace delete <工作空间名>

# 删除非当前激活的工作空间
terraform workspace delete staging

基本写法:在配置中引用工作空间

# 根据工作空间区分环境配置
resource "aws_instance" "example" {
  ami           = "ami-0c55b159cbfafe1f0"
  instance_type = terraform.workspace == "production" ? "t3.medium" : "t3.micro"
}

后端配置

基本写法:本地后端

# 默认本地后端
terraform {
  backend "local" {
    path = "terraform.tfstate"
  }
}

基本写法:S3 远程后端

# 使用 S3 实现远程状态(对象版本化)与锁
terraform {
  backend "s3" {
    bucket       = "my-tfstate-bucket"
    key          = "prod/terraform.tfstate"
    region       = "us-east-1"
    use_lockfile = true   # Terraform 1.10+:S3 原生锁文件(替代 DynamoDB 锁)
    encrypt      = true
  }
}

说明:早期版本用 dynamodb_table 做状态锁;1.10 起推荐 S3 原生 锁文件(use_lockfile = true),DynamoDB 方式仍可用但已是过渡方案。 远程后端 + 锁是团队协作的底线:两人同时 apply 时锁保证串行,S3 版本化提供状态回滚能力。


基本写法:后端初始化迁移 terraform init -migrate-state

# 切换后端时迁移现有状态
terraform init -migrate-state

基本写法:强制重新配置后端 terraform init -reconfigure

# 忽略已有配置重新初始化后端
terraform init -reconfigure

模块引用

基本写法:引用模块输出

# 引用子模块的输出值
resource "aws_instance" "example" {
  ami           = "ami-0c55b159cbfafe1f0"
  instance_type = "t3.micro"
  subnet_id     = module.vpc.public_subnet_id
}

基本写法:从 Git 仓库引用模块

# 引用 Git 仓库中的模块
module "vpc" {
  source = "git::https://github.com/example/terraform-modules.git//vpc?ref=v1.2.0"
  cidr   = "10.0.0.0/16"
}

小结

  • 初学者要点:state 是 Terraform 的「资源账本」,丢失即失忆;团队 协作必须远端后端 + 锁(1.10+ 用 S3 use_lockfile);查看类命令 (list/show/output)随便跑,state rm/state push/workspace delete 属高危;存量资源用 1.5+ 的 import 块 + -generate-config-out 声明式纳管。
  • 进阶注意:工作空间适合轻量多环境(同一配置的小变体),环境差异大 或需要隔离权限/状态时改用「每环境独立目录 + 远端后端」;改名优先 用 state mv 而非删了重建;-refresh-only 是漂移检测的正道(只 对账不改资源);state rm + import 组合可把资源在模块间搬家而不 触发销毁。