4. 基础设施即代码(IaC):Terraform核心概念

在平台工程中,环境编排的核心挑战在于如何以可重复、可版本控制、可审计的方式管理云基础设施。Terraform 作为业界最广泛使用的声明式 IaC 工具,通过 Provider、Resource、State 三大核心概念,将基础设施的声明、编排与生命周期管理标准化。本章深入剖析其核心机制与最佳实践。

4.1 核心概念:Provider / Resource / State

Terraform 的运作模型围绕三个抽象层展开:Provider 负责与目标 API 通信,Resource 描述期望的基础设施对象,State 则作为真实世界与配置文件的映射桥梁。

概念 角色 关键特征
Provider API 适配器 封装云厂商(AWS/Azure/GCP)或服务(Kubernetes/Helm)的 API 调用;通过 required_providers 声明版本约束。
Resource 基础设施对象 使用 resource "type" "name" 块定义;支持参数、元参数(count/for_each)、依赖关系。
State 映射文件 JSON 格式存储资源 ID、属性及依赖;用于 plan 对比与 apply 变更;必须安全存储。
平台工程视角: Provider 是平台团队封装底层差异的关键接口。通过定制 Provider 或使用 terraform-provider-http,可以将内部系统(如 CMDB、工单系统)暴露为 Terraform 资源,实现统一编排。

4.2 HCL 语法与模块化设计

HCL(HashiCorp Configuration Language)是 Terraform 的声明式语言,强调可读性与层次结构。模块化设计则通过封装可复用的配置单元,降低平台环境的重复代码。

4.2.1 HCL 基础语法

# 变量定义
variable "environment" {
  description = "部署环境名称"
  type        = string
  default     = "dev"
}

# 本地值
locals {
  name_prefix = "${var.environment}-platform"
}

# 数据源:查询现有资源
data "aws_vpc" "selected" {
  tags = {
    Name = "${var.environment}-vpc"
  }
}

# 资源声明
resource "aws_instance" "web" {
  ami           = "ami-0c55b159cbfafe1f0"
  instance_type = "t3.medium"
  subnet_id     = data.aws_vpc.selected.main_route_table_id

  tags = {
    Name        = "${local.name_prefix}-web"
    Environment = var.environment
  }
}

# 输出值
output "instance_ip" {
  value = aws_instance.web.public_ip
}

4.2.2 模块化设计原则

  • 单一职责: 每个模块只管理一类资源(如网络、计算、数据库)。
  • 版本化: 使用 Git 标签或 Terraform Registry 管理模块版本,避免隐式变更。
  • 输入输出契约: 明确定义 variable 与 output,隐藏内部实现细节。
  • 组合而非继承: 通过 module 块嵌套组合,避免模块内部条件分支过多。
# 调用网络模块
module "vpc" {
  source      = "terraform-aws-modules/vpc/aws"
  version     = "5.0.0"
  name        = "${var.environment}-vpc"
  cidr        = "10.0.0.0/16"
  azs         = ["us-east-1a", "us-east-1b"]
  private_subnets = ["10.0.1.0/24", "10.0.2.0/24"]
  public_subnets  = ["10.0.101.0/24", "10.0.102.0/24"]
  enable_nat_gateway = true
}
模块设计避坑: 避免在模块内部使用 count 或 for_each 创建大量资源,这会导致 plan 输出难以阅读。优先将循环逻辑放在调用方。

4.3 状态管理后端

State 是 Terraform 的核心敏感资产,包含资源 ID、连接信息及依赖关系。平台工程必须采用远程后端(Remote Backend)实现状态共享、锁定与版本历史。

4.3.1 常用后端对比

后端类型 锁定机制 适用场景 注意事项
S3 + DynamoDB DynamoDB 表行锁 AWS 原生环境,团队协作 需配置 DynamoDB 表;S3 版本控制必须开启
Azure Storage Blob 租约锁 Azure 环境 支持公共/私有容器;需 SAS 令牌或 RBAC
GCS 对象版本控制 + 条件更新 GCP 环境 需启用对象版本控制;IAM 权限精细控制
Terraform Cloud 内置工作区锁 全托管,SaaS 模式 需考虑数据驻留与网络隔离

4.3.2 后端配置示例(S3 + DynamoDB)

terraform {
  backend "s3" {
    bucket         = "my-platform-terraform-state"
    key            = "prod/network/terraform.tfstate"
    region         = "us-east-1"
    encrypt        = true
    dynamodb_table = "terraform-state-lock"
  }
}
安全警告: State 文件可能包含明文密码、密钥或连接字符串。务必启用存储后端的加密(如 S3 SSE-S3 或 KMS),并限制 IAM 权限仅允许最小必要操作(s3:GetObject/s3:PutObject)。

4.4 Terraform 核心工作流与状态流转

下图展示了从代码编写到基础设施变更的完整状态流转,突出 State 在 Plan 与 Apply 阶段的核心作用。

Terraform 核心工作流与状态流转 Terraform 核心工作流与状态流转 HCL 配置 terraform init terraform plan State 文件 terraform apply 真实基础设施 terraform destroy 关键说明 • State 是 Plan 的输入 • Apply 更新 State • Destroy 清理 State

4.5 平台工程中的 IaC 策略

在发布工程自助门户中,Terraform 不仅仅是 CLI 工具,更是平台能力的核心引擎。以下策略可提升 IaC 的可维护性与安全性:

  • 策略即代码(Policy as Code): 集成 terraform-plan 输出到 OPA(Open Policy Agent)或 Sentinel,在 Apply 前自动检查合规性(如禁止公开 S3 桶、强制加密)。
  • 工作区(Workspace)隔离: 每个环境(dev/staging/prod)使用独立 Workspace 或独立 State 文件,避免环境间资源冲突。
  • 自动化 CI/CD 集成: 在 GitLab CI / GitHub Actions 中运行 terraform plan,将输出作为 MR 评论;仅允许 apply 在合并到主分支后触发。
  • 状态文件加密与备份: 后端存储必须启用加密(如 AWS KMS),并配置跨区域备份策略,防止单点故障。
平台工程最佳实践: 将 Terraform 模块封装为内部 Registry(如 Terraform Enterprise 或 GitLab Terraform Module Registry),平台团队统一发布版本,应用团队通过 source 引用,无需关心底层实现。

4.6 本章小结