2. Terraform 基础回顾:Provider、Resource、Data Source、State、Module 核心概念
在构建 SLI 口径采集管线之前,必须牢固掌握 Terraform 的五大核心抽象。这些抽象构成了声明式基础设施管理的全部基础,也是后续模块化设计与多环境交付的基石。
2.1 Provider:基础设施的驱动层
Provider 是 Terraform 与目标平台之间的适配器。每个 Provider 负责定义一组可用的 Resource 和 Data Source,并封装与平台 API 的认证、请求、重试逻辑。
| 属性 | 说明 | 示例 |
|---|---|---|
| 来源 | 官方 registry.terraform.io 或私有镜像 | hashicorp/aws |
| 版本约束 | 通过 required_providers 锁定大版本 |
~> 5.0 |
| 认证方式 | 环境变量、静态凭证、Assume Role、OIDC | AWS_PROFILE |
| 别名 | 同一 Provider 多区域/多账号配置 | provider "aws" { alias = "us-east" } |
SLI 管线场景: 采集管线通常跨云(AWS + GCP)或跨账号(生产/观测账号)。通过 Provider 别名机制,可以在同一个配置中管理多个区域的采集目标与一个中央的观测存储。
2.2 Resource:基础设施的原子单元
Resource 是 Terraform 管理的核心对象。每个 Resource 对应一个真实的基础设施组件——一台虚拟机、一个 S3 存储桶、一个 Prometheus 实例、一个 Grafana 数据源。
# 声明一个 AWS S3 存储桶作为 SLI 原始日志的暂存区
resource "aws_s3_bucket" "sli_raw_logs" {
bucket = "sli-raw-logs-production"
force_destroy = false
tags = {
Environment = "production"
ManagedBy = "terraform"
Purpose = "sli-collection"
}
}
- 资源地址:
aws_s3_bucket.sli_raw_logs,在配置中唯一标识该资源。 - 参数:
bucket、force_destroy等由 Provider 定义的 Schema。 - 元参数:
depends_on、count、for_each、lifecycle控制资源行为。
常见陷阱: Resource 的
id 在 apply 之后才确定。不要在同一个配置中依赖尚未创建的资源的 id 作为字符串字面量,应使用属性引用 aws_s3_bucket.sli_raw_logs.id。
2.3 Data Source:只读的查询接口
Data Source 用于读取已有基础设施的信息,而不创建或修改任何资源。在 SLI 管线中,Data Source 常用于获取已有的 VPC、子网、KMS 密钥、Prometheus 端点等。
# 查询已有的 VPC,用于部署采集器
data "aws_vpc" "selected" {
tags = {
Environment = "production"
Purpose = "observability"
}
}
# 引用 Data Source 的属性
resource "aws_security_group" "collector_sg" {
vpc_id = data.aws_vpc.selected.id
# ...
}
| 对比维度 | Resource | Data Source |
|---|---|---|
| 副作用 | 创建/更新/删除基础设施 | 纯读取,无副作用 |
| 生命周期 | 受 Terraform State 管理 | 每次 plan/apply 时重新查询 |
| 典型用途 | 部署采集器、存储桶、告警规则 | 获取已有网络、证书、镜像 ID |
| 依赖关系 | 可被其他资源引用 | 可被资源引用,但不产生反向依赖 |
2.4 State:基础设施的真相映射
State 文件是 Terraform 的核心状态数据库,记录了每个 Resource 的当前属性与 Terraform 配置之间的映射关系。没有 State,Terraform 无法知道哪些资源已被管理。
- 本地 State:
terraform.tfstate,仅适用于单机实验。 - 远程 State:S3 + DynamoDB、Terraform Cloud、Consul 等,支持团队协作与状态锁定。
- State 内容:每个 Resource 的
id、所有属性值、依赖关系、元数据。 - 敏感数据:State 中可能包含密码、密钥,必须加密存储并限制访问。
SLI 管线最佳实践: 使用 S3 作为 State 后端,DynamoDB 实现状态锁定。每个环境(dev/staging/production)使用独立的 State 文件路径,避免环境间互相污染。
# backend.tf
terraform {
backend "s3" {
bucket = "terraform-state-sli-pipeline"
key = "env:/${terraform.workspace}/sli-collection.tfstate"
region = "us-east-1"
dynamodb_table = "terraform-state-lock"
encrypt = true
}
}
2.5 Module:可复用的配置封装
Module 是 Terraform 中实现代码复用与抽象的核心机制。一个 Module 可以包含多个 Resource、Data Source、变量和输出,对外暴露简洁的接口。
# 调用一个 SLI 采集器模块
module "sli_collector" {
source = "./modules/sli-collector"
environment = "production"
vpc_id = data.aws_vpc.selected.id
subnet_ids = data.aws_subnets.private.ids
sli_metrics_bucket = aws_s3_bucket.sli_raw_logs.id
collector_version = "2.1.0"
}
# 模块输出
output "collector_endpoint" {
value = module.sli_collector.endpoint
}
| Module 特性 | 说明 |
|---|---|
| 输入变量 | 通过 variable 定义,调用时传入 |
| 输出值 | 通过 output 暴露内部资源属性 |
| 本地/远程源 | ./modules/xxx 或 git::https://... 或 Terraform Registry |
| 版本管理 | 远程 Module 支持语义版本约束 ~> 1.0 |
| 封装粒度 | 按职责拆分:网络层、采集层、存储层、告警层 |
本课程的核心方法: 将 SLI 口径采集管线拆解为 4 个独立 Module——
sli-collector、sli-storage、sli-alerting、sli-dashboard。每个 Module 有明确的输入输出,支持独立测试与版本演进。
2.6 核心概念在 SLI 管线中的映射
将上述五个概念映射到 SLI 口径采集管线的具体组件,可以更直观地理解它们的作用:
| Terraform 概念 | SLI 管线中的对应 | 示例 |
|---|---|---|
| Provider | AWS、GCP、Prometheus、Grafana 平台驱动 | hashicorp/aws、grafana/grafana |
| Resource | 采集器实例、S3 存储桶、Prometheus 规则、Grafana 仪表盘 | aws_instance.collector |
| Data Source | 查询已有 VPC、子网、证书、KMS 密钥 | data.aws_subnets.private |
| State | 记录每个采集器、存储桶、告警规则的当前属性 | S3 + DynamoDB 远程 State |
| Module | 采集器模块、存储模块、告警模块、仪表盘模块 | module.sli_collector |