Terraform 实战:用 IaC 管理云基础设施

Terraform 是当下最主流的基础设施即代码(IaC)工具:你不再手动在云控制台点选 ECS、安全组、数据库,而是用一份 HCL 文件声明“最终要长什么样”,由 Terraform 计算出变更并安全地落地。本文从 provider、resource 讲到 state 状态管理与 module 模块化,并带你用阿里云实操一套可复用的基础设施模板,把“点出来的环境”变成“版本控制里的基础设施”。

一、Terraform 是什么:为什么用代码管基础设施

传统运维靠手点控制台,环境一旦复杂就面临“配置漂移”——测试环境和生产环境慢慢对不上,出问题时没人说得清到底改了哪。Terraform 把基础设施抽象成代码,每一次变更都可评审、可回滚、可复制。

1.1 声明式 vs 命令式

命令式告诉你“先做什么再做什么”(比如一串 shell 脚本),声明式只描述“目标状态”。Terraform 属于后者:你写“我要一台 2 核 4G 的 ECS”,它自己决定是新建、还是改配置、还是什么都不做。

1.2 核心工作模型

三个关键概念贯穿全文:Provider 是云厂商插件(阿里云、AWS、腾讯云);Resource 是一个具体资源(一台实例、一个_bucket);State 是 Terraform 记录“现实长什么样”的本地/远程快照,用来比对目标与现状的差值。

二、快速上手:写第一个 main.tf

一个最小可运行的 Terraform 配置通常包含 provider 块与若干 resource 块。下面用阿里云为例,声明一台 ECS 实例。

2.1 provider 与 resource

# main.tf
terraform {
  required_providers {
    alicloud = {
      source  = "aliyun/alicloud"
      version = "~> 1.220"
    }
  }
}

provider "alicloud" {
  region = "cn-hangzhou"
}

resource "alicloud_instance" "web" {
  instance_name              = "tf-demo-web"
  instance_type              = "ecs.c7.large"   # 2 vCPU / 4 GiB
  image_id                   = "ubuntu_22_04_x64_20G_alibase_20240101.vhd"
  security_groups            = [alicloud_security_group.web.id]
  vswitch_id                 = "vsw-bp1xxxxxx"
  internet_max_bandwidth_out = 10
}

写好配置后,标准三步把环境拉起来。注意 plan 会预览变更而不真正执行,上线前务必先看 diff。

2.2 init / plan / apply

# 1. 下载 provider 插件(首次或改 provider 时)
terraform init

# 2. 预览变更:+ 新建 / - 删除 / ~ 修改
terraform plan

# 3. 真正执行(交互确认);非交互用 -auto-approve
terraform apply

# 销毁整套环境(危险,慎用)
terraform destroy

三、状态管理 state:Terraform 的“记忆”

很多人初学踩的第一个坑就是 state。State 文件记录了资源与云上实体的映射,一旦丢失或多人各持一份,Terraform 就会以为资源不存在而重复创建,或误删线上资产。

3.1 本地 state 的三个坑

默认 terraform.tfstate 落在本地:① 团队协作时互相覆盖;② 文件进了 Git 可能泄露密钥;③ 本地机器坏了状态就没了。所以生产环境一定用远程后端。

3.2 远程后端实战(阿里云 OSS)

# backend.tf
terraform {
  backend "oss" {
    bucket = "my-tf-state"
    key    = "prod/web/terraform.tfstate"
    region = "cn-hangzhou"
    # 建议同时开启 OSS 版本控制与合规保留,防误删
  }
}

迁移到远程后端只需再跑一次 terraform init,它会提示把本地 state 迁过去。远程后端天然支持状态锁,避免两个人同时 apply 互相冲掉。

四、变量与模块化:写出可复用的基础设施

硬编码配置没法复用。用 variable 抽参数、output 暴露结果,再用 module 把一组资源打包成“积木”,就能一份代码管多套环境。

4.1 variable 与 output

# variables.tf
variable "instance_type" {
  type        = string
  default     = "ecs.c7.large"
  description = "ECS 规格"
}

# outputs.tf
output "web_public_ip" {
  value = alicloud_instance.web.public_ip
}

4.2 module 复用

# 主配置里调用自定义模块
module "web_cluster" {
  source        = "./modules/web"
  instance_type = var.instance_type
  replica       = 2
}

常见变量类型与默认值策略如下,合理设默认值能降低调用方的心智负担。

类型示例适用场景
string“ecs.c7.large”规格、地域、镜像 ID
number2副本数、带宽
list(string)[“sg-a”,”sg-b”]安全组列表、可用区
map(any){env=”prod”}标签、环境变量

五、生产实战:用代码拉起一套 Web 服务

下面把前面知识点串起来:声明安全组、ECS,并自动输出公网 IP。这与手动在控制台操作等价,但全程可评审、可复制。

5.1 安全组 + ECS 联动

resource "alicloud_security_group" "web" {
  name   = "tf-web-sg"
  vpc_id = "vpc-bp1xxxxxx"
}

resource "alicloud_security_group_rule" "ssh" {
  type              = "ingress"
  ip_protocol       = "tcp"
  port_range        = "22/22"
  security_group_id = alicloud_security_group.web.id
  cidr_ip           = "10.0.0.0/8"   # 仅内网,避免 0.0.0.0/0 暴露
}

安全组规则建议只放行必要端口、来源尽量收紧。服务器层面的加固可参考我们的服务器安全加固:SSH / 防火墙 / Fail2ban 实战指南,把“网络入口”和“主机防护”两道防线都立起来。

六、踩坑与最佳实践

6.1 新手最常踩的雷区

① 把 .tfstate 提交到 Git;② 在资源已存在时又写一遍导致冲突(应先用 terraform import 接管存量资源);③ 对生产环境直接 apply -auto-approve 不看 plan;④ 用 count 改列表顺序导致资源被整体重建。

命令作用上线前必做
terraform fmt格式化代码建议 CI 校验
terraform validate语法/类型校验必做
terraform plan预览变更必做,存为产物
terraform apply落地变更看 plan 后再执行

6.2 把 Terraform 接进 CI/CD

把 fmt + validate + plan 放进入库流水线是低成本高回报的护栏。我们的K8s 入门:Pod、Deployment、Service与Docker 网络模式详解都强调“环境一致性”,而 Terraform 正是把这份一致性从容器层一路管到云资源层的关键一环。

七、与现有运维体系衔接

Terraform 负责“建”,建好之后的“跑”和“存”另有专人:用K8s 持久化存储 PV/PVC承载有状态负载,用服务器安全加固守住主机边界。IaC 不是银弹,但它是让整套环境“可声明、可复现、可审计”的地基——当你能在 10 分钟内用一份代码重建整套预发环境时,就会再也回不去手动点控制台的日子。

总结

Terraform 把基础设施变成了和应用程序一样的代码:声明目标、预览变更、安全落地、远程锁状态、模块化复用。掌握 provider / resource / state / module 这四块,你就能用一套 HCL 管起跨云、跨环境的所有资源,让“环境即代码”真正落地。

上一篇 浏览器渲染原理:从关键渲染路径到重排重绘
下一篇 Caddy 实战:自动 HTTPS 的现代 Web 服务器与反向代理
最新评论
Docker 网络模式详解:bridge/host 生产选型 - FSData
Docker 网络模式详解:bridge/host 生产选型 - FSData
8月20日
[…] 注意最后那条:把端口绑定到 127.0.0.1,再由宿主机上的 Nginx 反代进来,比直接 -p 80:80 暴露安全得多,也方便统一做
Vue3 + TypeScript 工程化:类型安全的前端架构 - FSData
Vue3 + TypeScript 工程化:类型安全的前端架构 - FSData
8月20日
[…] Pinia 的工程化用法,可以参考我们之前的实战文章 《Vue3 组合式 API + Pinia:状态管理从入门到实战》,那里覆盖了 Sto
2026 年最值得装的 10 个 VS Code 插件(AI/前端/后端/效率全覆盖) - FSData
2026 年最值得装的 10 个 VS Code 插件(AI/前端/后端/效率全覆盖) - FSData
8月19日
[…] 状态,点一下就能起停容器,配合我们讲过的 Docker Compose 编排 […]
Redis 缓存设计:穿透、击穿、雪崩与最佳实践 - FSData
Redis 缓存设计:穿透、击穿、雪崩与最佳实践 - FSData
8月19日
[…] 缓存三大坑的本质都是”缓存失效导致请求穿透到数据库”。记住口诀:穿透用布隆、击穿用锁、雪崩用错峰。配合合理的过期策略
GitHub Actions 实战:从零搭建 CI/CD 流水线 - FSData
GitHub Actions 实战:从零搭建 CI/CD 流水线 - FSData
8月19日
[…] Docker 镜像部署。结合我们之前写的 Docker Compose 一键编排实战,可以在 CI […]