通过Terraform工作区创建差异化配置EC2实例的方案
适配场景的最佳实现方案
这套方案完全匹配你使用Terraform 0.12.26、单GitHub分支存储代码、仅用单个aws_instance资源块、多工作区差异化部署EC2的要求,没有多余封装,维护成本低。
第一步:定义兼容多环境的变量结构
在根目录variables.tf中定义变量,所有差异化配置全部通过变量传入,不要在核心逻辑里硬编码环境判断:
# 多工作区EC2差异化配置集合 variable "ec2_configs" { type = map(object({ instance_type = string instance_count = number ami_id = string # 其他需要差异化的字段,比如子网ID、安全组ID、系统盘大小都可以在这里扩展 })) } # 全环境通用配置单独定义 variable "key_pair_name" { type = string } variable "common_tags" { type = map(string) default = { ManagedBy = "Terraform" } }
第二步:按环境拆分独立TFVARS文件
完全沿用你最初的设想,每个工作区对应一个独立的tfvars文件,文件直接以工作区名称命名即可:
dev.tfvars:存储开发环境配置prod.tfvars:存储生产环境配置
dev.tfvars示例:
ec2_configs = { dev = { instance_type = "t3.micro" instance_count = 2 ami_id = "ami-0xxxxxxxxx" # 替换为开发环境实际使用的AMI } } key_pair_name = "dev-ssh-key"
prod.tfvars示例:
ec2_configs = { prod = { instance_type = "m5.large" instance_count = 6 ami_id = "ami-0yyyyyyyyy" # 替换为生产环境实际使用的AMI } } key_pair_name = "prod-ssh-key"
第三步:编写单个aws_instance资源块
在主配置文件(通常为main.tf)中,仅写一个aws_instance资源块,通过Terraform内置的terraform.workspace值自动匹配当前工作区的配置,通过count控制实例创建数量:
# 提前提取当前工作区的配置,简化后续引用 locals { current_env_config = var.ec2_configs[terraform.workspace] env_tags = merge(var.common_tags, { Environment = terraform.workspace }) } # 全局唯一的aws_instance资源块,不需要为每个环境重复编写 resource "aws_instance" "app" { count = local.current_env_config.instance_count ami = local.current_env_config.ami_id instance_type = local.current_env_config.instance_type key_name = var.key_pair_name # 全环境一致的配置直接写在资源块内即可,比如根卷配置、监控开关、用户数据脚本 root_block_device { volume_size = 30 volume_type = "gp3" } tags = merge(local.env_tags, { Name = "app-${terraform.workspace}-${count.index + 1}" }) }
第四步:部署操作方式
切换到对应工作区后,执行命令时指定匹配的tfvars文件即可,以开发环境为例:
terraform workspace select dev terraform plan -var-file=dev.tfvars terraform apply -var-file=dev.tfvars
生产环境部署只需切换到prod工作区,将命令中的var-file替换为prod.tfvars即可。
0.12版本实际落地注意事项
- 不要在核心逻辑里写硬编码的工作区if/else判断,所有差异化配置全部收敛到tfvars文件,后续新增测试、预发这类新环境时,只需要新增对应tfvars文件,不需要修改资源逻辑
- 0.12版本的
count参数在调整实例数量时,不要随意修改配置条目顺序,避免触发实例意外重建,通过Name标签带序号的方式区分单台实例即可 - Terraform工作区会自动隔离不同环境的状态文件,不需要额外配置远程状态路径隔离逻辑,不会出现环境状态互相覆盖的问题
- 如果觉得每次执行命令带
-var-file参数麻烦,可以写个简单的shell包装脚本,自动根据当前选中的工作区加载同名tfvars文件,不需要改动Terraform本身代码
这种实现方式没有过度抽象,代码可读性高,排查问题时直接查看对应环境的tfvars就能明确配置差异,比为每个环境写重复资源块的维护成本低很多。
内容的提问来源于stack exchange,提问作者Dave Michaels
相关产品推荐
相关产品推荐

