如何使用Terraform动态将多VNET的多子网添加到Azure Service Bus防火墙
实现方案
这个需求可以通过Terraform实现,核心通过重构本地变量结构、嵌套获取数据源、动态块生成规则三步完成,具体配置如下:
第一步:重构locals块,绑定VNET与对应子网关系
先把分散定义的VNET和子网整合为映射结构,方便后续遍历关联,后续新增/删除VNET或子网仅需要修改该映射即可:
locals { # 键为VNET名称,值为该VNET下对应的子网名称列表 vnet_subnet_map = { "vnet1" = ["vnet1-subnet1", "vnet1-subnet2", "vnet1-subnet3"] "vnet2" = ["vnet2-subnet1", "vnet2-subnet2", "vnet2-subnet3"] "vnet3" = ["vnet3-subnet1", "vnet3-subnet2", "vnet3-subnet3"] } # 展开为扁平化子网列表,每个元素包含所属VNET名称和子网名称,解决嵌套遍历复杂度问题 flattened_subnets = flatten([ for vnet_name, subnets in local.vnet_subnet_map : [ for subnet_name in subnets : { vnet_name = vnet_name subnet_name = subnet_name } ] ]) }
第二步:修正数据源定义,批量获取所有VNET和子网信息
# 批量拉取所有目标VNET的数据源 data "azurerm_virtual_network" "all_vnets" { for_each = local.vnet_subnet_map name = each.key resource_group_name = "westy" } # 批量拉取所有目标子网的数据源,用VNET名+子网名作为唯一key避免索引冲突 data "azurerm_subnet" "all_subnets" { for_each = { for item in local.flattened_subnets : "${item.vnet_name}_${item.subnet_name}" => item } name = each.value.subnet_name resource_group_name = "westy" virtual_network_name = each.value.vnet_name }
第三步:使用dynamic动态块批量生成网络规则
resource "azurerm_resource_group" "example" { name = "example-resources" location = "West Europe" } resource "azurerm_servicebus_namespace" "example" { name = "example-sb-namespace" location = azurerm_resource_group.example.location resource_group_name = azurerm_resource_group.example.name sku = "Premium" capacity = 1 } resource "azurerm_servicebus_namespace_network_rule_set" "example" { namespace_name = azurerm_servicebus_namespace.example.name resource_group_name = azurerm_resource_group.example.name default_action = "Deny" trusted_services_allowed = true # 自动遍历所有子网,生成对应数量的network_rules规则,无需手动重复编写 dynamic "network_rules" { for_each = data.azurerm_subnet.all_subnets content { subnet_id = network_rules.value.id ignore_missing_vnet_service_endpoint = false } } ip_rules = ["125.123.142.174"] }
内容的提问来源于stack exchange,提问作者devops-admin
相关产品推荐
相关产品推荐

