You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.29 11:06:03