Last active
April 10, 2025 02:57
-
-
Save gerrytan/0da61fdba869b8796e990e0b42225e7a to your computer and use it in GitHub Desktop.
azurerm: unable to update tags of NIC attached to a private endpoint
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| # 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