IaC将基础设施的定义从手工操作变成声明式代码,实现版本控制、自动部署、可复现、可审计。Terraform是当前最流行的IaC工具。
┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐
│ 编写HCL │→│ terraform │→│ terraform │→│ terraform │
│ (*.tf) │ │ init │ │ plan │ │ apply │
└──────────┘ └──────────┘ └──────────┘ └─────┬─────┘
│
┌──────▼──────┐
│ 云API调用 │
└──────┬──────┘
┌─────────────────────────────┼─────────┐
▼ ▼ ▼ ▼
┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────┐
│ VPC │ │ EC2 │ │ RDS │ │ S3 │
└──────────┘ └──────────┘ └──────────┘ └──────┘
└────────────────┴─────────────┴─────────┘
│
┌──────▼──────┐
│ tfstate(S3) │
└─────────────┘# 安装Terraform
wget -O- https://releases.hashicorp.com/terraform/1.8.0/terraform_1.8.0_linux_amd64.zip > terraform.zip
unzip terraform.zip && sudo mv terraform /usr/local/bin/
mkdir -p terraform/aws-infra && cd terraform/aws-infra
cat > versions.tf << 'EOF'
terraform {
required_version = ">= 1.5"
required_providers {
aws = { source = "hashicorp/aws", version = "~> 5.0" }
}
backend "s3" {
bucket = "my-tf-state-2026"
key = "aws-infra/terraform.tfstate"
region = "ap-southeast-1"
}
}
EOF
cat > main.tf << 'EOF'
variable "environment" { default = "production" }
variable "instance_type" { default = "t3.medium" }
resource "aws_vpc" "main" {
cidr_block = "10.0.0.0/16"
enable_dns_hostnames = true
tags = { Name = "${var.environment}-vpc" }
}
resource "aws_subnet" "public" {
vpc_id = aws_vpc.main.id
cidr_block = "10.0.1.0/24"
map_public_ip_on_launch = true
availability_zone = "ap-southeast-1a"
tags = { Name = "${var.environment}-public" }
}
resource "aws_instance" "app" {
ami = data.aws_ami.ubuntu.id
instance_type = var.instance_type
subnet_id = aws_subnet.public.id
vpc_security_group_ids = [aws_security_group.app.id]
tags = { Name = "${var.environment}-app" }
}
data "aws_ami" "ubuntu" {
most_recent = true
owners = ["099720109477"]
filter {
name = "name"
values = ["ubuntu/images/hvm-ssd/ubuntu-jammy-22.04-amd64-server-*"]
}
}
resource "aws_security_group" "app" {
vpc_id = aws_vpc.main.id
ingress {
from_port = 22
to_port = 22
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
ingress {
from_port = 443
to_port = 443
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
egress {
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
}
}
output "instance_ip" { value = aws_instance.app.public_ip }
EOF
terraform init
terraform plan -out=tfplan
terraform apply tfplanmkdir -p modules/vpc
cat > modules/vpc/main.tf << 'EOF'
variable "cidr" { default = "10.0.0.0/16" }
variable "env" { default = "dev" }
variable "azs" { default = ["ap-southeast-1a","ap-southeast-1b"] }
resource "aws_vpc" "this" {
cidr_block = var.cidr
tags = { Name = "${var.env}-vpc" }
}
resource "aws_subnet" "public" {
count = length(var.azs)
vpc_id = aws_vpc.this.id
cidr_block = cidrsubnet(var.cidr, 8, count.index)
availability_zone = var.azs[count.index]
map_public_ip_on_launch = true
}
resource "aws_subnet" "private" {
count = length(var.azs)
vpc_id = aws_vpc.this.id
cidr_block = cidrsubnet(var.cidr, 8, count.index + length(var.azs))
availability_zone = var.azs[count.index]
}
output "vpc_id" { value = aws_vpc.this.id }
output "public_ids" { value = aws_subnet.public[*].id }
EOF
# 使用Module
cat > environments/prod/main.tf << 'EOF'
module "vpc" {
source = "../../modules/vpc"
cidr = "10.1.0.0/16"
env = "prod"
azs = ["ap-southeast-1a","ap-southeast-1b","ap-southeast-1c"]
}
EOF# 远程State(S3+DynamoDB锁)
aws dynamodb create-table --table-name tf-lock \
--attribute-definitions AttributeName=LockID,AttributeType=S \
--key-schema AttributeName=LockID,KeyType=HASH \
--billing-mode PAY_PER_REQUEST
# State操作
terraform state list
terraform state show aws_instance.app
terraform state mv aws_instance.app aws_instance.app_new
# Import已有资源
terraform import aws_instance.app i-1234567890abcdef0
# GitHub Actions集成
cat > .github/workflows/terraform.yml << 'EOF'
name: Terraform CI/CD
on: [push, pull_request]
jobs:
terraform:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: hashicorp/setup-terraform@v3
- run: terraform init
- run: terraform plan -out=tfplan
- run: terraform apply -auto-approve tfplan
if: github.ref == 'refs/heads/main'
EOF┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐
│ 编写HCL │→│ terraform │→│ terraform │→│ terraform │
│ (*.tf) │ │ init │ │ plan │ │ apply │
└──────────┘ └──────────┘ └──────────┘ └─────┬─────┘
│
┌──────▼──────┐
│ 云API调用 │
└──────┬──────┘
┌─────────────────────────────┼─────────┐
▼ ▼ ▼ ▼
┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────┐
│ VPC │ │ EC2 │ │ RDS │ │ S3 │
└──────────┘ └──────────┘ └──────────┘ └──────┘
└────────────────┴─────────────┴─────────┘
│
┌──────▼──────┐
│ tfstate(S3) │
└─────────────┘aws dynamodb get-item --table-name tf-lock --key '{"LockID":{"S":"my-tf-state/prod/terraform.tfstate-md5"}}'
# 强制解锁(确认无其他人执行)
terraform force-unlock
# State修复
terraform state pull > backup.tfstate
terraform state push backup.tfstate 掌握Terraform HCL、Module复用、State管理、CI/CD集成——基础设施即代码是DevOps核心