前言

随着云原生技术的普及,手工登录控制台管理云资源的方式已经难以满足团队协作和审计要求。基础设施即代码(Infrastructure as Code,IaC)成为了现代运维的标配。Terraform 作为 HashiCorp 推出的声明式 IaC 工具,以跨云支持和状态管理能力脱颖而出。本文从实战角度出发,介绍 Terraform 的核心概念、团队协作模式以及常见避坑指南,适合想将云资源管理纳入版本控制的运维团队参考。

一、核心概念速览

Terraform 的工作逻辑非常清晰:用户编写 .tf 声明文件描述”期望的基础设施状态”,Terraform 通过 Provider(如阿里云、AWS)对接云 API,调用 API 确保实际环境与声明一致。两者的差异称为 drift,可通过 terraform plan 预览。

几个关键文件:

  • .tf 文件:声明资源,如 resource "alicloud_instance" "web" { ... }
  • .tfstate 文件:Terraform 的状态数据库,记录当前资源快照(敏感信息,切勿明文上传)
  • .tfvars 文件:变量文件,分离配置与代码,如 variable "instance_type" { default = "ecs.n4.large" }

二、快速上手

1. 安装与初始化

1
2
3
4
5
6
7
8
9
# Linux 安装
curl -fsSL https://releases.hashicorp.com/terraform/1.7.5/terraform_1.7.5_linux_amd64.zip -o terraform.zip
unzip terraform.zip && mv terraform /usr/local/bin/

# 验证
terraform version

# 初始化(下载 Provider 插件)
terraform init

2. 编写第一个资源

以下示例在阿里云创建一台 ECS 实例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
# variables.tf
variable "region" {
default = "cn-beijing"
}

variable "instance_type" {
default = "ecs.n4.large"
}

# main.tf
terraform {
required_providers {
alicloud = {
source = "aliyun/alicloud"
version = "1.212.0"
}
}
}

provider "alicloud" {
region = var.region
}

resource "alicloud_instance" "web" {
instance_name = "web-server-${var.environment}"
instance_type = var.instance_type
image_id = "ubuntu_22_04_x64_20G_alibase_20231220.vhd"
vswitch_id = var.vswitch_id
security_groups = [var.security_group_id]

tags = {
Environment = var.environment
ManagedBy = "terraform"
}
}

3. 规划与执行

1
2
3
4
5
6
7
8
# 预览变更(强烈建议先执行此步)
terraform plan -var-file="prod.tfvars"

# 应用变更
terraform apply -var-file="prod.tfvars"

# 销毁资源(测试环境慎用)
terraform destroy -var-file="prod.tfvars"

三、团队协作模式

手工本地运行 Terraform 的最大问题是 状态冲突:多人同时 apply 会导致状态覆盖和资源重复创建。推荐以下协作方案:

1. 远程状态存储

使用对象存储(如阿里云 OSS + RDS)作为后端:

1
2
3
4
5
6
7
8
terraform {
backend "oss" {
bucket = "tf-state-prod"
key = "prod/network/terraform.tfstate"
encrypt = true
tablestore_table = "tfstate"
}
}

这样每次 terraform plan/apply 都会锁定状态文件,避免并发冲突。

2. 工作目录分离

不同环境隔离为独立目录,避免 dev 操作影响 prod:

1
2
3
4
5
6
7
8
9
10
infrastructure/
├── prod/
│ ├── main.tf
│ └── prod.tfvars
├── staging/
│ ├── main.tf
│ └── staging.tfvars
└── modules/
├── vpc/
└── ecs/

共享模块提取到 modules/,在各个环境调用:

1
2
3
4
module "vpc" {
source = "../../modules/vpc"
vpc_cidr = var.prod_vpc_cidr
}

3. 变量敏感信息处理

敏感变量(如密码、密钥)不要写入 .tfvars,而是通过环境变量或 CI/CD 密钥管理传入:

1
2
3
4
5
# 通过环境变量传入(推荐)
export ARM_ACCESS_KEY_ID="your_access_key"
export ARM_ACCESS_KEY_SECRET="your_access_secret"

# 或者在 CI/CD 中配置 secret 变量,terraform init 自动读取

四、常见问题与避坑

1. 状态膨胀

随着资源增多,单个 .tfstate 文件会越来越大,terraform plan 变慢。解决方案:使用 terraform state mv 将状态按模块拆分,或使用 terraform import 将存量资源纳入管理。

2. 资源误删

线上误执行 terraform destroy 是灾难性的。建议:

  • 所有生产环境开启 state locking(后端锁)
  • 生产环境永远使用 terraform apply -var-file="prod.tfvars" 并经 review
  • 开启 Protection(如阿里云 ECS 实例的删除保护)

3. drift 积累

长期手工修改云资源(绕过 Terraform)会导致 state 与实际环境偏差越来越大。定期运行 terraform plan 检测 drift,发现 drift 时优先用 terraform import 纳入管理,而非直接 apply 覆盖手工修改。

4. Provider 版本兼容性

Provider 大版本升级可能破坏已有状态文件的兼容性。锁定版本:

1
2
3
4
5
6
7
8
terraform {
required_providers {
alicloud = {
source = "aliyun/alicloud"
version = "=1.212.0" # 严格锁定
}
}
}

五、CI/CD 集成建议

将 Terraform 流程嵌入 GitLab CI / GitHub Actions,实现自动化:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# .gitlab-ci.yml 示例
stages:
- validate
- plan
- apply

terraform:
image: hashicorp/terraform:1.7.5
script:
- terraform init
- terraform validate
- terraform plan -out=tfplan -var-file=$ENV.tfvars
artifacts:
paths:
- tfplan

配合 MR/PR 流程,每次变更都必须经过 code review,从源头控制风险。

结语

Terraform 将云资源管理带入版本化、可审计、可协作的时代。核心在于:声明优于命令、状态重于代码、协作需要锁。本文覆盖了从安装到团队落地的关键路径,建议从 staging 环境开始实践,逐步将核心基础设施纳入 Terraform 管理,积累经验后再扩展到生产环境。


如有问题或经验欢迎交流。