通过Terraform为GCP非托管实例组添加多跨可用区HA实例
问题描述
需要将多个跨可用区的GCP实例添加至非托管实例组(UIG),但现有代码仅能为UIG绑定少量实例:当var.num_instances数量≥可用区数量时,代码可正常创建UIG并绑定实例;但当可用区数量<var.num_instances时,无法完成所有实例的绑定。
现有代码
main.tf
data "google_compute_zones" "available" { project = var.project region = var.region } module "google_uig" { source = "C:/Users/xxxx/OneDrive/Desktop/New folder/terraform-google-core/modules/compute_engine_uig" depends_on = [ module.google_vm ] project = var.project # count = var.num_instances count = length(data.google_compute_zones.available.names) < var.num_instances ? length(data.google_compute_zones.available.names) : var.num_instances zone = var.zone == null ? data.google_compute_zones.available.names[count.index % length(data.google_compute_zones.available.names)] : var.zone name = "use1${[for zone in (data.google_compute_zones.available.names): substr(zone,-1,-1)][count.index]}-oss94-mta99-app-ig01" instances = element((module.google_vm[*].google_instance_id), count.index) }
terraform.tfvars
project = "gcp-test01" region = "us-central1" num_instances = "6" image_project = "gcp-kcfn01" image_name = "centos7-kent-v20220105" instance_name = "kcfn01-cfn01-apoc01-app" tags = ["oss01-mta-app", "usc1-sss-oss-snet01-local"] machine_type = "n1-standard-4" disk_size = "50" disk_type = "pd-standard" boot_disk_size = "50" boot_disk_type = "pd-standard" network = "cfn01-sss-net" subnetwork = "cfn01-usc1-sss-oss-snet01" subnetwork_project = "gcp-kcfn01"
问题根源
- UIG数量被限制:当前
count逻辑取可用区数量和实例数的较小值,当实例数多于可用区时,UIG的数量最多等于可用区数,无法覆盖所有实例。 - 单UIG仅绑定单个实例:
instances参数通过element仅取单个实例ID,没有将对应可用区下的所有实例批量加入UIG。
注意:GCP非托管实例组(UIG)属于单一可用区,每个UIG只能包含同一可用区的实例,因此需要为每个可用区创建一个UIG,并将该可用区下的所有实例加入对应UIG。
修正方案
步骤1:确保VM实例按可用区均匀分配
假设module.google_vm的count设为var.num_instances,且实例的可用区通过取模分配(需确保VM模块支持传入zone参数):
module "google_vm" { source = "<你的VM模块路径>" count = var.num_instances # 其他参数... zone = var.zone == null ? data.google_compute_zones.available.names[count.index % length(data.google_compute_zones.available.names)] : var.zone # 其余VM配置参数... }
步骤2:修正UIG模块配置
按可用区数量创建UIG,每个UIG加入对应可用区的所有实例:
data "google_compute_zones" "available" { project = var.project region = var.region } module "google_uig" { source = "C:/Users/xxxx/OneDrive/Desktop/New folder/terraform-google-core/modules/compute_engine_uig" depends_on = [module.google_vm] project = var.project # 每个可用区创建一个UIG count = length(data.google_compute_zones.available.names) zone = data.google_compute_zones.available.names[count.index] # 生成唯一的UIG名称,基于可用区后缀 name = "use1${substr(data.google_compute_zones.available.names[count.index], -1, -1)}-oss94-mta99-app-ig01" # 筛选当前可用区下的所有实例ID instances = [ for vm in module.google_vm : vm.google_instance_id if vm.zone == data.google_compute_zones.available.names[count.index] ] }
关键说明
- UIG与可用区绑定:GCP非托管实例组无法跨可用区,因此必须为每个可用区单独创建UIG。
- 实例筛选逻辑:通过
for循环+条件判断,将同一可用区的所有实例ID收集为列表,传入instances参数,实现批量绑定。 - 变量类型修正:注意
var.num_instances当前是字符串类型("6"),建议改为数字类型(6),避免类型转换问题。
内容的提问来源于stack exchange,提问作者Sagar Saxena
相关产品推荐
相关产品推荐

