hashicorp / terraform-provider-azurerm

Terraform provider for Azure Resource Manager
https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs
Mozilla Public License 2.0
4.58k stars 4.62k forks source link

Terraform can't delete NIC from VM #18915

Closed cuntoulishifu closed 1 year ago

cuntoulishifu commented 1 year ago

Is there an existing issue for this?

Community Note

Terraform Version

0.13

AzureRM Provider Version

2.89.0

Affected Resource(s)/Data Source(s)

azurerm_network_interface

Terraform Configuration Files

variable "private_ips" {
  type = set(string)
  default = ["10.108.64.100","xx.xx.64.102"]
}
variable "network_interface_ids" {
  type=list(string)
  default = ["/subscriptions/11111111-22222-3333-44444-55555/resourceGroups/aaaa-bbbb-cccccccc-rg/providers/Microsoft.Network/networkInterfaces/aaaaaaaaa-nic-xxxx"]
}
locals {

  nics = {
    for item in var.private_ips : item => item
  }

}
resource "azurerm_network_interface" "default" {
  for_each = local.nics
  name                = "nic-${var.vm_name}-${each.value}"
  location            = var.location
  resource_group_name = var.resource_group_name

  ip_configuration {
    name                          = "ipc-${var.vm_name}-${each.value}"
    subnet_id                     = data.azurerm_subnet.default.id
    private_ip_address_allocation = "Static"
    private_ip_address            = each.value
  }
  lifecycle {
    ignore_changes=all
  } 
}

resource "azurerm_windows_virtual_machine" "default" {
  name                       = var.vm_name
  location                   = var.location
  resource_group_name        = var.resource_group_name
  network_interface_ids      = concat(([for nic in azurerm_network_interface.default : nic.id]),var.network_interface_ids)
  size                       = var.vm_size
  admin_password             = var.admin_password
  admin_username             = var.admin_username
  allow_extension_operations = true
  availability_set_id        = var.availability_set_id
  computer_name              = var.vm_name
  enable_automatic_updates   = true
  priority                   = "Regular"
  provision_vm_agent         = true
  timezone                   = "Central Standard Time"

  identity {
    type = "SystemAssigned"
  }

  os_disk {
    caching              = "ReadWrite"
    storage_account_type = var.os_disk_type
  }

  source_image_reference {
    publisher = var.os_publisher
    offer     = var.os_offer
    sku       = var.os_sku
    version   = var.os_version
  }
}

Debug Output/Panic Output

Operation failed: failed running terraform apply (exit 1)

Expected Behaviour

delete azure network interface

Actual Behaviour

Error:

deleting Network Interface: (Name "nic-xxxxxxx-xx.xx.64.102" / Resource Group "xxxx-east2-xxxxxx-rg"):

network.InterfacesClient#Delete: Failure sending request: StatusCode=400 -- Original Error: Code="NicInUse" Message="Network Interface /subscriptions/aaaa-bbbbb-cccc-ddddd-eeeeeeee/resourceGroups/xxxx-east2-xxxx-rg/providers/Microsoft.Network/networkInterfaces/nic-xxxxxwin01-xx.xxx.64.102

is used by existing

resource /subscriptions/aaaa-bbbbb-cccc-ddddd-eeeeeeee/resourceGroups/xxx-xxxx-xxxxxx-RG/providers/Microsoft.Compute/virtualMachines/xxxxtestwin01.

In order to delete the network interface, it must be dissociated from the resource. To learn more, see aka.ms/deletenic." Details=[]

Steps to Reproduce

  1. create vm and set "private_ips"= ["10.108.64.100","xx.xx.64.102"]
  2. delete "xx.xx.64.102" from "private_ips",
  3. terraform plan (no error);
  4. terraform apply (got above error message )

Important Factoids

Azure China

References

No response

myc2h6o commented 1 year ago

Hi @cuntoulishifu thanks for opening the issue! The behavior here is by default in Terraform, that deletion of the dependent resource happens before updating the resource depending on it. According to https://github.com/hashicorp/terraform/blob/main/docs/destroying.md#create-before-destroy, you can reverse this dependency by setting create_before_destroy = true in the lifecycle of azurerm_network_interface.default, then the VM will be updated before deleting the NIC.

cuntoulishifu commented 1 year ago

Hi @cuntoulishifu thanks for opening the issue! The behavior here is by default in Terraform, that deletion of the dependent resource happens before updating the resource depending on it. According to https://github.com/hashicorp/terraform/blob/main/docs/destroying.md#create-before-destroy, you can reverse this dependency by setting create_before_destroy = true in the lifecycle of azurerm_network_interface.default, then the VM will be updated before deleting the NIC.

Hi @myc2h6o thanks a lot your your information! now I know more about Terraform😀! but after adding the create_before_destroy = true setting I still got the same error message ...😫

myc2h6o commented 1 year ago

@cuntoulishifu I forgot to mention, the create_before_destroy = true needs to be added before removing the NIC (private_ips entries). Could you try update the config to add create_before_destroy = true, trigger a terraform apply, and then remove the NIC? I found a similar issue #15483 for reference, which also updates a resource while deleting one of its dependent resource

rcskosir commented 1 year ago

Thank you for opening this issue. Since the behavior described in your issue is the expected behavior of Terraform. I am going to mark this issue as closed. Hopefully @myc2h6o's suggestions above are able to help you troubleshoot your configuration, if not, please feel free to ask questions in our forum: Azure Provider forum

github-actions[bot] commented 5 months ago

I'm going to lock this issue because it has been closed for 30 days ⏳. This helps our maintainers find and focus on the active issues. If you have found a problem that seems similar to this, please open a new issue and complete the issue template so we can capture all the details necessary to investigate further.