手动创建虚拟机、配网络、挂磁盘——换个环境全部重来。Terraform 让你用代码定义基础设施,plan 看变化、apply 一键建,destroy 一键拆。
上周在 Dell 3430 上手动创建了 3 台虚拟机给 K3s 集群。每台都要:分配 CPU 内存、挂载磁盘、配置网络桥接、装系统。花了 2 小时。这周想加一台 node,又来一遍?该用 Terraform 了。
Ansible 解决的是“机器已经在了,怎么配置”的问题。Terraform 解决的是“机器本身怎么来”的问题——从虚拟机到网络到存储,全部用代码定义。
IaC 是什么
Infrastructure as Code(基础设施即代码)的核心思想是:用声明式代码描述基础设施的最终状态,工具负责创建和变更。
对比两种方式:
| 维度 |
手动操作 |
IaC(Terraform) |
| 创建 VM |
Web 控制台点 20 下 |
改一行代码,terraform apply |
| 环境复制 |
拍脑袋回忆“上次怎么配的” |
同一份代码跑两次 |
| 变更审计 |
靠记忆和聊天记录 |
Git 提交记录 |
| 销毁资源 |
逐个删除,容易遗漏 |
terraform destroy |
| 团队协作 |
口口相传 |
Git 分支 + Code Review |
安装
# 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
# macOS
brew tap hashicorp/tap && brew install hashicorp/tap/terraform
# 验证
terraform version
核心概念
Terraform 只有 4 个核心概念:
┌──────────────────────────────────────────┐
│ Terraform 工作流 │
│ │
│ Provider ──► Resource ──► State ──► Plan/Apply │
│ │ │ │ │ │
│ │ │ │ │ │
│ 连接 定义 记录 执行 │
│ 云平台 资源 当前状态 变更 │
└──────────────────────────────────────────┘
- Provider:对接具体平台(Proxmox、Docker、Kubernetes、AWS……)
- Resource:一个具体资源(虚拟机、容器、网络规则……)
- State:Terraform 记录的“当前基础设施长什么样”
- Plan/Apply:先看变更计划,再执行
第一个项目:用 Docker 练手
先别急着上虚拟机,用 Docker 练手更合适。创建目录 terraform-demo/:
mkdir terraform-demo && cd terraform-demo
创建 main.tf:
terraform {
required_providers {
docker = {
source = "kreuzwerker/docker"
version = "~> 3.0"
}
}
}
provider "docker" {}
# 定义一个 Nginx 容器
resource "docker_container" "nginx" {
name = "demo-nginx"
image = "nginx:alpine"
ports {
internal = 80
external = 8080
}
}
三步走:
# 1. 初始化(下载 Provider)
terraform init
# 2. 看看要做什么变更
terraform plan
plan 输出会显示:
Terraform will perform the following actions:
# docker_container.nginx will be created
+ resource "docker_container" "nginx" {
+ name = "demo-nginx"
+ image = "nginx:alpine"
+ ports {
+ external = 8080
+ internal = 80
}
}
Plan: 1 to add, 0 to change, 0 to destroy.
+ 表示新增,~ 表示修改,- 表示删除。确认无误后:
# 3. 执行
terraform apply
输入 yes 确认,Nginx 容器就跑起来了。访问 http://localhost:8080 验证。
销毁:
terraform destroy
容器消失,干干净净。这就是 IaC 的魅力:创建和销毁都是一条命令。
实战:管理 Proxmox 虚拟机
HomeLab 场景下最实用的是对接 Proxmox(或 KVM/libvirt)。以下示例创建一台 K3s 节点:
terraform {
required_providers {
proxmox = {
source = "Telmate/proxmox"
version = "~> 2.9"
}
}
}
provider "proxmox" {
pm_api_url = "https://192.168.1.200:8006/api2/json"
pm_user = "root@pam"
pm_password = var.proxmox_password
}
variable "proxmox_password" {
type = string
sensitive = true
}
variable "node_count" {
type = number
default = 3
}
resource "proxmox_vm_qemu" "k3s_node" {
count = var.node_count
name = "k3s-node-${count.index + 1}"
target_node = "pve"
clone = "ubuntu-2204-template"
full_clone = true
cores = 4
memory = 8192
scsihw = "virtio-scsi-single"
disk {
size = "100G"
type = "scsi"
storage = "local-lvm"
}
network {
model = "virtio"
bridge = "vmbr0"
}
# Cloud-init 配置
ciuser = "ubuntu"
cipassword = var.vm_password
ipconfig0 = "ip=192.168.1.${10 + count.index}/24,gw=192.168.1.1"
sshkeys = file("~/.ssh/id_ed25519.pub")
}
执行 terraform plan 看变更,terraform apply 一键创建 3 台虚拟机。想加一台?改 node_count = 4,再 apply。
State 管理
State 文件(terraform.tfstate)记录了当前基础设施的实际状态。这个文件非常重要——丢了就不知道哪些资源是你创建的。
团队协作时不要把 state 放本地,用远程后端:
terraform {
backend "http" {
# 用 GitLab 或 MinIO 做 remote state
address = "https://git.example.com/api/v4/projects/1/terraform/state/homelab"
}
}
几个重要操作:
# 查看当前 state 里的资源
terraform state list
# 查看某个资源详情
terraform state show docker_container.nginx
# 手动把已存在的资源导入 Terraform 管理
terraform import docker_container.existing <container_id>
变量管理
不要把密码和 IP 硬编码在 tf 文件里。用变量:
# variables.tf
variable "proxmox_password" {
type = string
sensitive = true
}
variable "vm_memory" {
type = number
default = 8192
validation {
condition = var.vm_memory >= 2048
error_message = "内存不能小于 2048MB。"
}
}
# terraform.tfvars(不提交到 Git)
proxmox_password = "your-password"
vm_memory = 16384
.gitignore 里加上:
*.tfstate
*.tfstate.*
.terraform/
*.tfvars
小结
| 概念 |
Ansible |
Terraform |
| 管什么 |
机器内的配置 |
机器本身的创建 |
| 时机 |
机器已存在 |
机器还不存在 |
| 格式 |
YAML Playbook |
HCL 配置 |
| 幂等 |
是 |
是 |
| 配合 |
← Terraform 创建好机器后,Ansible 接管配置 |
— |
典型工作流:Terraform 创建 VM → Ansible 配置软件 → ArgoCD 部署应用。三者配合就是完整的自动化流水线。下一篇,聊 ArgoCD——让 K8s 应用部署也变成自动的。