2. Terraform 基础回顾:HCL语法、Provider、Resource、Data Source核心概念
在深入配置审计与版本控制之前,必须牢固掌握 Terraform 的四大核心支柱:HCL 语法、Provider、Resource 与 Data Source。它们是所有基础设施即代码(IaC)脚本的基石,也是后续自动化审计规则的目标对象。
2.1 HCL 语法:声明式配置语言
HashiCorp Configuration Language(HCL)是 Terraform 的原生语言,采用声明式风格——你描述“最终状态”,Terraform 负责计算“如何到达”。
2.1.1 基础语法结构
# 块类型 "块标签" {
# 参数名 = 参数值
# }
resource "aws_instance" "web" {
ami = "ami-0c55b159cbfafe1f0"
instance_type = "t2.micro"
tags = {
Name = "WebServer"
}
}
| 语法元素 | 说明 | 示例 |
|---|---|---|
| 块(Block) | 顶级结构单元,由类型和标签组成 | resource "aws_instance" "web" |
| 参数(Argument) | 键值对,赋值给块内的属性 | ami = "ami-xxx" |
| 表达式(Expression) | 引用、运算或函数调用 | var.instance_count |
| 注释 | # 或 // 单行,/* */ 多行 |
# 这是注释 |
💡 审计要点:HCL 对缩进不敏感,但团队应约定统一的缩进风格(推荐 2 空格),否则
terraform fmt 会频繁产生 diff,干扰版本控制历史。
2.1.2 变量与输出
# variables.tf
variable "region" {
description = "AWS 部署区域"
type = string
default = "us-east-1"
}
# outputs.tf
output "instance_ip" {
value = aws_instance.web.public_ip
description = "Web 服务器的公网 IP"
}
2.2 Provider:云平台适配层
Provider 是 Terraform 与目标云平台(AWS、Azure、GCP 等)之间的桥梁。它负责 API 认证、资源生命周期管理和状态同步。
2.2.1 Provider 声明与版本约束
terraform {
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 5.0" # 语义版本约束
}
}
}
provider "aws" {
region = var.region
# 认证方式:环境变量 / 共享凭证文件 / IAM 角色
}
| 版本约束符号 | 含义 | 示例 |
|---|---|---|
>= 1.2.0 |
大于等于指定版本 | 允许 1.2.0 及以上 |
~> 5.0 |
只允许补丁版本升级 | 5.0.x,不允许 5.1.0 |
>= 1.0, < 2.0 |
范围约束 | 1.x 系列任意版本 |
⚠️ 安全警告:Provider 版本锁定是供应链安全的第一道防线。未指定版本约束时,
terraform init 会拉取最新版,可能导致非预期的 API 变更或兼容性断裂。审计规则应强制所有 Provider 声明 version 参数。
2.3 Resource:基础设施的原子单元
Resource 是 Terraform 中最核心的块,代表一个真实的基础设施组件——虚拟机、子网、安全组、DNS 记录等。每个 Resource 块定义了一个期望状态。
2.3.1 Resource 语法与依赖
resource "aws_security_group" "web_sg" {
name = "web-sg"
description = "Allow HTTP and SSH"
ingress {
from_port = 80
to_port = 80
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
ingress {
from_port = 22
to_port = 22
protocol = "tcp"
cidr_blocks = ["10.0.0.0/8"]
}
egress {
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
}
}
resource "aws_instance" "web" {
ami = "ami-0c55b159cbfafe1f0"
instance_type = "t2.micro"
vpc_security_group_ids = [aws_security_group.web_sg.id] # 隐式依赖
}
2.3.2 Resource 元参数
| 元参数 | 用途 | 审计关注点 |
|---|---|---|
count |
创建多个相同实例 | 避免硬编码数量,应使用变量 |
for_each |
从 map 或 set 创建差异化实例 | 确保 key 唯一且可预测 |
depends_on |
显式声明依赖关系 | 过度使用可能掩盖设计缺陷 |
lifecycle |
控制创建/更新/删除行为 | prevent_destroy 用于关键资源 |
provider |
指定非默认 Provider 别名 | 多区域部署时必用 |
2.4 Data Source:读取外部状态
Data Source 用于读取已有基础设施或外部数据,而不创建新资源。它让 Terraform 能够查询当前环境状态,实现数据驱动的配置。
2.4.1 Data Source 语法
# 查询现有 VPC
data "aws_vpc" "default" {
default = true
}
# 查询最新的 Amazon Linux 2 AMI
data "aws_ami" "amazon_linux" {
most_recent = true
owners = ["amazon"]
filter {
name = "name"
values = ["amzn2-ami-hvm-*-x86_64-gp2"]
}
}
resource "aws_instance" "from_data" {
ami = data.aws_ami.amazon_linux.id
instance_type = "t2.micro"
subnet_id = data.aws_subnet.selected.id
}
🔍 审计视角:Data Source 的查询结果在
terraform plan 阶段确定。如果 Data Source 依赖的资源尚未创建,会导致 plan 失败。审计规则应检查 Data Source 的 depends_on 是否完整。
2.5 核心概念关系图
下图展示了 HCL、Provider、Resource 与 Data Source 之间的协作关系:
2.6 核心概念对比
| 概念 | 关键字 | 作用 | 是否修改基础设施 | 依赖方向 |
|---|---|---|---|---|
| Provider | provider |
API 认证与资源类型注册 | 否(仅配置) | Resource / Data Source 依赖 Provider |
| Resource | resource |
创建、更新、删除基础设施 | 是 | 可引用其他 Resource 和 Data Source |
| Data Source | data |
只读查询已有资源 | 否 | 可被 Resource 引用 |
| HCL | — | 所有块的声明语法基础 | — | — |
2.7 常见陷阱与审计规则
- 陷阱 1:Provider 版本未锁定 —— 导致
terraform init拉取不兼容版本。审计规则:检查required_providers块中是否包含version约束。 - 陷阱 2:Resource 硬编码敏感值 —— 密码、密钥直接写在
.tf文件中。审计规则:禁止password、secret_key等参数使用字面量字符串。 - 陷阱 3:Data Source 未指定
most_recent—— 查询 AMI 时可能返回多个结果导致失败。审计规则:对aws_ami等 Data Source 强制要求most_recent = true。 - 陷阱 4:隐式依赖循环 —— Resource A 引用 B,B 又引用 A,导致
terraform plan死锁。审计规则:使用terraform graph生成依赖图,人工审查循环引用。
📌 课程关联:本章回顾的 HCL、Provider、Resource、Data Source 是后续“配置审计规则引擎”的四个扫描维度。第 5 章将针对每个维度编写具体的 OPA / Sentinel 策略。