2. Terraform 基础回顾:核心概念与工作流
在深入制品供应链误差预算台账的自动化部署之前,必须牢固掌握 Terraform 的核心概念与标准工作流。本章将系统回顾 Provider、Resource、Data Source 三大核心抽象,剖析状态文件的管理机制,并拆解 init / plan / apply / destroy 的完整生命周期。
2.1 核心概念:Provider、Resource、Data Source
Terraform 通过声明式配置管理基础设施,其抽象模型由三个基本构件组成:
| 概念 | 作用 | 类比 | 关键属性 |
|---|---|---|---|
| Provider | 连接 Terraform 与目标平台(云、SaaS、本地系统)的插件 | 驱动程序 | source、version、region、endpoint |
| Resource | 声明式定义“要创建或管理”的具体基础设施对象 | 名词/实体 | type、name、arguments、attributes |
| Data Source | 只读查询已有基础设施的属性和状态 | 只读视图 | type、name、query arguments |
供应链安全视角: Provider 的版本锁定和来源验证是供应链安全的第一道防线。始终使用
required_providers 块指定 source 和 version,避免隐式拉取未审计的 Provider 二进制。
2.1.1 Provider 声明与版本约束
Provider 必须在 terraform 块中显式声明,并通过 required_providers 锁定来源与版本范围:
terraform {
required_version = ">= 1.5.0"
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 5.0"
}
random = {
source = "hashicorp/random"
version = ">= 3.5, < 4.0"
}
}
}
provider "aws" {
region = "us-east-1"
}
最佳实践: 使用
~> 5.0 语义版本约束,允许补丁升级但阻止大版本变更。在制品供应链场景中,Provider 版本变更应纳入变更评审流程。
2.1.2 Resource 声明与依赖
Resource 是 Terraform 配置的核心。每个 Resource 块定义一个基础设施对象,并通过隐式引用或 depends_on 建立依赖关系:
resource "aws_s3_bucket" "sbom_archive" {
bucket = "supply-chain-sbom-${random_id.suffix.hex}"
force_destroy = true
}
resource "random_id" "suffix" {
byte_length = 4
}
resource "aws_s3_bucket_versioning" "sbom_versioning" {
bucket = aws_s3_bucket.sbom_archive.id
versioning_configuration {
status = "Enabled"
}
}
上述代码中,aws_s3_bucket_versioning 通过 aws_s3_bucket.sbom_archive.id 隐式依赖 S3 桶;random_id 则通过 ${random_id.suffix.hex} 被桶名称引用。
2.1.3 Data Source 查询已有资源
Data Source 用于读取外部或已存在的基础设施信息,不创建新资源:
data "aws_iam_policy_document" "sbom_access" {
statement {
effect = "Allow"
actions = ["s3:GetObject"]
resources = ["${aws_s3_bucket.sbom_archive.arn}/*"]
}
}
data "aws_caller_identity" "current" {}
output "account_id" {
value = data.aws_caller_identity.current.account_id
}
常见陷阱: Data Source 在
plan 阶段读取实时状态,如果依赖的 Resource 尚未创建,会导致查询失败。确保 Data Source 的依赖资源已存在或使用 depends_on 显式声明。
2.2 状态文件管理
状态文件(terraform.tfstate)是 Terraform 的核心数据存储,它建立了配置代码与实际基础设施之间的映射关系。状态文件记录了每个 Resource 的元数据、属性值、依赖关系以及 Provider 版本信息。
2.2.1 状态文件的作用
- 映射绑定: 将配置中的
resource "type" "name"与云平台中的真实资源 ID 关联。 - 性能优化: 避免每次
plan/apply都全量调用 API 列举所有资源。 - 依赖解析: 记录资源间的依赖顺序,确保创建/销毁顺序正确。
- 差异计算: 对比状态文件与配置文件的差异,生成执行计划。
2.2.2 远程状态存储
在团队协作和自动化部署中,必须使用远程后端(Backend)存储状态文件,避免本地文件冲突和丢失:
terraform {
backend "s3" {
bucket = "terraform-state-prod"
key = "supply-chain/sbom-budget.tfstate"
region = "us-east-1"
encrypt = true
dynamodb_table = "terraform-state-lock"
}
}
| 后端类型 | 适用场景 | 锁机制 | 供应链安全要点 |
|---|---|---|---|
| S3 + DynamoDB | AWS 原生,团队协作 | DynamoDB 悲观锁 | 启用 SSE-S3/KMS 加密,限制 IAM 访问 |
| AzureRM Storage | Azure 环境 | Blob Lease 锁 | 启用基础设施加密,使用 RBAC |
| GCS | GCP 环境 | Cloud Storage Object Hold | 使用 CMEK 加密,审计日志 |
| Terraform Cloud | 全托管,企业级 | 内置锁 + 运行队列 | VCS 集成,策略即代码 (OPA) |
供应链安全风险: 状态文件包含敏感信息(如数据库密码、密钥材料、资源 ARN)。切勿将
.tfstate 文件提交到版本控制;始终启用远程后端的加密和访问审计。
2.3 标准工作流:init / plan / apply / destroy
Terraform 的工作流是声明式基础设施管理的核心循环。每个命令在供应链自动化流水线中都有明确的角色。
2.3.1 工作流步骤详解
| 步骤 | 命令 | 核心行为 | 供应链场景作用 |
|---|---|---|---|
| 1. 初始化 | terraform init |
下载 Provider 插件、初始化后端、加载模块 | 验证 Provider 来源哈希,确保供应链完整性 |
| 2. 预览 | terraform plan |
对比配置与状态,生成执行计划 | 审计变更范围,检测配置漂移 |
| 3. 应用 | terraform apply |
执行计划中的创建/更新/删除操作 | 部署 SBOM 存储、签名服务、预算台账 |
| 4. 销毁 | terraform destroy |
删除所有被管理的资源 | 清理测试环境,回收供应链资源 |
2.3.2 完整工作流示例
# 1. 初始化:安装 Provider,配置后端
terraform init
# 2. 预览变更:输出计划,人工或自动审核
terraform plan -out=tfplan
# 3. 应用变更:执行计划,更新状态
terraform apply tfplan
# 4. (可选)销毁资源:清理环境
terraform destroy --auto-approve
CI/CD 集成要点: 在制品供应链流水线中,
terraform plan 的输出应作为变更评审的附件;terraform apply 应绑定到审批门禁;terraform destroy 仅用于临时环境,生产环境需启用删除保护。
2.4 本章小结
- Provider 是 Terraform 与目标平台之间的安全桥梁,必须锁定来源和版本。
- Resource 声明期望状态,Data Source 读取现有状态,两者共同构成配置的读写模型。
- 状态文件 是基础设施的真理来源,必须使用远程后端 + 加密 + 锁机制。
- init → plan → apply → destroy 是标准工作流,每个阶段在供应链自动化中都有对应的安全控制点。