Terraform 基础设施即代码入门
bash brew tap hashicorp/tap brew install hashicorp/tap/terraform
### Linux (Debian/Ubuntu)
```bash
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
Windows
直接下载可执行文件并添加到系统 PATH 中,或使用 Chocolatey:
choco install terraform
验证安装
安装完成后,打开终端运行:
terraform version
如果显示版本号,说明安装成功。
编写第一个 Terraform 配置
为使示例零门槛运行,我们使用 Docker Provider 来管理本地容器,无需任何云账号。请确保已安装 Docker Desktop 并启动。
工作目录和 main.tf
新建一个空目录并进入,所有配置文件将以 .tf 后缀保存在该目录下。创建 main.tf:
# 告知 Terraform 使用哪些 Provider
terraform {
required_providers {
docker = {
source = "kreuzwerker/docker"
version = "~> 3.0.1"
}
}
}
配置 Provider
接下来配置 Docker Provider。若 Docker 已在本机运行,通常无需额外参数:
provider "docker" {
# 本地 Docker 引擎,使用默认环境连接
}
创建资源
创建一个运行 nginx 的容器资源:
resource "docker_image" "nginx" {
name = "nginx:latest"
keep_locally = false
}
resource "docker_container" "nginx" {
image = docker_image.nginx.image_id
name = "learn-tf-nginx"
ports {
internal = 80
external = 8080
}
}
docker_image确保 nginx 镜像已被拉取。docker_container基于该镜像启动一个容器,将容器内 80 端口映射到本机 8080 端口。
变量定义
将可能变化的值提取为变量,提高配置的灵活性和可重用性。新建 variables.tf:
variable "container_name" {
description = "Name of the container"
type = string
default = "learn-tf-nginx"
}
variable "host_port" {
description = "Host port to expose"
type = number
default = 8080
}
修改 main.tf 中的容器定义,引用变量:
resource "docker_container" "nginx" {
image = docker_image.nginx.image_id
name = var.container_name
ports {
internal = 80
external = var.host_port
}
}
输出值
输出容器启动后的状态信息,便于外部查询。新建 outputs.tf:
output "container_id" {
description = "ID of the Docker container"
value = docker_container.nginx.id
}
output "container_url" {
description = "Access URL"
value = "http://localhost:${var.host_port}"
}
Terraform 工作流
Terraform 的核心工作流由 init → plan → apply 组成,随后可用 destroy 清理资源。
初始化 (init)
在包含 .tf 文件的目录下执行:
terraform init
此命令会下载所需的 Provider 插件(本例为 kreuzwerker/docker)并初始化后端(默认为本地后端)。
格式化与验证 (fmt / validate)
- 格式化代码:
terraform fmt自动对齐和格式化所有.tf文件。 - 语法验证:
terraform validate检查配置文件是否有语法错误,无需连接平台。
计划 (plan)
terraform plan
Terraform 会对比当前状态与配置文件,输出一份详细的变更计划:哪些资源将被创建、修改或删除。这是安全的检查步骤,不会变更任何真实资源。
执行后应当看到 docker_image.nginx 和 docker_container.nginx 将被创建。
应用 (apply)
确认计划无误后,执行:
terraform apply
Terraform 会再次显示计划并要求确认。输入 yes 后,开始创建资源。完成后,终端会打印定义的输出值,例如:
container_url = "http://localhost:8080"
打开浏览器访问该地址,应能看到 nginx 欢迎页。
销毁 (destroy)
不再需要资源时,确保清理,避免资源闲置占用:
terraform destroy
同样需要输入 yes 确认。Terraform 会销毁由当前配置管理的所有资源。
状态管理
什么是状态文件
Terraform 执行完 apply 后,会在当前目录生成 terraform.tfstate。这是一个 JSON 文件,记录了已创建资源的标识和属性。它用于:
- 将配置中的资源名称映射到真实的资源 ID。
- 检测配置变更时,仅修改需要更新的资源。
- 存储资源间的依赖关系。
该文件可能包含敏感信息(如密码),因此绝对不要将其提交到版本控制系统。可将其添加到 .gitignore。
远程状态与团队协作
在团队中使用时,本地状态文件会导致锁冲突和状态不一致。Terraform 支持远程后端,例如 AWS S3、Terraform Cloud 或 HashiCorp Consul,将状态文件保存到共享存储中,并提供状态锁定功能,防止多人同时变更。
例如,配置 S3 后端的简单示例(需先创建 S3 桶):
terraform {
backend "s3" {
bucket = "my-terraform-state-bucket"
key = "project/terraform.tfstate"
region = "us-east-1"
}
}