如何在Terraform中使用循环创建虚拟网络子网、NSG安全规则并完成关联
Terraform Azure 网络资源批量创建实现方案
以下方案通过Terraform的for_each和dynamic循环能力实现批量资源创建,全程无需硬编码资源参数,调整配置仅需修改变量值即可。
1. 变量定义(variables.tf)
先定义可配置的参数,方便后续扩容或调整规则:
# VNet基础配置 variable "vnet_config" { type = object({ resource_group_name = string location = string name = string address_space = list(string) }) default = { resource_group_name = "your-rg-name" location = "chinanorth3" name = "demo-vnet" address_space = ["10.0.0.0/16"] } } # 子网配置列表,默认配置5个子网,可按需增减 variable "subnet_list" { type = list(object({ name = string address_prefix = string })) default = [ { name = "subnet-01" address_prefix = "10.0.1.0/24" }, { name = "subnet-02" address_prefix = "10.0.2.0/24" }, { name = "subnet-03" address_prefix = "10.0.3.0/24" }, { name = "subnet-04" address_prefix = "10.0.4.0/24" }, { name = "subnet-05" address_prefix = "10.0.5.0/24" } ] } # NSG安全规则列表,可按需添加/删除规则 variable "nsg_security_rules" { type = list(object({ name = string priority = number direction = string access = string protocol = string source_port_range = string destination_port_range = string source_address_prefix = string destination_address_prefix = string })) default = [ { name = "allow-ssh-inbound" priority = 100 direction = "Inbound" access = "Allow" protocol = "Tcp" source_port_range = "*" destination_port_range = "22" source_address_prefix = "*" destination_address_prefix = "*" }, { name = "allow-http-inbound" priority = 101 direction = "Inbound" access = "Allow" protocol = "Tcp" source_port_range = "*" destination_port_range = "80" source_address_prefix = "*" destination_address_prefix = "*" }, { name = "allow-all-outbound" priority = 100 direction = "Outbound" access = "Allow" protocol = "*" source_port_range = "*" destination_port_range = "*" source_address_prefix = "*" destination_address_prefix = "*" } ] }
2. 核心资源逻辑(main.tf)
# 已存在资源组可跳过该资源块 resource "azurerm_resource_group" "demo" { name = var.vnet_config.resource_group_name location = var.vnet_config.location } # 创建虚拟网络 resource "azurerm_virtual_network" "demo" { name = var.vnet_config.name address_space = var.vnet_config.address_space location = azurerm_resource_group.demo.location resource_group_name = azurerm_resource_group.demo.name } # 批量创建子网:将子网列表转为map后用for_each循环,避免count的索引偏移问题 resource "azurerm_subnet" "demo" { for_each = { for subnet in var.subnet_list : subnet.name => subnet } name = each.value.name resource_group_name = azurerm_resource_group.demo.name virtual_network_name = azurerm_virtual_network.demo.name address_prefixes = [each.value.address_prefix] } # 创建NSG,用dynamic块批量生成安全规则 resource "azurerm_network_security_group" "demo" { name = "demo-nsg" location = azurerm_resource_group.demo.location resource_group_name = azurerm_resource_group.demo.name dynamic "security_rule" { for_each = var.nsg_security_rules content { name = security_rule.value.name priority = security_rule.value.priority direction = security_rule.value.direction access = security_rule.value.access protocol = security_rule.value.protocol source_port_range = security_rule.value.source_port_range destination_port_range = security_rule.value.destination_port_range source_address_prefix = security_rule.value.source_address_prefix destination_address_prefix = security_rule.value.destination_address_prefix } } } # 批量关联子网与NSG resource "azurerm_subnet_network_security_group_association" "demo" { for_each = azurerm_subnet.demo subnet_id = each.value.id network_security_group_id = azurerm_network_security_group.demo.id }
3. 关键说明
- 子网创建使用
for_each循环,后续增删子网时不会触发其他正常子网的重建,比count更适合该场景 - NSG规则通过
dynamic块批量生成,新增/删除规则仅需修改nsg_security_rules变量即可,无需调整NSG资源逻辑 - 所有子网默认关联同一个NSG,如果需要不同子网关联不同NSG,可在
subnet_list变量中新增NSG标识字段,对应创建多个NSG资源后调整关联逻辑即可
内容的提问来源于stack exchange,提问作者Pradeep
相关产品推荐
相关产品推荐

