Skip to content

Instantly share code, notes, and snippets.

@gerrytan
Last active April 10, 2025 02:57
Show Gist options
  • Select an option

  • Save gerrytan/0da61fdba869b8796e990e0b42225e7a to your computer and use it in GitHub Desktop.

Select an option

Save gerrytan/0da61fdba869b8796e990e0b42225e7a to your computer and use it in GitHub Desktop.
azurerm: unable to update tags of NIC attached to a private endpoint
# Problem:
# tags of network interface card (NIC) attached to a private endpoint (PE) cannot be updated via Terraform (TF)
# Root cause analysis:
# TF performs a PUT over the NIC, and it
# fails with 400 response if the NIC is attached to a PE, possibly
# other attachments too. When PATCH is performed via CLI, the NIC tag update works fine
# Steps to reproduce:
# 1. TF apply the resources with the NIC commented out, when PE is created, it will have a NIC that is not yet onboarded to TF
# 2. Use CLI command az network nic show -g my-rg-name -n my.nic.name to get the NIC variables values, and comment out the NIC resource
# 3. TF apply again to import the NIC into TF state
# 4. Update the NIC tags in the TF code
#
# Expected: NIC tags updated
# Actual: Got following error
#
# Error: updating Network Interface (Subscription: "*****-****"
# Resource Group Name: "my-rg-name"
# Network Interface Name: "my-nic-name"): performing CreateOrUpdate: unexpected
# status 400 (400 Bad Request) with error:
# CannotModifyNicAttachedToPrivateEndpoint: Network interface
# /subscriptions/0000-000-000/resourceGroups/my-rg-name/providers/Microsoft.Network/networkInterfaces/my.nic.name
# is linked to a private endpoint
# /subscriptions/000-00-000/resourceGroups/my-rg-name/providers/Microsoft.Network/privateEndpoints/my-pe-name.
# It can not be modified by user.
terraform {
required_providers {
azurerm = {
source = "hashicorp/azurerm"
version = ">= 4.0.0"
}
}
}
provider "azurerm" {
features {}
# export ARM_SUBSCRIPTION_ID env variable to avoid hardcoding the subscription_id here
}
variable "prefix" {
type = string
}
variable "prefix_short" {
type = string
}
variable "location" {
type = string
}
# Get these values via
# az network nic show -g my-rg-name -n my.nic.name
# after initial private endpoint creation
variable "nic_id" {
type = string
}
variable "nic_name" {
type = string
}
variable "nic_ipconfig_name" {
type = string
}
# Resource Group ----------------------------
resource "azurerm_resource_group" "rg" {
name = "${var.prefix}-rg"
location = var.location
lifecycle {
ignore_changes = [tags]
}
}
# VNet --------------------------------
resource "azurerm_virtual_network" "vnet" {
name = "${var.prefix}-vnet"
resource_group_name = azurerm_resource_group.rg.name
location = azurerm_resource_group.rg.location
address_space = ["10.0.0.0/16"]
}
resource "azurerm_subnet" "subnet" {
name = "${var.prefix}-subnet"
resource_group_name = azurerm_resource_group.rg.name
virtual_network_name = azurerm_virtual_network.vnet.name
address_prefixes = ["10.0.0.0/24"]
}
# Storage Account ----------------------------
# To test private endpoint
resource "azurerm_storage_account" "sa" {
name = "${var.prefix_short}st"
resource_group_name = azurerm_resource_group.rg.name
location = azurerm_resource_group.rg.location
account_tier = "Standard"
account_replication_type = "LRS"
}
# Private endpoint ----------------------------
resource "azurerm_private_endpoint" "pe" {
name = "${var.prefix}-pe"
location = azurerm_resource_group.rg.location
resource_group_name = azurerm_resource_group.rg.name
subnet_id = azurerm_subnet.subnet.id
private_service_connection {
name = "${var.prefix}-psc"
private_connection_resource_id = azurerm_storage_account.sa.id
is_manual_connection = false
subresource_names = ["blob"]
}
}
# NIC ----------------------------
import {
id = var.nic_id
to = azurerm_network_interface.nic
}
resource "azurerm_network_interface" "nic" {
accelerated_networking_enabled = false
ip_forwarding_enabled = false
location = azurerm_resource_group.rg.location
name = var.nic_name
resource_group_name = azurerm_resource_group.rg.name
virtual_machine_id = null
ip_configuration {
name = var.nic_ipconfig_name
primary = true
private_ip_address = "10.0.0.4"
private_ip_address_allocation = "Dynamic"
private_ip_address_version = "IPv4"
subnet_id = azurerm_subnet.subnet.id
}
tags = {
foo = "bar"
} # Update this to reproduce customer problem
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment