
使用 Terraform 实现基础设施即代码
项目结构
terraform/
├── environments/
│ ├── dev/
│ │ ├── main.tf
│ │ ├── variables.tf
│ │ └── terraform.tfvars
│ └── prod/
│ ├── main.tf
│ └── terraform.tfvars
├── modules/
│ ├── vpc/
│ │ ├── main.tf
│ │ ├── variables.tf
│ │ └── outputs.tf
│ ├── ecs-service/
│ └── rds/
└── shared/
└── backend.tf

模块设计
# modules/ecs-service/main.tf
variable "name" { type = string }
variable "image" { type = string }
variable "cpu" { type = number; default = 256 }
variable "memory" { type = number; default = 512 }
variable "environment_variables" {
type = map(string)
default = {}
}
resource "aws_ecs_task_definition" "this" {
family = var.name
requires_compatibilities = ["FARGATE"]
network_mode = "awsvpc"
cpu = var.cpu
memory = var.memory
container_definitions = jsonencode([{
name = var.name
image = var.image
portMappings = [{ containerPort = 3000 }]
environment = [
for k, v in var.environment_variables : { name = k, value = v }
]
logConfiguration = {
logDriver = "awslogs"
options = {
"awslogs-group" = "/ecs/\${var.name}"
"awslogs-region" = data.aws_region.current.name
"awslogs-stream-prefix" = "ecs"
}
}
}])
}
output "task_definition_arn" {
value = aws_ecs_task_definition.this.arn
}
使用模块
# environments/prod/main.tf
module "api_service" {
source = "../../modules/ecs-service"
name = "api-prod"
image = "123456789.dkr.ecr.us-east-1.amazonaws.com/api:${var.image_tag}"
cpu = 512
memory = 1024
environment_variables = {
NODE_ENV = "production"
DB_HOST = module.rds.endpoint
REDIS_URL = "redis://${module.redis.endpoint}:6379"
}
}

使用 S3 的远程状态
# backend.tf
terraform {
backend "s3" {
bucket = "my-company-terraform-state"
key = "prod/terraform.tfstate"
region = "us-east-1"
encrypt = true
dynamodb_table = "terraform-state-lock" # 防止并发执行
}
}
# 创建锁表
resource "aws_dynamodb_table" "terraform_lock" {
name = "terraform-state-lock"
billing_mode = "PAY_PER_REQUEST"
hash_key = "LockID"
attribute { name = "LockID"; type = "S" }
}
用于环境的工作区
# 创建工作区
terraform workspace new dev
terraform workspace new staging
terraform workspace new prod
# 切换工作区
terraform workspace select prod
# 在配置中使用
locals {
env_config = {
dev = { instance_type = "t3.small"; min_count = 1; max_count = 3 }
staging = { instance_type = "t3.medium"; min_count = 2; max_count = 5 }
prod = { instance_type = "t3.large"; min_count = 3; max_count = 20 }
}
config = local.env_config[terraform.workspace]
}

CI/CD 集成
# .github/workflows/terraform.yml
- name: Terraform Init
run: terraform init -backend-config="key=${{ github.ref_name }}/terraform.tfstate"
- name: Terraform Plan
run: terraform plan -out=tfplan -var="image_tag=${{ github.sha }}"
- name: Terraform Apply (main branch only)
if: github.ref == 'refs/heads/main'
run: terraform apply tfplan
漂移检测
# 检测配置漂移(控制台中的手动更改)
terraform plan -detailed-exitcode
# 退出码 0:无更改
# 退出码 1:错误
# 退出码 2:发现差异(漂移!)
Terraform 模块使得跨环境和团队可复用的 DRY 基础设施代码成为可能。