2. Terraform 基础回顾:核心概念与工作流
在深入准入策略与 IDP 自助门户之前,必须夯实 Terraform 的核心知识体系。本章将系统回顾 Provider、Resource、Data Source 三大核心概念,剖析状态文件的作用与风险,并梳理 Init/Plan/Apply 标准工作流。这些基础是理解后续“高风险变更”检测与策略拦截的基石。
2.1 三大核心概念
Terraform 的声明式模型围绕三个抽象层构建:Provider(提供者)、Resource(资源)和 Data Source(数据源)。它们共同构成了基础设施即代码的原子单元。
| 概念 | 作用 | 典型示例 | 生命周期 |
|---|---|---|---|
| Provider | 与目标 API 交互的插件,负责资源 CRUD | aws, azurerm, kubernetes |
全局配置,版本锁定 |
| Resource | 被管理的具体基础设施对象 | aws_instance, azurerm_virtual_network |
创建、更新、删除(由 Terraform 管理) |
| Data Source | 只读查询已有基础设施信息 | aws_ami, azurerm_subnet |
仅读取,不管理 |
关键区别: Resource 会创建/修改/删除真实对象,属于“有状态”操作;Data Source 仅查询现有对象,不产生变更。在准入策略中,Resource 的变更操作是高风险审查的重点。
2.1.1 Provider 声明与版本约束
terraform {
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 5.0"
}
}
}
provider "aws" {
region = "us-east-1"
}
Provider 的 source 和 version 约束必须显式声明。版本锁定是避免意外升级导致兼容性问题的第一道防线。
2.1.2 Resource 定义与依赖
resource "aws_instance" "web" {
ami = data.aws_ami.ubuntu.id
instance_type = "t3.micro"
tags = {
Name = "WebServer"
}
}
resource "aws_security_group" "web_sg" {
name = "web-sg"
ingress {
from_port = 443
to_port = 443
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
}
资源之间通过隐式引用(data.aws_ami.ubuntu.id)或显式 depends_on 建立依赖图。Terraform 自动解析依赖顺序,确保创建/销毁按正确次序执行。
2.1.3 Data Source 查询模式
data "aws_ami" "ubuntu" {
most_recent = true
owners = ["099720109477"]
filter {
name = "name"
values = ["ubuntu/images/hvm-ssd/ubuntu-22.04-*"]
}
}
Data Source 在 plan 阶段读取,结果可用于 Resource 的配置参数。它不会在状态文件中创建新条目,但会缓存读取结果。
2.2 状态文件(State File)
状态文件是 Terraform 的“真相来源”(Source of Truth),它记录了当前管理的所有资源及其属性映射。状态文件的核心作用包括:
- 资源映射: 将配置中的逻辑资源 ID 与云上真实资源 ID 关联。
- 性能优化: 缓存资源属性,避免每次
plan都调用全部 API。 - 依赖解析: 存储资源间的依赖关系,支持并行操作。
- 团队协作: 远程状态后端(如 S3 + DynamoDB)支持锁机制,防止并发冲突。
高风险警示: 状态文件包含敏感信息(如密码、密钥、连接字符串)。在 IDP 自助门户场景中,必须对状态文件实施访问控制、加密存储和审计日志。状态文件损坏或泄露可能导致基础设施失控。
2.2.1 状态文件结构示例
{
"version": 4,
"terraform_version": "1.6.0",
"resources": [
{
"module": "root",
"mode": "managed",
"type": "aws_instance",
"name": "web",
"provider": "provider[\"registry.terraform.io/hashicorp/aws\"]",
"instances": [
{
"attributes": {
"id": "i-0abcd1234efgh5678",
"ami": "ami-0c55b159cbfafe1f0",
"instance_type": "t3.micro"
}
}
]
}
]
}
2.2.2 本地 vs 远程状态对比
| 维度 | 本地状态 | 远程状态 |
|---|---|---|
| 存储位置 | terraform.tfstate(本地文件) |
S3、Azure Storage、Consul 等 |
| 锁机制 | 无锁,手动防冲突 | DynamoDB / Blob Lease 自动锁 |
| 团队协作 | 不适用,易覆盖 | 支持多人并行,状态一致 |
| 安全性 | 依赖本地文件权限 | 支持加密、访问策略、审计 |
| 适用场景 | 个人学习、实验 | 生产环境、团队协作 |
2.3 标准工作流:Init → Plan → Apply
Terraform 的工作流是声明式基础设施管理的核心循环。每个阶段都有明确的输入、输出和检查点。
2.3.1 工作流步骤详解
- Init(初始化): 下载 Provider 插件、初始化后端、加载模块。必须首先执行。
- Plan(计划): 对比配置与状态文件,生成执行计划。显示哪些资源将被创建、修改或删除。
- Apply(应用): 执行计划中的变更操作,更新状态文件。需要人工确认或自动批准。
2.3.2 命令执行示例
# 1. 初始化
terraform init
# 2. 生成执行计划
terraform plan -out=tfplan
# 3. 查看计划摘要
terraform show tfplan
# 4. 应用变更
terraform apply tfplan
最佳实践: 在 CI/CD 流水线中,
plan 阶段应作为准入检查点。高风险变更(如删除资源、开放 0.0.0.0/0 安全组)应在 plan 输出中被策略引擎捕获并阻止,而不是等到 apply 阶段才拦截。
2.4 核心概念与工作流总结
回顾本章要点:
- Provider 是 Terraform 与云 API 的桥梁,必须版本锁定。
- Resource 管理基础设施对象,Data Source 只读查询,两者共同构成配置主体。
- 状态文件 是基础设施的真相来源,必须远程存储、加密、加锁。
- Init → Plan → Apply 是标准工作流,Plan 阶段是准入策略的最佳插入点。