Terraform是HashiCorp推出的基础设施即代码(IaC)工具,通过声明式配置文件定义云资源,实现基础设施的版本化管理和自动化部署。相比手动在控制台创建资源,Terraform支持多云环境统一编排、资源变更可审计、环境可复现,已成为DevOps和SRE实践中的标准工具。
Terraform核心概念与工作流程
Terraform的工作流程包含四个阶段:编写(Write)→ 计划(Plan)→ 应用(Apply)→ 销毁(Destroy)。核心概念包括Provider(云平台接口)、Resource(资源定义)、State(状态文件)、Module(可复用模块)。
# main.tf - 基础结构示例
terraform {
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 5.0"
}
}
required_version = ">= 1.5"
}
provider "aws" {
region = "ap-northeast-1"
}
# 定义一个EC2实例
resource "aws_instance" "web" {
ami = "ami-0c55b159cbfafe1f0"
instance_type = "t3.micro"
tags = {
Name = "web-server"
Environment = "production"
}
}
变量管理与多环境配置实践
生产实践中需要区分开发、测试、生产等不同环境。Terraform通过变量文件(terraform.tfvars)和workspace两种方式实现多环境管理。推荐使用独立的目录配合变量文件的方式,环境之间完全隔离:
# variables.tf - 变量声明
variable "environment" {
type = string
default = "dev"
}
variable "instance_type" {
type = map(string)
default = {
dev = "t3.micro"
staging = "t3.small"
prod = "t3.medium"
}
}
variable "instance_count" {
type = map(number)
default = {
dev = 1
staging = 2
prod = 3
}
}
# dev.tfvars
environment = "dev"
# prod.tfvars
environment = "prod"
使用不同环境配置执行:
# 初始化
terraform init
# 开发环境
terraform plan -var-file="dev.tfvars"
terraform apply -var-file="dev.tfvars"
# 生产环境
terraform plan -var-file="prod.tfvars"
terraform apply -var-file="prod.tfvars"
远程状态后端配置与状态锁定
Terraform状态文件记录了当前基础设施的实际状态。本地状态文件存在安全风险和协作冲突,生产环境必须使用远程后端存储状态。S3+DynamoDB是AWS上的标准方案,S3存储状态文件,DynamoDB提供状态锁定防止并发操作冲突:
# backend.tf - 远程状态配置
terraform {
backend "s3" {
bucket = "terraform-state-yunthe"
key = "infra/prod/terraform.tfstate"
region = "ap-northeast-1"
encrypt = true
dynamodb_table = "terraform-locks"
}
}
# 需要先手动创建S3桶和DynamoDB表
# S3桶开启版本控制,便于状态回滚
# DynamoDB表设置LockID主键
状态锁定机制确保同一时间只有一个Terraform进程能修改基础设施。当terraform apply执行时,先在DynamoDB中写入锁记录,操作完成后释放锁。如果多个工程师同时操作,后执行者会收到锁定错误并等待。
Module模块化设计与资源复用
当基础设施规模增长后,将资源配置封装为Module可以大幅提升复用性和可维护性。一个典型的VPC模块包含子网、路由表、Internet Gateway等资源:
# modules/vpc/main.tf
variable "cidr_block" {
type = string
default = "10.0.0.0/16"
}
variable "environment" {
type = string
}
variable "availability_zones" {
type = list(string)
default = ["ap-northeast-1a", "ap-northeast-1c"]
}
resource "aws_vpc" "main" {
cidr_block = var.cidr_block
enable_dns_support = true
enable_dns_hostnames = true
tags = {
Name = "vpc-${var.environment}"
Environment = var.environment
}
}
resource "aws_subnet" "public" {
count = length(var.availability_zones)
vpc_id = aws_vpc.main.id
cidr_block = cidrsubnet(var.cidr_block, 8, count.index)
availability_zone = var.availability_zones[count.index]
tags = {
Name = "subnet-public-${count.index}-${var.environment}"
}
}
output "vpc_id" {
value = aws_vpc.main.id
}
output "subnet_ids" {
value = aws_subnet.public[*].id
}
在根配置中引用模块:
# main.tf - 引用模块
module "vpc_prod" {
source = "./modules/vpc"
cidr_block = "10.1.0.0/16"
environment = "prod"
availability_zones = ["ap-northeast-1a", "ap-northeast-1c", "ap-northeast-1d"]
}
module "vpc_dev" {
source = "./modules/vpc"
environment = "dev"
}
# 模块输出可以在其他资源中引用
resource "aws_instance" "app" {
subnet_id = module.vpc_prod.subnet_ids[0]
# ...
}
资源导入与漂移检测
当存量基础设施需要纳入Terraform管理时,使用import命令将已有资源导入状态文件。Terraform 1.5+支持在配置文件中声明导入,替代命令行方式:
# 在配置文件中声明导入
import {
to = aws_instance.existing
id = "i-0123456789abcdef0"
}
resource "aws_instance.existing" {
# 配置需要与实际资源匹配
ami = "ami-0c55b159cbfafe1f0"
instance_type = "t3.micro"
}
# 执行导入
terraform plan # 检查配置与实际资源的差异
terraform apply # 将资源纳入状态管理
漂移检测是Terraform的重要能力。当有人手动修改了云资源(如通过控制台改了安全组规则),运行terraform plan会显示配置与实际状态的差异。定期执行plan检查漂移并修复,是保障基础设施一致性的关键实践:
# CI/CD中的漂移检测脚本
#!/bin/bash
terraform init -input=false
PLAN_FILE=$(mktemp)
terraform plan -detailed-exitcode -out=$PLAN_FILE
EXIT_CODE=$?
if [ $EXIT_CODE -eq 0 ]; then
echo "No drift detected"
elif [ $EXIT_CODE -eq 2 ]; then
echo "Drift detected! Review the plan:"
terraform show $PLAN_FILE
# 发送告警通知
exit 1
else
echo "Plan failed"
exit 1
fi
CI/CD集成与自动化流水线配置
将Terraform集成到CI/CD流水线中实现基础设施变更的自动化审批和部署。以GitHub Actions为例:
# .github/workflows/terraform.yml
name: Terraform Pipeline
on:
push:
paths: ["terraform/**"]
pull_request:
paths: ["terraform/**"]
jobs:
terraform:
runs-on: ubuntu-latest
defaults:
run:
working-directory: terraform
steps:
- uses: actions/checkout@v4
- uses: aws-actions/configure-aws-credentials@v4
with:
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
aws-region: ap-northeast-1
- uses: hashicorp/setup-terraform@v3
- name: Terraform Init
run: terraform init -input=false
- name: Terraform Format Check
run: terraform fmt -check -recursive
- name: Terraform Plan
run: terraform plan -input=false -out=tfplan
# PR中会自动显示plan结果
- name: Terraform Apply
if: github.ref == 'refs/heads/main'
run: terraform apply -auto-approve tfplan
流水线中plan阶段自动执行并输出变更计划,apply阶段仅在合并到主分支时触发,确保所有变更经过Code Review后才会应用到生产环境。配合Terraform Cloud或Atlantis等工具,还可以在PR评论中直接执行plan和apply,进一步提升协作效率。
原创文章,作者:小编,如若转载,请注明出处:https://www.yunthe.com/terraform-ji-chu-she-shi-ji-dai-ma-shi-zhan-duo-yun-zi-yuan/