一句话概述:Terraform 是 HashiCorp 的基础设施即代码(IaC)工具,用 HCL 声明式语言定义云资源(服务器、数据库、网络等),一条命令自动创建/更新/销毁,支持 AWS/Azure/GCP 等 1000+ Provider。
核心知识点表
| 概念 | 白话解释 |
|---|
| IaC | Infrastructure as Code,用代码管理服务器而不是手动点击控制台 |
| HCL | HashiCorp Configuration Language,Terraform 的配置语言 |
| Provider | 提供者,连接具体云平台的插件(如 AWS Provider) |
| Resource | 资源,要创建的基础设施(如服务器、数据库) |
| State | 状态文件,记录已创建资源的当前状态 |
| Module | 模块,可复用的 Terraform 配置包 |
| Plan | 计划,执行前预览将要做的变更 |
安装配置
# macOS
brew install terraform # Homebrew 安装
# Ubuntu/Debian
wget -O - https://apt.releases.hashicorp.com/gpg | sudo gpg --dearmor -o /usr/share/keyrings/hashicorp-archive-keyring.gpg
echo "deb [signed-by=/usr/share/keyrings/hashicorp-archive-keyring.gpg] https://apt.releases.hashicorp.com $(lsb_release -cs) main" | sudo tee /etc/apt/sources.list.d/hashicorp.list
sudo apt update && sudo apt install terraform
# 验证安装
terraform version # 查看版本
配置 AWS Provider(示例)
# 设置 AWS 凭证(环境变量方式)
export AWS_ACCESS_KEY_ID="your-access-key" # AWS 访问密钥
export AWS_SECRET_ACCESS_KEY="your-secret-key" # AWS 秘密密钥
export AWS_DEFAULT_REGION="ap-southeast-1" # 默认区域
基本使用
# main.tf — 创建一台 AWS EC2 服务器
# 定义 Provider(使用哪个云平台)
terraform {
required_providers {
aws = {
source = "hashicorp/aws" # AWS Provider 来源
version = "~> 5.0" # 版本约束
}
}
}
provider "aws" {
region = "ap-southeast-1" # 新加坡区域
}
# 定义 Resource(要创建的资源)
resource "aws_instance" "web" { # 资源类型 + 资源名
ami = "ami-0c55b159cbfafe1f0" # 系统镜像 ID
instance_type = "t2.micro" # 实例规格(免费套餐)
tags = {
Name = "my-web-server" # 实例名称标签
}
}
# 输出(显示创建后的信息)
output "public_ip" {
value = aws_instance.web.public_ip # 输出公网 IP
}
核心工作流
# 1. 初始化(下载 Provider 插件)
terraform init # 首次运行或添加新 Provider 时
# 2. 预览变更(看看要做什么)
terraform plan # 显示将要创建/修改/删除的资源
# 输出示例:Plan: 1 to add, 0 to change, 0 to destroy.
# 3. 应用变更(真正执行)
terraform apply # 创建资源(会再次确认)
terraform apply -auto-approve # 跳过确认直接执行
# 4. 查看当前状态
terraform show # 查看已创建的资源详情
# 5. 销毁资源
terraform destroy # 删除所有已创建的资源
使用变量
# variables.tf — 定义变量
variable "instance_type" {
description = "EC2 实例规格" # 变量描述
type = string # 变量类型
default = "t2.micro" # 默认值
}
variable "instance_count" {
description = "创建服务器数量"
type = number
default = 2
}
# main.tf — 使用变量
resource "aws_instance" "web" {
count = var.instance_count # 引用变量
ami = "ami-xxx"
instance_type = var.instance_type # 引用变量
tags = {
Name = "web-${count.index + 1}" # web-1, web-2
}
}
# 通过命令行传入变量
terraform apply -var="instance_type=t2.small"
# 通过变量文件
# terraform.tfvars
instance_type = "t2.small"
instance_count = 3
terraform apply -var-file="production.tfvars" # 指定变量文件
高级用法
Module(模块复用)
# 使用社区模块创建 VPC
module "vpc" {
source = "terraform-aws-modules/vpc/aws" # 来自 Terraform Registry
version = "5.0.0"
name = "my-vpc"
cidr = "10.0.0.0/16" # VPC 网段
azs = ["ap-southeast-1a", "ap-southeast-1b"]
public_subnets = ["10.0.1.0/24", "10.0.2.0/24"]
private_subnets = ["10.0.3.0/24", "10.0.4.0/24"]
enable_nat_gateway = true # 启用 NAT 网关
}
远程状态存储
# backend.tf — 把状态文件存到 S3(团队协作必须)
terraform {
backend "s3" {
bucket = "my-terraform-state" # S3 桶名
key = "prod/terraform.tfstate" # 状态文件路径
region = "ap-southeast-1"
dynamodb_table = "terraform-locks" # DynamoDB 锁表(防并发)
encrypt = true # 加密存储
}
}
Data Source(查询现有资源)
# 查询最新的 Ubuntu AMI
data "aws_ami" "ubuntu" {
most_recent = true # 最新的
owners = ["099720109477"] # Canonical 官方
filter {
name = "name"
values = ["ubuntu/images/hvm-ssd/ubuntu-*-22.04-amd64-server-*"]
}
}
resource "aws_instance" "web" {
ami = data.aws_ami.ubuntu.id # 使用查询到的 AMI
instance_type = "t2.micro"
}
多环境管理
# 使用 Workspace(工作空间)
terraform workspace new dev # 创建 dev 环境
terraform workspace new prod # 创建 prod 环境
terraform workspace select dev # 切换到 dev
# 或使用不同的 tfvars 文件
terraform apply -var-file="envs/dev.tfvars"
terraform apply -var-file="envs/prod.tfvars"
常见报错
| 报错信息 | 原因 | 解决方案 |
|---|
Error: No valid credential sources | 云平台凭证未配置 | 设置环境变量或 credentials 文件 |
Error: State lock | 状态文件被锁定 | terraform force-unlock LOCK_ID |
Error: Resource already exists | 资源在 Terraform 外创建的 | terraform import 导入现有资源 |
Error: Provider not found | Provider 未安装 | 运行 terraform init |
Error: Cycle detected | 资源间循环依赖 | 重新设计依赖关系 |
速查表
# === 核心命令 ===
terraform init # 初始化
terraform plan # 预览变更
terraform apply # 应用变更
terraform destroy # 销毁资源
terraform show # 查看状态
terraform output # 查看输出
terraform fmt # 格式化代码
terraform validate # 验证配置
terraform import TYPE.NAME ID # 导入现有资源
terraform state list # 列出状态中的资源
# === 文件命名惯例 ===
# main.tf → 主配置
# variables.tf → 变量定义
# outputs.tf → 输出定义
# providers.tf → Provider 配置
# backend.tf → 远程状态配置
# terraform.tfvars → 变量值
同类对比
| 特性 | Terraform | Pulumi | CloudFormation | OpenTofu |
|---|
| 语言 | HCL | 通用语言 | JSON/YAML | HCL |
| 多云 | 1000+ Provider | 多云 | 仅 AWS | 兼容TF |
| 开源 | BSL | Apache 2.0 | 闭源 | MPL 2.0 |
| 状态管理 | 文件/远程 | 自带 | AWS管理 | 文件/远程 |
| 学习曲线 | 中等 | 低(会编程) | 中等 | 中等 |
| 生态 | 最大 | 发展中 | AWS生态 | 兼容TF |
选型建议:多云 IaC 首选 Terraform(生态最成熟,市场占有率 34%);纯 AWS 可以用 CloudFormation;介意 BSL 许可证选 OpenTofu(Terraform 开源分支,100% 兼容)。