Terraform是HashiCorp开源的基础设施即代码(IaC)工具,通过声明式配置文件管理云资源生命周期。DevOps实践中,Terraform已成为多云资源编排的标准方案。相比手动控制台操作,IaC方式可实现版本管理、代码审查和自动化部署,显著降低配置漂移风险。
Terraform核心概念与工作流
Terraform的执行流程分四个阶段:init(初始化后端和Provider插件)、plan(生成执行计划)、apply(执行变更)、destroy(销毁资源)。配置文件使用HCL(HashiCorp Configuration Language)语法,以resource块定义资源。
# main.tf - 基础配置结构
terraform {
required_version = ">= 1.5.0"
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 5.0"
}
alibaba = {
source = "aliyun/alicloud"
version = "~> 1.220"
}
}
backend "s3" {
bucket = "terraform-state-prod"
key = "infra/terraform.tfstate"
region = "us-east-1"
encrypt = true
dynamodb_table = "terraform-locks"
}
}
provider "aws" {
region = "us-east-1"
}
provider "alicloud" {
region = "cn-hangzhou"
}
backend配置决定状态文件存储位置。S3后端配合DynamoDB表实现状态锁,防止多人同时执行apply导致状态冲突。生产环境务必启用encrypt=true,状态文件中可能包含敏感信息。
多云资源编排实战
多云场景下,Terraform通过不同Provider管理各云厂商资源。以下示例在AWS和阿里云分别部署VPC和ECS实例,实现多云容灾架构。
# AWS VPC与EC2
resource "aws_vpc" "main" {
cidr_block = "10.10.0.0/16"
enable_dns_support = true
enable_dns_hostnames = true
tags = { Name = "prod-vpc", Env = "production" }
}
resource "aws_subnet" "web" {
vpc_id = aws_vpc.main.id
cidr_block = "10.10.1.0/24"
availability_zone = "us-east-1a"
map_public_ip_on_launch = true
tags = { Name = "web-subnet" }
}
resource "aws_instance" "web_server" {
ami = "ami-0c7217cdde87094e3"
instance_type = "t3.large"
subnet_id = aws_subnet.web.id
vpc_security_group_ids = [aws_security_group.web.id]
user_data = file("init.sh")
tags = { Name = "web-server-01", Env = "production" }
}
# 阿里云ECS
resource "alicloud_instance" "backup" {
instance_type = "ecs.g6.large"
image_id = "ubuntu_22_04_x64"
security_groups = [alicloud_security_group.default.id]
instance_name = "backup-server-01"
internet_charge_type = "PayByTraffic"
system_disk_category = "cloud_essd"
system_disk_size = 100
tags = { Name = "backup-server", Env = "production" }
}
多云编排的关键是资源依赖管理。Terraform自动解析资源间依赖关系(如ECS引用Security Group),必要时可用depends_on显式声明依赖。跨云资源的引用需要通过variable和output传递数据。
状态文件管理与远程后端
状态文件(terraform.tfstate)记录所有资源的当前状态,是Terraform的核心数据。本地状态文件存在团队协作冲突和数据丢失风险,生产环境必须使用远程后端。
# 状态文件隔离方案 - 使用workspaces
terraform workspace new dev
terraform workspace select dev
terraform apply -var-file="dev.tfvars"
terraform workspace new prod
terraform workspace select prod
terraform apply -var-file="prod.tfvars"
terraform workspace show
Workspace实现同一配置文件管理多套环境,状态文件自动隔离。但Workspace隔离不等于安全隔离——有prod权限的人也能切换到dev workspace。更严格的隔离方案是使用独立的backend key,每个环境一个独立的state文件路径。
模块化配置与代码复用
将通用资源组合封装为Module,提高配置复用性。Module结构示例:
# modules/vpc/main.tf
variable "cidr_block" {
type = string
default = "10.0.0.0/16"
}
variable "environment" {
type = string
default = "dev"
}
variable "az_count" {
type = number
default = 2
}
resource "aws_vpc" "this" {
cidr_block = var.cidr_block
tags = { Environment = var.environment }
}
resource "aws_subnet" "public" {
count = var.az_count
vpc_id = aws_vpc.this.id
cidr_block = cidrsubnet(var.cidr_block, 8, count.index)
availability_zone = data.aws_availability_zones.available.names[count.index]
tags = { Tier = "public" }
}
output "vpc_id" {
value = aws_vpc.this.id
}
output "subnet_ids" {
value = aws_subnet.public[*].id
}
# 调用Module
module "prod_vpc" {
source = "./modules/vpc"
cidr_block = "10.20.0.0/16"
environment = "production"
az_count = 3
}
Module版本管理推荐使用Git tag。私有Module可通过Terraform Registry或直接引用Git仓库:source = “git::https://github.com/company/tf-modules.git//vpc?ref=v1.2.0”
CI/CD集成与自动化流水线
Terraform与CI/CD流水线集成实现自动化基础设施变更。GitHub Actions或GitLab CI中,每次Pull Request自动运行terraform plan并将结果评论到PR页面,人工审核通过后合并触发apply。
# .github/workflows/terraform.yml
name: Terraform CI/CD
on:
pull_request:
branches: [main]
push:
branches: [main]
jobs:
terraform:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: hashicorp/setup-terraform@v3
with:
terraform_version: "1.5.7"
- name: Terraform Init
run: terraform init
env:
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_KEY }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET }}
- name: Terraform Plan
if: github.event_name == 'pull_request'
run: terraform plan -no-color
env:
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_KEY }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET }}
- name: Terraform Apply
if: github.event_name == 'push' && github.ref == 'refs/heads/main'
run: terraform apply -auto-approve
env:
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_KEY }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET }}
安全要点:云平台密钥通过CI/CD Secrets注入,不出现在代码仓库中。Apply操作仅限main分支push触发,Plan可在PR阶段运行。建议配合Terraform Cloud或Atlantis实现更完善的审批流程。
原创文章,作者:小编,如若转载,请注明出处:https://www.yunthe.com/terraform-duo-yun-zi-yuan-bian-pai-shi-zhan-ji-chu-she-shi/