Terraform基础设施即代码与多环境挑战
当团队从单环境扩展到dev/staging/prod多环境时,基础设施管理复杂度呈指数增长。不同环境的VPC网络、实例规格、安全组策略各不相同,手动配置既容易出错又难以审计。Terraform作为主流基础设施即代码工具,通过声明式配置和状态管理解决了这一问题,但多环境场景下的目录结构、状态隔离和变量管理仍然有不少工程细节需要处理。
多环境管理的核心目标有三个:配置复用最大化(减少重复代码)、环境隔离彻底化(避免状态交叉污染)、变更流程规范化(prod变更必须经过审批)。
目录结构设计
多环境Terraform项目的目录结构有两种主流流派:目录隔离法和Workspaces隔离法。目录隔离法为每个环境创建独立的目录结构,状态文件天然隔离;Workspaces法使用Terraform Workspaces在同一目录下管理多环境,通过变量映射区分。
project-root/
├── modules/ # 共享模块
│ ├── vpc/
│ ├── ec2/
│ └── rds/
├── environments/
│ ├── dev/
│ │ ├── main.tf
│ │ ├── variables.tf
│ │ ├── outputs.tf
│ │ └── terraform.tfvars
│ ├── staging/
│ │ ├── main.tf
│ │ ├── variables.tf
│ │ ├── outputs.tf
│ │ └── terraform.tfvars
│ └── prod/
│ ├── main.tf
│ ├── variables.tf
│ ├── outputs.tf
│ └── terraform.tfvars
└── shared/
└── backend.tf
目录隔离法的优势在于每个环境完全独立,状态文件不会互相干扰,且可以使用不同的Terraform版本和Provider版本。缺点是模块引用路径需要显式声明。
状态后端隔离与远程状态配置
每个环境必须使用独立的状态文件,这是多环境管理的铁律。状态交叉污染的后果极其严重——staging的apply操作可能覆盖prod的资源状态。
# environments/dev/backend.tf
terraform {
backend "s3" {
bucket = "tf-state-dev"
key = "infra/dev/terraform.tfstate"
region = "us-east-1"
encrypt = true
dynamodb_table = "tf-lock-dev"
}
}
# environments/prod/backend.tf
terraform {
backend "s3" {
bucket = "tf-state-prod"
key = "infra/prod/terraform.tfstate"
region = "us-east-1"
encrypt = true
dynamodb_table = "tf-lock-prod"
}
}
状态锁定(State Locking)是防止并发写入的关键机制。DynamoDB作为锁表确保同一时刻只有一个operator可以操作某个环境的状态。对于阿里云用户,可以使用OSS后端配合TableStore实现同样的效果。
模块化与变量分层策略
共享模块是配置复用的核心。一个设计良好的模块应该接受环境差异作为输入变量,内部逻辑保持一致。变量分层策略如下:
第一层:模块默认值。模块内部variables.tf中定义的default值,作为最基础配置。
第二层:环境公共变量。environments/xxx/terraform.tfvars中定义该环境的所有变量值。
第三层:环境特定变量。使用locals块根据环境名称做条件计算,处理无法通过简单变量覆盖的差异逻辑。
# environments/prod/main.tf
locals {
env_config = {
dev = {
instance_type = "t3.small"
min_size = 1
max_size = 2
multi_az = false
}
staging = {
instance_type = "t3.medium"
min_size = 2
max_size = 4
multi_az = true
}
prod = {
instance_type = "c5.2xlarge"
min_size = 4
max_size = 20
multi_az = true
}
}
config = local.env_config[var.environment]
}
module "compute" {
source = "../../modules/ec2"
instance_type = local.config.instance_type
min_size = local.config.min_size
max_size = local.config.max_size
multi_az = local.config.multi_az
}
CI/CD流水线集成与审批门控
多环境Terraform的变更必须通过CI/CD流水线执行,禁止本地直连prod状态。典型的流水线分为plan和apply两个阶段:
# GitLab CI示例
stages:
- plan
- apply
terraform_plan_dev:
stage: plan
script:
- cd environments/dev
- terraform init
- terraform plan -out=tfplan
artifacts:
paths:
- environments/dev/tfplan
terraform_apply_prod:
stage: apply
needs: [terraform_plan_prod]
script:
- cd environments/prod
- terraform init
- terraform apply tfplan
when: manual
only:
- main
environment:
name: production
action: start
prod环境的apply阶段设置when: manual,要求运维人员手动确认后才执行。结合GitLab的Protected Environments或GitHub的Environment Protection Rules,可以进一步限制只有特定角色的用户才能触发prod部署。
Drift检测与状态一致性维护
配置漂移(Configuration Drift)是指实际基础设施状态与Terraform状态不一致的情况,通常由手动操作控制台、自动化脚本直接修改资源导致。漂移检测是SRE稳定性工程的重要环节。
#!/bin/bash
# drift_detect.sh - 定期检测各环境漂移
ENVIRONMENTS="dev staging prod"
SLACK_WEBHOOK="https://hooks.slack.com/services/xxx"
for env in $ENVIRONMENTS; do
cd environments/$env || continue
terraform init -backend-config=backend.tf > /dev/null 2>&1
CHANGES=$(terraform plan -detailed-exitcode 2>&1)
EXIT_CODE=$?
if [ $EXIT_CODE -eq 2 ]; then
PAYLOAD="{\"text\":\"[$env] 检测到基础设施漂移,请检查\n$CHANGES\"}"
curl -s -X POST -H 'Content-type: application/json' \
--data "$PAYLOAD" $SLACK_WEBHOOK
fi
done
建议将漂移检测脚本加入定时任务,每天凌晨执行一次。当检测到漂移时,优先通过terraform plan确认差异,再决定是执行apply恢复声明式状态,还是更新Terraform配置以匹配实际变更。口袋网在实践中有条经验:任何非Terraform发起的资源变更必须同步更新Terraform代码,否则下一次apply会覆盖手动变更。
数据资源与跨环境依赖
跨环境依赖是多环境管理中的常见场景。Terraform通过data块和remote_state数据源解决这个问题:
# environments/staging/main.tf
data "terraform_remote_state" "prod" {
backend = "s3"
config = {
bucket = "tf-state-prod"
key = "infra/prod/terraform.tfstate"
region = "us-east-1"
}
}
resource "aws_vpc_peering_connection" "staging_to_prod" {
vpc_id = module.vpc.vpc_id
peer_vpc_id = data.terraform_remote_state.prod.outputs.vpc_id
peer_region = "us-east-1"
auto_accept = false
}
跨环境引用增加了耦合度,应控制使用范围。推荐的实践是只通过remote_state读取输出值,不直接依赖其他环境的内部资源结构,保持各环境的自治性。
原创文章,作者:小编,如若转载,请注明出处:https://www.yunthe.com/terraform-duo-huan-jing-ji-chu-she-shi-ji-dai-ma-guan-li/