如何使用flatten循环读取多VM区域属性?求现有配置优化建议
问题分析与解决方案
1. 当前循环逻辑的核心问题
你的嵌套flatten循环存在跨区域关联VM的错误:
- 内层循环遍历
var.VirtualMachine的所有顶层键(Primary/Secondary),而非当前reg_key对应的VM组,导致生成大量无效的区域-VM配对(比如Primary区域关联Secondary的VM),后续过滤条件虽然能剔除部分无效项,但会浪费计算资源且可能引发键重复问题。
2. 循环逻辑修正
调整内层循环,仅遍历当前区域下的VM,并优化过滤逻辑减少无效迭代:
advmAccess = { for k, v in flatten([ for reg_key, reg in module.regions : [ for lz_key, lz in local.landingZone : [ for net_key, net in var.Network : [ for sn_key, sn in net.Subnets : [ # 仅遍历当前region对应的VM集合 for vm_key, vm in var.VirtualMachine[reg_key] : { reg_key = reg_key lz_key = lz_key net_key = net_key sn_key = sn_key vm_key = vm_key vm_size = vm.Size vm_os = vm.Disks.OS vm_image = vm.Image # 预留扩展字段:若需处理VM扩展,添加此行 # vm_extensions = lookup(vm, "Extensions", {}) } ] if sn_key == "Access" ] ] if lz_key == reg_key # 提前过滤匹配的landing zone,减少循环次数 ] ]) : "${v.reg_key}.${v.sn_key}.${v.vm_key}" => v # 添加vm_key避免键重复 if v.net_key == v.reg_key # 简化条件:利用提前过滤的lz_key匹配 }
3. VM配置是否需要修改?
当前VM配置结构(按region分组)是合理的,无需大幅修改,但需注意两点:
- 确保
var.VirtualMachine的顶层键名(Primary/Secondary)与module.regions输出的reg_key完全一致,避免因名称不匹配导致无法找到对应VM。 - 若需添加VM扩展,可直接在每个VM对象中新增
Extensions字段,示例:
runtime-1 = { Size = "Standard_B2ms" Disks = { ... } Image = { ... } Extensions = { CustomScript = { Publisher = "Microsoft.Compute" Type = "CustomScriptExtension" TypeHandlerVersion = "1.10" Settings = { commandToExecute = "echo Hello World" } } } }
4. VM扩展处理建议
- 用变量(var)存储扩展:如果每个VM的扩展配置不同,直接在
var.VirtualMachine的VM对象中定义Extensions字段最直接,支持按需自定义。 - 用本地值(local)处理共享扩展:如果多个VM需要相同的扩展配置,可在locals中定义共享扩展并合并到VM配置:
locals { shared_vm_extensions = { CustomScript = { ... } # 共享扩展配置 } merged_vm_config = { for reg_key, vms in var.VirtualMachine : reg_key => { for vm_key, vm in vms : vm_key => merge(vm, { Extensions = merge(local.shared_vm_extensions, lookup(vm, "Extensions", {})) }) } } }
之后在循环中用local.merged_vm_config[reg_key]替代var.VirtualMachine[reg_key]即可。
内容的提问来源于stack exchange,提问作者Mahs
相关产品推荐
相关产品推荐

