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

如何用Terraform的azapi_update_resource扩展NIC的IP配置并保留原有配置?

问题描述

我有如下配置的Azure NIC:

resource "azurerm_network_interface" "nic" {
  name                 = "nic1"
  location             = "West Europe"
  resource_group_name  = "MyRG"
  enable_ip_forwarding = true

  ip_configuration {
    name                          = "ipconfig1"
    subnet_id                     = azurerm_subnet.publicsubnet.id
    private_ip_address_allocation = "Static"
    private_ip_address            = "10.0.0.10"
    public_ip_address_id          = azurerm_public_ip.ClusterPublicIP.id
  }
}

该NIC已分配公网IP,最终供Azure防火墙使用。我希望为这个NIC添加多个IP地址,且这些IP地址在创建应用时添加。我已能通过以下代码创建公网IP:

resource "azurerm_public_ip" "pip" {
  allocation_method   = "Static"
  location            = "West Europe"
  name                = "pip-${var.appname}"
  resource_group_name = var.rgName
}

但azurerm provider中没有单独添加IP配置到已有NIC的资源,因为ip_configuration块必须嵌入在azurerm_network_interface内。

因此我尝试使用azapi provider,代码如下:

resource "azapi_update_resource" "add_pip_to_forti" {
  type        = "Microsoft.Network/networkInterfaces@2023-06-01"
  resource_id = var.nicResourceId

  body = jsonencode({
    properties = {
      ipConfigurations = [
        {
          name = "assignedByTF"
          etag = "W/\"50b5631e-6e90-4196-a2df-d5c280c41b73\""
          type = "Microsoft.Network/networkInterfaces/ipConfigurations"
          properties = {
            privateIPAddress          = "10.0.0.200"
            privateIPAllocationMethod = "Static"
            publicIPAddress = {
              id = azurerm_network_interface.nic.id
            }
            subnet = {
              id = "/subscriptions/my-sub/resourceGroups/my-rg/providers/Microsoft.Network/virtualNetworks/hub-europe/subnets/pubsub"
            }
            primary                 = false
            privateIPAddressVersion = "IPv4"
          }
        }
      ]
    }
  })
}

但该操作会删除NIC上的现有配置,且因主ip_configuration无法删除而失败。

我的问题是:如何修改上述azapi_update_resource块,通过Terraform扩展IP配置数组并保留现有值?


解决方案

要保留现有IP配置并添加新配置,核心是先获取NIC当前配置,再将新配置合并到ipConfigurations数组,而非直接覆盖。具体实现如下:

1. 获取NIC现有配置

使用azapi_resource_data数据源拉取目标NIC的完整属性,包括已有的IP配置:

data "azapi_resource_data" "existing_nic" {
  type        = "Microsoft.Network/networkInterfaces@2023-06-01"
  resource_id = var.nicResourceId
}

2. 合并配置并更新NIC

修改azapi_update_resource,通过concat函数将现有IP配置与新配置合并,同时注意:

  • 复用数据源返回的etag,避免更新冲突
  • 新配置的primary必须设为false(主IP只能有一个)
  • publicIPAddress.id指向你创建的公网IP资源(而非NIC自身)
  • 子网ID可直接复用现有配置中的值

修改后的代码:

resource "azapi_update_resource" "add_pip_to_forti" {
  type        = "Microsoft.Network/networkInterfaces@2023-06-01"
  resource_id = var.nicResourceId
  etag        = data.azapi_resource_data.existing_nic.etag

  body = jsonencode({
    properties = {
      ipConfigurations = concat(
        data.azapi_resource_data.existing_nic.properties.ipConfigurations,
        [
          {
            name = "ipconfig-${var.appname}"
            properties = {
              privateIPAddress          = "10.0.0.200" # 按需设置静态IP,或改为Dynamic
              privateIPAllocationMethod = "Static"
              publicIPAddress = {
                id = azurerm_public_ip.pip.id
              }
              subnet = {
                id = data.azapi_resource_data.existing_nic.properties.ipConfigurations[0].properties.subnet.id
              }
              primary                 = false
              privateIPAddressVersion = "IPv4"
            }
          }
        ]
      )
    }
  })
}

注意事项

  • 批量添加多个IP时,可将新配置存入列表变量后再合并
  • 静态私网IP需确保在子网地址范围内且未被占用
  • 若NIC由Terraform原生资源管理,后续请勿修改原azurerm_network_interface的ip_configuration块,避免配置冲突

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.06 20:03:11