目录

Terraform 深度拆解:基础设施即代码的事实标准

Terraform 深度拆解:基础设施即代码的事实标准

核心判断

Terraform 之所以成为 IaC(基础设施即代码)的事实标准,不是因为"声明式配置"——Pulumi/CloudFormation/CDK 都能做声明式。它赢在三件事的组合

  1. HCL 配置语言:声明意图而非执行步骤,但又不强制纯 JSON/YAML
  2. Provider 插件架构:把云厂商 API 适配下沉到独立可执行文件,核心引擎与云服务解耦
  3. State 图:把"声明 vs 实际"统一存到单一文件,让"删除资源"“变更追踪"“依赖分析"变得可计算

这三件事组合让 Terraform 能"表达任意云的任意资源”,并保持一个稳定的核心。这套架构直接启发了后来所有 IaC 工具的设计。

项目坐标

维度数据
仓库hashicorp/terraform
Stars约 49k
主语言Go
LicenseBSL 1.1(v1.5+ 从 MPL 改为 BSL,部分使用受限)
当前主版本1.9+(截至 2026 年)
配置语言HCL(HashiCorp Configuration Language)
状态后端本地文件 / S3 / Terraform Cloud / GCS / Azure Storage

2023 年 HashiCorp 把 Terraform 切换到 BSL 1.1 许可证,引发社区分叉 OpenTofu(Linux Foundation 治理)。如果合规/许可证敏感,要评估用 OpenTofu。

核心机制:State Graph

Terraform 跑 apply 的流程:

1. 读 .tf 配置文件 → parse → desired state(期望状态)
2. 读 terraform.tfstate → current state(当前状态)  
3. 对比 desired vs current + 调 provider API 查 live state(实际状态)
4. 计算 diff(创建/更新/删除操作列表)
5. 按依赖图(dependency graph)排序
6. 依次执行计划的操作
7. 更新 terraform.tfstate

State 是 Terraform 的核心抽象:

  • 依赖追踪:Terraform 自动从 resource "X" { y = resource.Z.id } 推出依赖图,无需手动声明
  • 变更 diff:diff = desired - current,删除/创建/更新用符号 + - ~ 表示
  • 回滚能力:在 destroy 模式下能从 state 还原资源(部分恢复)

关键事实:State 是 Terraform 工作的"真相之源”,不是 .tf 文件。如果 State 损坏或丢失,Terraform 无法判断"哪些资源已经存在",会尝试重建——后果可能是删除生产数据库。所以 State 必须有远程后端 + 锁定机制。

一个最小例子

# main.tf
terraform {
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 5.0"
    }
  }
  backend "s3" {
    bucket = "my-tf-state"
    key    = "prod/terraform.tfstate"
    region = "us-east-1"
    dynamodb_table = "tf-lock"
  }
}

provider "aws" {
  region = "us-east-1"
}

resource "aws_instance" "web" {
  ami           = "ami-0c55b159cbfafe1f0"
  instance_type = "t3.small"
  
  tags = {
    Name = "web-server"
  }
}

resource "aws_eip" "web_ip" {
  instance = aws_instance.web.id
}

output "public_ip" {
  value = aws_eip.web_ip.public_ip
}
terraform init     # 下载 provider + 配置 backend
terraform plan     # 看变更计划
terraform apply    # 执行 + 写 state
terraform destroy  # 清理所有受管资源

terraform plan 输出形如:

Terraform will perform the following actions:
  + aws_instance.web    will be created
  + aws_eip.web_ip      will be created
Plan: 2 to add, 0 to change, 0 to destroy.

Provider 生态

截至 2026 年,HashiCorp 官方维护 3000+ Provider,覆盖:

  • 公有云:AWS、GCP、Azure、Oracle、Aliyun、Tencent Cloud
  • PaaS:Heroku、Cloudflare、Datadog、PagerDuty
  • SaaS:GitHub、Slack、Stripe、Tailscale
  • 数据库:PostgreSQL、MongoDB、Redis、Vault
  • 监控:Grafana、Prometheus、New Relic
  • Kubernetes:原生 k8s provider

第三方维护的 Provider 还有数千个。任何能用 HTTP API 描述的服务都可以写一个 Provider。

模块化(Modules)

Terraform 的模块系统让"复用基础设施模板"成为可能:

# modules/vpc/main.tf
variable "cidr_block" { type = string }
variable "environment" { type = string }

resource "aws_vpc" "this" {
  cidr_block = var.cidr_block
  tags = { Environment = var.environment }
}

# ... subnets, route tables, IGW ...

output "vpc_id" { value = aws_vpc.this.id }
# prod/main.tf
module "main_vpc" {
  source      = "../modules/vpc"
  cidr_block  = "10.0.0.0/16"
  environment = "prod"
}

module "staging_vpc" {
  source      = "../modules/vpc"
  cidr_block  = "10.1.0.0/16"
  environment = "staging"
}

社区生态:

  • Terraform Registryregistry.terraform.io 收录 18,000+ 模块
  • Terragrunt:Wrapping Terraform,简化多环境/多 region 复用
  • Terratest:Go 写的 Terraform 集成测试框架

State 后端

生产环境的 State 必须放远程、加锁:

Backend适用场景
Local单人开发、本地试验
S3 + DynamoDBAWS 项目经典组合,加锁防并发
GCSGCP 项目
Azure StorageAzure 项目
Terraform CloudHashiCorp 托管,含 VCS 集成、Policy as Code
Consul自托管,集成 HashiCorp 生态
etcd自托管

并发场景下,State 锁(lock)是必须的——否则两个人同时 apply 会导致 State 损坏。

Terraform Cloud / Enterprise

HashiCorp 商业版 Terraform Cloud 提供:

  • VCS 集成:GitHub/GitLab PR 自动跑 plan
  • State 管理:加密存储 + 跨工作区共享
  • Policy as Code:Sentinel / OPA 强制合规策略
  • 私有模块注册:组织内复用模块
  • 审计日志:合规审计

如果团队规模 5-10 人或以上,Terraform Cloud 的协作价值明显;规模更小就本地 S3 backend 足够。

与 Pulumi / CDK / OpenTofu 的取舍

维度TerraformPulumiAWS CDKOpenTofu
语言HCLTypeScript / Python / Go / .NETTypeScript / Python / Java / GoHCL(同 Terraform)
状态管理显式 state file显式 state(云端存储)CloudFormation 内部管理同 Terraform
Provider 模型二进制 + RPC原生 SDK 包装CloudFormation 资源 1:1同 Terraform
多云支持✅ 3000+ provider✅ 150+ provider❌ 仅 AWS✅ 同 Terraform
学习曲线低(HCL 简单)中(要会编程语言)
循环/条件HCL 原生支持完整编程语言能力完整编程语言能力同 Terraform
社区巨大中(AWS 用户)中(Terraform 分支)
许可证BSL 1.1Apache 2.0Apache 2.0MPL 2.0

决策建议

  • 多云 + 运维团队 + 跨公司复用模块 → Terraform / OpenTofu
  • 开发团队 + 已用 TypeScript/Python + 想用 IDE 智能提示 → Pulumi
  • AWS 单云 + 已有 CloudFormation 资产 → CDK
  • Terraform 老项目 + 许可证顾虑 → 平滑迁移到 OpenTofu

实战:State 管理的几个坑

1. State 丢失导致重建

如果 S3 bucket 被删,State 丢失,Terraform 不会"知道"资源还在——它会试图重建。要始终用 State 备份 + 版本控制(S3 自己有版本控制功能)。

2. 手动改资源导致漂移

如果绕过 Terraform 直接在 AWS 控制台改了资源,State 与实际不一致(drift)。terraform plan 会显示"inconsistent"。可以 terraform apply -refresh-only 让 State 同步。

3. 资源依赖图错乱

显式使用 depends_on 是反模式——应该让 Terraform 从属性引用推断依赖:

# ✅ 好
resource "aws_eip" "ip" {
  instance = aws_instance.web.id   # 隐含依赖
}

# ❌ 不好
resource "aws_eip" "ip" {
  instance = aws_instance.web.id
  depends_on = [aws_instance.web]  # 冗余
}

4. 模块引用死循环

A 模块引用 B 模块,B 又引用 A → Terraform 会循环报错。设计模块时保持单向依赖。

何时不用 Terraform

  • 单个云 + 简单资源 → CloudFormation / Azure Resource Manager / GCP Deployment Manager 更原生
  • 极小项目(< 10 个资源) → 配置文件 + 手动 apply 也未尝不可
  • Kubernetes 资源编排 → Helm / Kustomize / ArgoCD 更专业
  • 完全不想学新工具 → Pulumi 用熟悉的语言

实战起步建议

  1. 第一个项目:本地单文件 + Local state,熟悉 plan/apply 流程
  2. 第二阶段:换 S3 backend + DynamoDB lock
  3. 第三阶段:拆模块(modules/network、modules/compute、modules/db)
  4. 第四阶段:用 Terragrunt 或 Terraform Cloud 跨环境管理(dev/staging/prod)
  5. 第五阶段:接 CI/CD(GitHub Actions 跑 plan,merge 后 apply)+ Policy as Code

参考资源