Terraform 核心概念与 HCL 语法基础
Terraform 是一个基础设施即代码(IaC)工具,它通过声明式配置语言(HCL)来定义、部署和管理云资源。在深入质量门禁集成之前,必须牢固掌握其三大核心支柱:Provider、Resource 和 State。本章将系统回顾这些概念,并梳理 HCL 语法的基础要素。
1. 三大核心概念
Terraform 的工作流程围绕三个核心抽象展开,它们共同构成了配置管理的闭环。
| 概念 | 角色 | 关键说明 |
|---|---|---|
| Provider | 插件 / 驱动 | 负责与目标 API(如 AWS、Azure、Kubernetes)通信。每个 Provider 定义了一组可用的资源和数据源。 |
| Resource | 基础设施对象 | 描述一个具体的基础设施组件,例如一台虚拟机、一个 DNS 记录、一个 Kubernetes 命名空间。是配置的最小单元。 |
| State | 状态映射文件 | 记录 Terraform 管理的所有资源及其当前属性。用于将真实世界资源与配置代码进行映射,是执行变更的依据。 |
required_providers 的版本约束,避免因 Provider 升级导致非预期的资源变更。
2. HCL 语法基础
HCL(HashiCorp Configuration Language)是 Terraform 的专用语言。其设计目标是既对人类可读,又能被机器高效解析。以下是最常用的语法结构。
2.1 块(Block)与参数(Argument)
块是 HCL 的基本结构单元,用于定义 Provider、Resource 等逻辑单元。参数是块内部的键值对。
# Provider 块:指定云提供商及认证信息
provider "aws" {
region = "us-east-1"
}
# Resource 块:定义一个 AWS EC2 实例
resource "aws_instance" "web_server" {
ami = "ami-0c55b159cbfafe1f0"
instance_type = "t2.micro"
tags = {
Name = "QualityGate-Example"
}
}
2.2 表达式与引用
Terraform 支持丰富的表达式,用于在资源之间建立依赖和传递数据。最常见的引用方式是 <资源类型>.<本地名称>.<属性>。
# 引用上一个资源块中定义的实例 ID
output "instance_id" {
value = aws_instance.web_server.id
}
# 使用字符串插值
resource "aws_eip" "ip" {
instance = aws_instance.web_server.id
vpc = true
}
2.3 变量(Variable)与输出(Output)
变量使配置可复用,输出则用于向外部暴露关键信息。
| 元素 | 关键字 | 用途 |
|---|---|---|
| 输入变量 | variable |
从外部(CLI、文件、环境变量)传入参数,实现配置参数化。 |
| 局部值 | locals |
在模块内部定义中间计算值,简化重复表达式。 |
| 输出值 | output |
将资源属性暴露给用户或作为其他模块的输入。 |
# 定义输入变量
variable "instance_count" {
description = "Number of instances to create"
type = number
default = 1
}
# 定义局部值
locals {
instance_name = "app-server-${var.instance_count}"
}
# 定义输出值
output "public_ip" {
value = aws_eip.ip.public_ip
}
3. State 文件详解
State 是 Terraform 的“大脑”。它存储了所有被管理资源的元数据,使得 Terraform 能够知道哪些资源属于当前配置,以及如何增量更新。
- 默认存储:本地文件
terraform.tfstate。 - 远程存储(推荐):使用 S3、Azure Storage、Consul 等后端。这是团队协作和 CI/CD 流水线的基础。
- 敏感数据:State 文件可能包含密码、密钥等敏感信息。必须对 State 文件进行加密存储和访问控制。
terraform.tfstate 文件提交到公开的 Git 仓库。始终使用远程后端并启用加密。对于敏感值,考虑使用 sensitive = true 标记输出变量。
4. Provider 配置与版本管理
Provider 是 Terraform 与外部 API 之间的桥梁。在 terraform {} 块中声明所需 Provider 及其版本约束,是保证环境可复现的第一步。
terraform {
required_version = ">= 1.5.0"
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 5.0"
}
kubernetes = {
source = "hashicorp/kubernetes"
version = ">= 2.20"
}
}
}
# 配置 Provider 的认证方式
provider "aws" {
region = var.aws_region
}
>= 1.0:版本大于等于 1.0~> 5.0:只允许补丁版本升级(如 5.0.x),不允许次版本升级(如 5.1.0)>= 2.20, < 3.0:范围约束,锁定在 2.x 系列
5. Resource 依赖与生命周期
Terraform 会自动分析资源之间的引用关系,构建依赖图。显式依赖可以通过 depends_on 声明,用于处理隐式引用无法覆盖的场景。
resource "aws_security_group" "sg" {
name = "allow_http"
ingress {
from_port = 80
to_port = 80
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
}
resource "aws_instance" "web" {
ami = "ami-123456"
instance_type = "t2.micro"
# 隐式依赖:通过引用 sg.id 建立
vpc_security_group_ids = [aws_security_group.sg.id]
# 显式依赖:当 Terraform 无法自动推断时使用
depends_on = [
aws_security_group.sg
]
}
6. 数据源(Data Source)
数据源用于读取外部或由其他进程管理的基础设施信息,而不创建新资源。这在质量门禁场景中非常有用,例如查询现有 VPC 或 AMI ID。
# 查询最新的 Ubuntu AMI
data "aws_ami" "ubuntu" {
most_recent = true
owners = ["099720109477"] # Canonical
filter {
name = "name"
values = ["ubuntu/images/hvm-ssd/ubuntu-focal-20.04-amd64-server-*"]
}
}
resource "aws_instance" "from_data" {
ami = data.aws_ami.ubuntu.id
instance_type = "t2.micro"
}
7. 常用命令速查
掌握以下命令是日常操作的基础。在质量门禁流水线中,plan 和 apply 是最核心的步骤。
| 命令 | 作用 | 质量门禁场景 |
|---|---|---|
terraform init |
初始化工作目录,下载 Provider 插件 | 流水线第一步,确保环境就绪 |
terraform validate |
检查配置文件语法是否正确 | 基础语法门禁,快速失败 |
terraform plan |
生成执行计划,显示变更内容 | 预览变更,人工审核或自动规则检查 |
terraform apply |
执行计划,创建/更新资源 | 通过门禁后执行变更 |
terraform destroy |
销毁所有被管理的资源 | 清理测试环境 |
terraform plan -out=tfplan 将计划保存到文件,然后 terraform apply tfplan 应用该计划。这可以确保 apply 阶段执行的是经过审核的精确计划,避免因配置漂移导致意外变更。