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

Terraform部署Azure:子网与网络安全组关联异常问题

问题原因

你遇到的错误核心是Azure平台的限制:一个子网只能关联一个网络安全组(NSG),无法同时绑定多个NSG。

你的脚本里尝试给同一个subnet-test-subnet子网创建两个azurerm_subnet_network_security_group_association资源,这直接违反了Azure的子网-NSG绑定规则。当Terraform尝试创建第二个关联时,发现子网已经被第一个NSG绑定,就会抛出资源已存在的错误(本质是状态冲突)。

解决方案

根据你的需求,有几种可行的处理方式:

1. 合并NSG规则到单个NSG

如果两个NSG的规则都是针对这个子网的,把subnet-test-nsg-1和subnet-test-nsg-2里的安全规则合并到同一个NSG中,只保留一个关联资源:

# 合并后的NSG
resource "azurerm_network_security_group" "merged_nsg" {
  name                = "subnet-test-merged-nsg"
  location            = azurerm_resource_group.rg_subnet_test.location
  resource_group_name = azurerm_resource_group.rg_subnet_test.name

  # 在这里添加原来两个NSG里的所有安全规则
  security_rule {
    # 来自nsg1的规则示例
    name                       = "allow-http-in"
    priority                   = 100
    direction                  = "Inbound"
    access                     = "Allow"
    protocol                   = "Tcp"
    source_port_range          = "*"
    destination_port_range     = "80"
    source_address_prefix      = "*"
    destination_address_prefix = "*"
  }

  security_rule {
    # 来自nsg2的规则示例
    name                       = "allow-ssh-in"
    priority                   = 200
    direction                  = "Inbound"
    access                     = "Allow"
    protocol                   = "Tcp"
    source_port_range          = "*"
    destination_port_range     = "22"
    source_address_prefix      = "*"
    destination_address_prefix = "*"
  }
}

# 只保留一个关联
resource "azurerm_subnet_network_security_group_association" "association" {
  subnet_id                 = azurerm_subnet.subnet_germany.id
  network_security_group_id = azurerm_network_security_group.merged_nsg.id
}

2. 拆分子网,每个子网绑定一个NSG

如果必须使用两个独立的NSG,可以把原子网的地址段拆分,创建两个子网,分别绑定对应的NSG:

# 第一个子网
resource "azurerm_subnet" "subnet_germany_1" {
  name                 = "subnet-test-subnet-1"
  address_prefixes     = ["10.100.2.0/25"]
  resource_group_name  = azurerm_virtual_network.vnet_subnet_test.resource_group_name
  virtual_network_name = azurerm_virtual_network.vnet_subnet_test.name
}

# 第二个子网
resource "azurerm_subnet" "subnet_germany_2" {
  name                 = "subnet-test-subnet-2"
  address_prefixes     = ["10.100.2.128/25"]
  resource_group_name  = azurerm_virtual_network.vnet_subnet_test.resource_group_name
  virtual_network_name = azurerm_virtual_network.vnet_subnet_test.name
}

# 关联第一个NSG到子网1
resource "azurerm_subnet_network_security_group_association" "association1" {
  subnet_id                 = azurerm_subnet.subnet_germany_1.id
  network_security_group_id = azurerm_network_security_group.app_server_nsg_1.id
}

# 关联第二个NSG到子网2
resource "azurerm_subnet_network_security_group_association" "association2" {
  subnet_id                 = azurerm_subnet.subnet_germany_2.id
  network_security_group_id = azurerm_network_security_group.app_server_nsg_2.id
}

3. 给虚拟机直接绑定NSG(如果适用)

如果你的目标是给不同的虚拟机应用不同的安全规则,可以跳过子网绑定,直接给虚拟机的网络接口(NIC)绑定NSG,这样单个子网下的不同VM可以使用不同的NSG:

# 虚拟机网络接口示例
resource "azurerm_network_interface" "vm_nic_1" {
  name                = "vm-nic-1"
  location            = azurerm_resource_group.rg_subnet_test.location
  resource_group_name = azurerm_resource_group.rg_subnet_test.name

  ip_configuration {
    name                          = "internal"
    subnet_id                     = azurerm_subnet.subnet_germany.id
    private_ip_address_allocation = "Dynamic"
  }
}

# 给NIC绑定第一个NSG
resource "azurerm_network_interface_security_group_association" "nic_nsg_1" {
  network_interface_id      = azurerm_network_interface.vm_nic_1.id
  network_security_group_id = azurerm_network_security_group.app_server_nsg_1.id
}

内容的提问来源于stack exchange,提问作者s3b

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.20 18:53:15