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

如何通过Terraform跨Azure订阅复用默认NSG至多VM/NIC

跨订阅NSG关联的Terraform实现方案

要实现将一个Azure订阅中的NSG附加到其他订阅的VM或NIC上,核心是配置多订阅的Terraform Azure Provider,并确保权限覆盖两个订阅,以下是具体步骤和代码示例:

1. 配置多订阅Azure Provider

需要初始化两个Provider实例,分别对应源订阅(创建/托管NSG的订阅)和目标订阅(VM/NIC所在的订阅),通过alias区分:

# 源订阅Provider(用于创建/读取NSG)
provider "azurerm" {
  alias           = "source_sub"
  subscription_id = "源订阅ID"
  tenant_id       = "租户ID"
  # 认证方式按需选择(服务主体、Azure CLI等)
  client_id       = "服务主体ID"
  client_secret   = "服务主体密钥"
}

# 目标订阅Provider(用于管理VM/NIC)
provider "azurerm" {
  alias           = "target_sub"
  subscription_id = "目标订阅ID"
  tenant_id       = "租户ID"
  client_id       = "服务主体ID"
  client_secret   = "服务主体密钥"
}

注意:使用的服务主体必须同时拥有源订阅的NSG读取权限和目标订阅的NIC修改/创建权限,否则会触发权限不足错误。

2. 在源订阅中创建或引用NSG

场景1:创建新的跨订阅NSG

如果NSG尚未存在,在源订阅中定义NSG资源:

resource "azurerm_network_security_group" "cross_sub_nsg" {
  provider            = azurerm.source_sub
  name                = "cross-sub-default-nsg"
  location            = "eastus"
  resource_group_name = "源订阅资源组名"

  # 按需添加安全规则示例
  security_rule {
    name                       = "allow-rdp"
    priority                   = 100
    direction                  = "Inbound"
    access                     = "Allow"
    protocol                   = "Tcp"
    source_port_range          = "*"
    destination_port_range     = "3389"
    source_address_prefix      = "*"
    destination_address_prefix = "*"
  }
}

场景2:引用已存在的NSG

如果NSG已在源订阅中创建,通过数据源直接引用:

data "azurerm_network_security_group" "existing_nsg" {
  provider            = azurerm.source_sub
  name                = "已存在的NSG名称"
  resource_group_name = "源订阅资源组名"
}

3. 在目标订阅中关联NSG到NIC/VM

方式1:关联到现有NIC

通过数据源获取目标订阅中的NIC,更新其network_security_group_id字段关联跨订阅NSG:

# 获取目标订阅中的现有NIC
data "azurerm_network_interface" "target_nic" {
  provider            = azurerm.target_sub
  name                = "目标NIC名称"
  resource_group_name = "目标订阅资源组名"
}

# 更新NIC关联跨订阅NSG
resource "azurerm_network_interface" "updated_nic" {
  provider            = azurerm.target_sub
  name                = data.azurerm_network_interface.target_nic.name
  location            = data.azurerm_network_interface.target_nic.location
  resource_group_name = data.azurerm_network_interface.target_nic.resource_group_name

  # 保留原NIC的IP配置
  ip_configuration {
    name                          = data.azurerm_network_interface.target_nic.ip_configuration[0].name
    subnet_id                     = data.azurerm_network_interface.target_nic.ip_configuration[0].subnet_id
    private_ip_address_allocation = data.azurerm_network_interface.target_nic.ip_configuration[0].private_ip_address_allocation
    public_ip_address_id          = data.azurerm_network_interface.target_nic.ip_configuration[0].public_ip_address_id
  }

  # 关联源订阅的NSG(创建新NSG用azurerm_network_security_group.cross_sub_nsg.id,引用现有则用data.azurerm_network_security_group.existing_nsg.id)
  network_security_group_id = azurerm_network_security_group.cross_sub_nsg.id
}

方式2:创建新VM时关联NSG

在目标订阅中创建VM时,直接在NIC配置中指定跨订阅NSG的ID:

# 获取目标订阅中的子网
data "azurerm_subnet" "target_subnet" {
  provider            = azurerm.target_sub
  name                = "目标子网名称"
  virtual_network_name = "目标VNet名称"
  resource_group_name = "目标订阅资源组名"
}

# 创建关联跨订阅NSG的新NIC
resource "azurerm_network_interface" "new_vm_nic" {
  provider            = azurerm.target_sub
  name                = "new-vm-nic"
  location            = "eastus"
  resource_group_name = "目标订阅资源组名"

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

  network_security_group_id = azurerm_network_security_group.cross_sub_nsg.id
}

# 创建VM并使用上述NIC
resource "azurerm_linux_virtual_machine" "new_cross_sub_vm" {
  provider            = azurerm.target_sub
  name                = "cross-sub-demo-vm"
  resource_group_name = "目标订阅资源组名"
  location            = "eastus"
  size                = "Standard_D2s_v3"
  admin_username      = "adminuser"
  network_interface_ids = [azurerm_network_interface.new_vm_nic.id]

  admin_ssh_key {
    username   = "adminuser"
    public_key = file("~/.ssh/id_rsa.pub")
  }

  os_disk {
    caching              = "ReadWrite"
    storage_account_type = "Premium_LRS"
  }

  source_image_reference {
    publisher = "Canonical"
    offer     = "0001-com-ubuntu-server-jammy"
    sku       = "22_04-lts"
    version   = "latest"
  }
}

核心注意事项

  • 权限要求:服务主体在源订阅需拥有Network Security Groups Reader角色,在目标订阅需拥有Network Contributor角色(或更细粒度的NIC修改权限)。
  • 区域一致性:NSG与目标NIC必须位于同一Azure区域,否则无法关联。
  • 状态管理:Terraform状态会记录跨订阅资源关联,后续变更需确保Provider配置稳定。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.01 16:37:33