2. 基础设施即代码(IaC)基础:Terraform/Pulumi核心概念与多环境管理

2.1 IaC 核心价值与声明式范式

基础设施即代码(IaC)将传统手工运维的服务器、网络、中间件等资源,转化为可版本控制、可测试、可重复执行的代码。其核心价值在于:一致性(消除环境漂移)、可追溯(Git 记录每一次变更)、自动化(减少人为失误)。

当前主流工具 Terraform 与 Pulumi 均采用声明式(Declarative)范式:用户描述“最终状态”,工具自动计算并执行差异(Diff)。这与脚本式(Imperative)的“如何做”形成鲜明对比。

对比维度 声明式(Terraform / Pulumi) 脚本式(Ansible / Shell)
关注点 What(最终状态) How(执行步骤)
幂等性 天然幂等,自动收敛 需手动编写幂等逻辑
状态管理 依赖状态文件(State) 无状态或依赖外部标记
变更风险 Plan 预览,可控 直接执行,风险较高
SRE 视角: 声明式 IaC 是 SRE 实现“以代码驱动可靠性”的基础。通过 Plan 阶段提前发现配置冲突或资源依赖错误,避免直接在生产环境执行不可逆操作。

2.2 Terraform 核心概念与工作流

Terraform 使用 HCL(HashiCorp Configuration Language)定义资源。其核心工作流围绕 Init → Plan → Apply → Destroy 展开。

  • Provider: 与云平台(AWS、Azure、GCP)或 SaaS 服务交互的插件。
  • Resource: 具体的基础设施对象,如 aws_instance、azurerm_virtual_network。
  • Data Source: 查询已有资源的只读信息。
  • State: 映射真实世界资源与配置文件的 JSON 文件,是 Terraform 决策的核心依据。
  • Module: 可复用的资源组合,是代码复用的基本单元。
# 示例:Terraform 定义 AWS EC2 实例
provider "aws" {
  region = "us-east-1"
}

resource "aws_instance" "web" {
  ami           = "ami-0c55b159cbfafe1f0"
  instance_type = "t3.micro"

  tags = {
    Name = "WebServer-${var.environment}"
  }
}

2.3 Pulumi 核心概念与编程模型

Pulumi 允许使用通用编程语言(TypeScript、Python、Go、C#)定义基础设施。其核心概念与 Terraform 类似,但通过语言特性(循环、函数、类)实现更灵活的抽象。

  • Stack: 对应 Terraform 的 Workspace,是独立的环境实例(dev/staging/prod)。
  • Resource: 与 Terraform 资源一一对应,但通过语言 SDK 创建。
  • Output: 资源的导出属性,用于跨资源引用或外部系统消费。
  • Config: 环境级配置参数,通过 pulumi config set 管理。
// 示例:Pulumi TypeScript 定义 AWS EC2 实例
import * as aws from "@pulumi/aws";
import { Config } from "@pulumi/pulumi";

const config = new Config();
const environment = config.require("environment");

const web = new aws.ec2.Instance("web", {
  ami: "ami-0c55b159cbfafe1f0",
  instanceType: "t3.micro",
  tags: {
    Name: `WebServer-${environment}`,
  },
});

export const publicIp = web.publicIp;
选型建议: 团队以运维/平台工程师为主,且对 HCL 接受度高,优先选择 Terraform;团队以应用开发者为主,希望复用现有编程技能和 CI/CD 工具链,Pulumi 更具优势。

2.4 多环境管理策略:Workspace vs. Directory

管理开发(dev)、测试(staging)、生产(prod)等多套环境是 IaC 落地的关键挑战。主流策略有两种:Workspace 和 Directory。

策略 实现方式 状态文件 适用场景
Workspace 同一套配置,不同 Workspace 名 共享后端,不同 Key 环境差异小,快速原型
Directory 每个环境独立目录,独立配置 完全隔离 环境差异大,严格隔离

Workspace 模式 适合环境间仅存在参数差异(如实例规格、副本数)的场景,但需注意状态文件隔离性较弱,误操作风险较高。Directory 模式 通过目录结构强制隔离,每个环境拥有独立的 backend.tf 和变量文件,是生产环境推荐方案。

# Directory 模式目录结构示例
environments/
├── dev/
│   ├── main.tf
│   ├── variables.tf
│   ├── terraform.tfvars
│   └── backend.tf
├── staging/
│   ├── main.tf
│   ├── variables.tf
│   ├── terraform.tfvars
│   └── backend.tf
└── prod/
    ├── main.tf
    ├── variables.tf
    ├── terraform.tfvars
    └── backend.tf
避坑提示: 避免在 Workspace 模式下使用 terraform workspace select 手动切换环境。生产环境应通过 CI/CD 流水线参数或环境变量强制指定 Workspace,防止人为误操作导致生产资源被意外修改。

2.5 参数配置策略:变量、文件与后端

多环境管理的核心在于参数化。通过将环境差异抽象为变量,实现“一份模板,多套配置”。

  • Input Variables: 定义资源参数(如 region、instance_type、tags)。
  • Local Values: 基于变量计算的中间值,简化表达式。
  • terraform.tfvars: 环境级变量文件,自动加载。
  • Backend: 状态文件存储后端(S3 + DynamoDB、Azure Storage Account、GCS),支持状态锁定与版本控制。
# variables.tf - 定义变量
variable "environment" {
  description = "部署环境名称"
  type        = string
}

variable "instance_type" {
  description = "EC2 实例规格"
  type        = string
  default     = "t3.micro"
}

# terraform.tfvars (dev)
environment   = "dev"
instance_type = "t3.small"

# terraform.tfvars (prod)
environment   = "prod"
instance_type = "m5.large"

2.6 多环境 IaC 架构总览

下图展示了基于 Directory 模式的多环境 IaC 架构,从代码仓库到状态后端的完整数据流。

多环境 IaC 架构总览 多环境 IaC 架构总览(Directory 模式) Git 代码仓库 environments/{dev,staging,prod} CI/CD 流水线 Plan / Apply / Destroy 环境隔离层(独立目录 + 独立状态文件) Dev 环境 terraform.tfvars (dev) backend.tf (dev-state) 资源:t3.small, 1 AZ 标签:env=dev Staging 环境 terraform.tfvars (staging) backend.tf (staging-state) 资源:t3.medium, 2 AZ 标签:env=staging Prod 环境 terraform.tfvars (prod) backend.tf (prod-state) 资源:m5.large, 3 AZ 标签:env=prod 状态后端(S3 / Azure Storage / GCS) 状态锁定(DynamoDB / Blob Lease) 说明:每个环境拥有独立的变量文件、后端配置和状态文件,实现完全隔离。CI/CD 流水线根据分支或参数选择目标环境目录执行。

2.7 状态文件管理与隔离

状态文件(State)是 IaC 的核心资产,记录了所有已管理资源的元数据与依赖关系。多环境管理必须确保状态文件的隔离性与安全性。

  • 远程后端: 禁止使用本地状态文件。必须使用 S3、Azure Storage Account 或 GCS 等远程后端。
  • 状态锁定: 启用 DynamoDB(AWS)、Blob Lease(Azure)或 Object Versioning(GCS)防止并发写入。
  • 环境级 Key: 每个环境使用独立的 State Key,如 env:dev/terraform.tfstate。
  • 敏感信息加密: 启用服务端加密(SSE-S3、Azure SSE)或客户管理密钥(CMK)。
# backend.tf (dev 环境示例)
terraform {
  backend "s3" {
    bucket         = "my-company-tfstate"
    key            = "env:dev/terraform.tfstate"
    region         = "us-east-1"
    dynamodb_table = "tfstate-lock"
    encrypt        = true
  }
}
SRE 最佳实践: 将状态文件视为“基础设施的数据库”。定期执行 terraform state list 审计资源,并使用 terraform state rm 谨慎处理废弃资源。建议在 CI/CD 中集成状态文件一致性检查(如 terraform validate + terraform plan -detailed-exitcode)。

2.8 多环境参数配置对比

下表总结了不同环境在参数配置上的典型差异,帮助团队快速建立配置基线。

配置项 Dev Staging Prod
实例规格 t3.small t3.medium m5.large
副本数 1 2 3
数据库实例 db.t3.micro db.t3.small db.r5.large (Multi-AZ)
备份策略 无 每日快照 每日快照 + 跨区域复制
监控告警 基础健康检查 详细指标告警 全量告警 + PagerDuty 集成
日志保留 7 天 30 天 90 天(合规审计)

2.9 多环境 IaC 工作流对比

下图对比了 Terraform 与 Pulumi 在多环境管理中的核心工作流差异,帮助团队根据技术栈选择合适工具。

Terraform vs Pulumi 多环境工作流 Terraform vs Pulumi 多环境工作流对比 Terraform 工作流 1. 编写 HCL 配置(.tf 文件) 2. terraform init (初始化 Provider) 3. terraform plan (预览变更) 4. terraform apply (执行变更) Pulumi 工作流 1. 编写 TypeScript/Python 代码 2. pulumi stack init (创建 Stack) 3. pulumi preview (预览变更) 4. pulumi up (执行变更) 核心差异:Terraform 通过 Workspace 管理环境,Pulumi 通过 Stack 管理环境;Pulumi 支持编程语言特性(循环、函数、类)实现更灵活的抽象。

2.10 本章小结

本章系统介绍了 Terraform 与 Pulumi 的核心概念,并深入探讨了多环境管理的两种主流策略(Workspace vs. Directory)及其参数配置方法。关键要点如下:

  • 声明式 IaC 是 SRE 实现基础设施可靠性的基石,通过 Plan 预览降低变更风险。
  • Directory 模式 是生产环境推荐的多环境管理方案,通过目录结构强制隔离状态文件与配置。
  • 参数化 是复用代码的关键,通过变量文件(terraform.tfvars)和环境变量实现环境差异。
  • 状态文件 必须使用远程后端 + 锁定机制,确保隔离性与并发安全。
  • 工具选型 应基于团队技术栈:运维团队优先 Terraform,开发者团队优先 Pulumi。