4. Terraform 入门:环境配置与第一个脚本
Terraform 是 HashiCorp 公司推出的基础设施即代码工具,采用声明式配置语言 HCL(HashiCorp Configuration Language)。它通过“期望状态”模型驱动基础设施的生命周期管理:用户描述目标状态,Terraform 自动计算并执行变更路径。本章将带你完成从安装、初始化到编写第一个脚本的完整闭环。
4.1 Terraform 核心概念
在动手之前,先建立三个关键认知:
| 概念 | 说明 | 类比 |
|---|---|---|
| Provider | 与目标云平台/服务交互的插件,负责 API 翻译与资源生命周期管理 | 数据库驱动 |
| Resource | 基础设施中的具体组件,如虚拟机、VPC、DNS 记录 | 数据库中的表记录 |
| State | 记录当前已管理资源的映射文件,Terraform 据此计算变更 | 数据库快照 |
关键原则:Terraform 只管理 State 中记录的资源。手动在控制台创建的资源不会被 Terraform 感知,除非通过 import 导入。
4.2 安装与版本选择
Terraform 以单一二进制文件分发,安装过程极简。推荐使用版本管理器 tfenv 或 tenv 来切换多版本。
4.2.1 安装方式对比
| 方式 | 适用场景 | 命令示例 |
|---|---|---|
| 包管理器(macOS/Linux) | 单版本、快速上手 | brew install terraform |
| 手动下载 | 离线环境、指定版本 | 从 releases.hashicorp.com 下载并放入 PATH |
| tfenv(推荐) | 多项目多版本切换 | tfenv install 1.9.8 |
4.2.2 验证安装
terraform --version
# 输出示例:Terraform v1.9.8 on darwin_arm64
版本兼容性注意:Provider 与 Terraform 核心版本有对应关系。1.5.x 以上版本支持
import 代码生成和 check 块,建议新项目直接使用 1.6+。
4.3 Provider 配置:声明与初始化
Provider 是 Terraform 与目标平台之间的桥梁。每个 Provider 需要声明来源和版本约束。
4.3.1 Provider 声明格式
terraform {
required_version = ">= 1.6"
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 5.0"
}
random = {
source = "hashicorp/random"
version = "3.6.0"
}
}
}
provider "aws" {
region = "ap-northeast-1"
}
| 参数 | 含义 | 推荐做法 |
|---|---|---|
source |
Provider 的注册地址,格式为 命名空间/类型 |
始终使用官方命名空间(如 hashicorp) |
version |
版本约束,支持 >=、~>、!= 等 |
使用 ~> x.y 锁定次要版本,避免意外升级 |
region |
Provider 级别的默认区域 | 通过变量传入,不硬编码 |
4.3.2 terraform init 执行流程
terraform init 是每个 Terraform 项目的第一个命令,完成以下工作:
- 读取
required_providers块 - 从 Terraform Registry 下载 Provider 插件到
.terraform/目录 - 创建或更新
.terraform.lock.hcl锁定文件 - 初始化后端(Backend)配置(如远程 State 存储)
- 加载模块(Module)
# 执行初始化
terraform init
# 输出关键行示例:
# - Initializing the backend...
# - Initializing provider plugins...
# - Finding hashicorp/aws versions matching "~> 5.0"...
# - Installing hashicorp/aws v5.82.2...
# - Terraform has been successfully initialized!
最佳实践:将
.terraform.lock.hcl 提交到版本控制。它确保团队所有成员使用完全相同的 Provider 版本,避免“在我机器上能跑”的问题。
4.4 第一个 Terraform 脚本:创建 AWS EC2 实例
以下脚本创建一个带有随机名称的 AWS EC2 实例,展示 Terraform 的核心工作流。
4.4.1 完整脚本
# main.tf
terraform {
required_version = ">= 1.6"
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 5.0"
}
random = {
source = "hashicorp/random"
version = "3.6.0"
}
}
}
provider "aws" {
region = "ap-northeast-1"
}
resource "random_pet" "server" {
length = 2
}
resource "aws_instance" "web" {
ami = "ami-0e4e4b2f188e9e1e1" # Amazon Linux 2023 in ap-northeast-1
instance_type = "t3.micro"
tags = {
Name = "web-${random_pet.server.id}"
}
}
output "instance_id" {
value = aws_instance.web.id
}
output "public_ip" {
value = aws_instance.web.public_ip
}
4.4.2 工作流步骤
| 步骤 | 命令 | 说明 |
|---|---|---|
| 1. 初始化 | terraform init |
下载 Provider,初始化后端 |
| 2. 格式化 | terraform fmt |
自动格式化 HCL 代码,保持风格一致 |
| 3. 验证 | terraform validate |
检查语法和配置错误 |
| 4. 预览 | terraform plan |
显示将要创建/修改/删除的资源清单 |
| 5. 应用 | terraform apply |
执行变更,创建基础设施 |
| 6. 销毁 | terraform destroy |
清理所有被管理的资源 |
4.4.3 plan 输出解读
terraform plan
# 输出关键部分:
Terraform will perform the following actions:
# random_pet.server will be created
+ resource "random_pet" "server" {
+ id = (known after apply)
+ length = 2
+ separator = "-"
}
# aws_instance.web will be created
+ resource "aws_instance" "web" {
+ ami = "ami-0e4e4b2f188e9e1e1"
+ instance_type = "t3.micro"
+ tags = {
+ "Name" = "web-${random_pet.server.id}"
}
+ (其他属性省略...)
}
Plan: 2 to add, 0 to change, 0 to destroy.
解读技巧:
+ 表示创建,~ 表示修改,- 表示删除。(known after apply) 表示该值在 apply 之前无法确定,Terraform 会在执行时计算。
4.5 Terraform 工作流可视化
下图展示了从编写代码到基础设施生效的完整数据流:
4.6 常见问题与避坑指南
问题 1:
原因:网络无法访问 registry.terraform.io,或 Provider source 拼写错误。
解决:配置代理或使用
terraform init 报错 Failed to query available provider packages原因:网络无法访问 registry.terraform.io,或 Provider source 拼写错误。
解决:配置代理或使用
terraform providers mirror 离线缓存。
问题 2:
原因:AWS 凭证未配置或 Provider 未正确读取。
解决:检查环境变量
terraform apply 提示 Error: No valid credential sources found原因:AWS 凭证未配置或 Provider 未正确读取。
解决:检查环境变量
AWS_ACCESS_KEY_ID / AWS_SECRET_ACCESS_KEY,或使用 aws configure 配置。
调试技巧:设置
TF_LOG=DEBUG 环境变量可输出详细日志,定位 API 调用和 State 操作问题。生产环境慎用,日志量较大。
4.7 本章要点总结
- Terraform 使用声明式 HCL 语言,通过 Provider 与云平台交互
terraform init是每个项目的第一个命令,负责下载 Provider 和初始化后端- Provider 配置需指定
source和version,推荐使用~> x.y锁定次要版本 - 标准工作流:
init → fmt → validate → plan → apply - State 文件是 Terraform 的核心资产,记录资源映射关系,必须妥善保管
- 始终在
apply之前执行plan,确认变更符合预期