Terraform 基础设施即代码
概述
Terraform 是 HashiCorp 公司开发的开源基础设施即代码 (IaC) 工具,使用声明式语言 HCL 定义和预配基础设施。
核心优势
- 多云管理:统一管理 AWS、Azure、GCP 等多云资源
- 声明式配置:描述期望状态,Terraform 自动达成
- 状态管理:跟踪资源状态,增量更新
- 模块化:复用基础设施代码
安装与入门
# 安装 Terraform(Ubuntu)
wget -O- https://apt.releases.hashicorp.com/gpg | gpg --dearmor | sudo tee /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 init → 初始化项目,下载 Provider
terraform plan → 预览变更
terraform apply → 执行变更
terraform destroy → 销毁资源
HCL 语法基础
# 指定 Provider 和版本
terraform {
required_version = ">= 1.6"
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 5.0"
}
}
}
# Provider 配置
provider "aws" {
region = "ap-northeast-1"
}
# 资源定义
resource "aws_instance" "web" {
ami = "ami-0c55b159cbfafe1f0"
instance_type = "t3.micro"
tags = {
Name = "web-server"
Env = "production"
}
}
# 数据源:查询已有资源
data "aws_vpc" "default" {
default = true
}
变量与输出
# variables.tf
variable "environment" {
description = "部署环境"
type = string
default = "dev"
}
variable "instance_count" {
type = number
default = 2
}
variable "tags" {
type = map(string)
default = {
Project = "MyApp"
Managed = "Terraform"
}
}
# 使用变量
resource "aws_instance" "app" {
count = var.instance_count
tags = var.tags
}
# outputs.tf
output "instance_ips" {
description = "实例 IP 地址列表"
value = aws_instance.app[*].public_ip
}
output "vpc_id" {
value = data.aws_vpc.default.id
}
状态管理
远程状态 (S3)
# backend.tf
terraform {
backend "s3" {
bucket = "my-terraform-state"
key = "production/terraform.tfstate"
region = "ap-northeast-1"
# 状态文件锁
dynamodb_table = "terraform-locks"
}
}
状态操作
# 查看当前状态
terraform state list
terraform state show aws_instance.web
# 移动资源
terraform state mv aws_instance.web aws_instance.web_new
# 从状态移除(不销毁资源)
terraform state rm aws_instance.old
# 导入已有资源
terraform import aws_instance.web i-1234567890abcdef0
模块化
# modules/vpc/main.tf
variable "vpc_cidr" {
type = string
}
resource "aws_vpc" "main" {
cidr_block = var.vpc_cidr
}
# 使用模块
module "vpc" {
source = "./modules/vpc"
vpc_cidr = "10.0.0.0/16"
}
module "ecs" {
source = "terraform-aws-modules/ecs/aws"
version = "~> 5.0"
cluster_name = "production"
vpc_id = module.vpc.vpc_id
}
常用 Provider 示例
阿里云
provider "alicloud" {
region = "cn-hangzhou"
}
resource "alicloud_instance" "server" {
image_id = "ubuntu_22_04_x64_20G_alibase_2023"
instance_type = "ecs.g6.large"
system_disk_category = "cloud_essd"
security_groups = [alicloud_security_group.web.id]
}
Kubernetes
provider "kubernetes" {
config_path = "~/.kube/config"
}
resource "kubernetes_namespace" "app" {
metadata {
name = "production"
}
}
resource "kubernetes_deployment" "app" {
metadata {
name = "web-app"
namespace = kubernetes_namespace.app.metadata[0].name
}
spec {
replicas = 3
selector {
match_labels = {
app = "web"
}
}
template {
metadata {
labels = {
app = "web"
}
}
spec {
container {
image = "nginx:latest"
name = "nginx"
port {
container_port = 80
}
}
}
}
}
}
最佳实践
目录结构
terraform/
├── environments/
│ ├── dev/
│ │ ├── main.tf
│ │ ├── variables.tf
│ │ └── terraform.tfvars
│ ├── staging/
│ └── production/
└── modules/
├── vpc/
├── compute/
└── database/
代码规范
- 使用
_命名资源(而不是-) - 为所有资源添加
Name标签 - 使用
terraform fmt格式化代码 - 对敏感信息使用
sensitive = true
安全最佳实践
- 远程状态必须加密
- 使用 DynamoDB 实现状态锁
- 不要在代码中硬编码密钥
- 使用最小权限原则配置 Provider
- 定期审核状态文件
总结
Terraform 将基础设施管理从手动操作转变为代码化、版本化的工程实践。通过模块化设计和远程状态管理,团队可以安全、高效地管理云计算资源。建议从简单的单云环境开始,逐步过渡到多云和模块化管理。