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.53k stars 4.6k forks source link

Terraform doesn't dissociate the Public IP address before deleting it and deletion fails #2566

Closed juanjojulian closed 3 years ago

juanjojulian commented 5 years ago

Community Note

Terraform (and AzureRM Provider) Version

Terraform v0.11.11

Affected Resource(s)

azurerm_network_interface azurerm_public_ip

Terraform Configuration Files

resource "azurerm_network_interface" "main" {
  count               = "${var.numberof_nics}"
  name                = "${var.hostname}-nic${count.index}"
  location            = "${var.region}"
  resource_group_name = "${var.sub-name}-${var.region}-${var.aplication}-rg"

  ip_configuration {
    name                          = "${var.hostname}-ipaddress${count.index}"
    subnet_id                     = "${var.subnet[count.index]}"
    private_ip_address_allocation = "static"
    private_ip_address            = "${var.private_ip[count.index]}"
    public_ip_address_id          = "${length(azurerm_public_ip.main.*.id) > 0 ? element(concat(azurerm_public_ip.main.*.id, list("")), count.index) : ""}"

  }
  depends_on = ["azurerm_resource_group.main"]
}

resource "azurerm_public_ip" "main" {
  count                = "${var.public_ip == "true" ? 1 : 0}"
  name                 = "${var.sub-name}-${var.region}-${var.hostname}-PublicIP${count.index}"
  location             = "${var.region}"
  resource_group_name  = "${var.sub-name}-${var.region}-${var.aplication}-rg"
  public_ip_address_allocation = "${var.public_ip_alloc}"
}

Expected Behavior

Terraform should:

  1. Dissociate Public IP
  2. Delete Public IP resource.
Terraform will perform the following actions:

  ~ module.tf-azure-vm-linux-module-srv-003.azurerm_network_interface.main
      ip_configuration.0.public_ip_address_id: "/subscriptions/mysubscription/resourceGroups/my-resourcegroup-rg/providers/Microsoft.Network/publicIPAddresses/something-srv-003-PublicIP0" => ""

  - module.tf-azure-vm-linux-module-srv-003.azurerm_public_ip.main

Actual Behavior

It seems that Terraform tries to delete the Public IP in first place before doing the dissociation and it fails.

  Enter a value: yes

module.tf-azure-vm-linux-module-srv-003.azurerm_public_ip.main: Destroying... (ID: /subscriptions/mysubscription-...something-srv-003-PublicIP0)
Releasing state lock. This may take a few moments...

Error: Error applying plan:

1 error(s) occurred:

* module.tf-azure-vm-linux-module-srv-003.azurerm_public_ip.main (destroy): 1 error(s) occurred:

* azurerm_public_ip.main: Error deleting Public IP "something-srv-003-PublicIP0" (Resource Group "my-resourcegroup-rg-rg"): network.PublicIPAddressesClient#Delete: Failure sending request: StatusCode=0 -- Original Error: Code="PublicIPAddressCannotBeDeleted" Message="Public IP address /subscriptions/mysubscriiption/resourceGroups/my-resourcegroup-rg/providers/Microsoft.Network/publicIPAddresses/something-srv-003-PublicIP0 can not be deleted since it is still allocated to resource /subscriptions/mysubscriptioin/resourceGroups/my-resourcegroup-rg/providers/Microsoft.Network/networkInterfaces/something-003-nic0/ipConfigurations/something-003-ipaddress0." Details=[]

Steps to Reproduce

  1. terraform apply
ghalevy commented 5 years ago

Any update on this?

jpbuecken commented 5 years ago

Maybe one solution would be a design change, similar to the aws or openstack provider. In both provider, the association is done in the public ip ressource (e.g. https://www.terraform.io/docs/providers/aws/r/eip.html and https://www.terraform.io/docs/providers/openstack/r/networking_floatingip_v2.html via port_id) . Another solution is to add a public_ip_attachment resource (similar to disks attachments). (Similar has been done for application_gateway_backend_address_pools_ids of https://www.terraform.io/docs/providers/azurerm/r/network_interface.html )

With that, the attachment is a dependency of public_ip resource. If you destroy the public_ip, it will destroy the dependency

fxredeyes commented 4 years ago

Any update on this? This issue is still happening since there is no public_ip_association resource that will manage the association between a public IP and a NIC. The reference of the public IP is still in the NIC so when we try to change or remove the Public IP, the provider is supposed to modify the NIC to remove the association first, then destroy the public IP. This is exactly what the plan is describing but when it comes to the apply, it starting by deleting the public IP before updating the NIC which results to an error...

miiitch commented 4 years ago

Hi, still no milestone for this?

stawii commented 4 years ago

Even if you add -target=azurerm_network_interface.main it STILL put destroying of public_ip into plan (and tries to do both in wrong order). This might be root cause or this issue. EDIT: Bug is still present in TF 0.12.24 and Azure 2.6.0 plugin..

niranjan0292 commented 4 years ago

I currently use the version Terraform v0.12.24

The issue still persists:

Error deleting Public IP "public_ip2" (Resource Group "AnsibleLab_terraform"): network.PublicIPAddressesClient#Delete: Failure sending request: StatusCode=400 -- Original Error: Code="PublicIPAddressCannotBeDeleted" Message="Public IP address /subscriptions/a12345b9-95c9-4d15-a288-abb49feaf3cc/resourceGroups/AnsibleLab_terraform/providers/Microsoft.Network/publicIPAddresses/public_ip2 can not be deleted since it is still allocated to resource /subscriptions/a12345b9-95c9-4d15-a288-abb49feaf3cc/resourceGroups/AnsibleLab_terraform/providers/Microsoft.Network/networkInterfaces/network_interface2/ipConfigurations/network_interface1_ip_configuration. In order to delete the public IP, disassociate/detach the Public IP address from the resource. To learn how to do this, see aka.ms/deletepublicip." Details=[]

One has to manually remove the Public IP address binding at the NIC level and then the successful deletion happens

TechArtistG commented 4 years ago

I get the same error with Virtual Gateways not NICs but same underlying problem

Xat59 commented 3 years ago

Same behavior here with the followings :

This is really annoying. Any workaround ?

c4m4 commented 3 years ago

This bug is open from Dec 21, 2018 :(

zwoefler commented 3 years ago

Has anybody a workaround, except for manually going into the Azure portal?!

jrgwv commented 3 years ago

Still occurs, I was hoping this would be fixed in a newer version of the provider but only manually going in to the front end configuration and removing the IP and load balancing rules works to allow a delete.

Terraform v0.12.29

GarethOates commented 3 years ago

Experiencing the same problem with terraform version v0.13.4 and azurerm provider v2.37.0

darren-johnson commented 3 years ago

I'm getting this too with v0.13.5 and azurerm v2.38.0

sohel-m commented 3 years ago

Any reason why this issue is not being looked into ? Valid comments above are marked as off-topic :( This issue still persists with terraform v0.13.5 azurerm v2.40.0

f3r73ch commented 3 years ago

Same here ^^^

IanMoroney commented 3 years ago

It seems like this issue is resolved, or I haven't been able to reproduce the issue with a variant of the original code: Terraform version: 0.14.4 AzureRM Provider version: 2.31.1

@sohel-m , @f3r73ch , @juanjojulian , @ghalevy , @jpbuecken , are you able to reproduce the issue in your own configs now? If you can, please provide some code to reproduce the issue and I can take a look.

Code:

resource "azurerm_network_interface" "main" {
  count               = "1"
  name                = "test-nic${count.index}"
  location            = var.we_region
  resource_group_name = azurerm_resource_group.we_infra_rg.name

  ip_configuration {
    name                          = "test-ipaddress${count.index}"
    subnet_id                     = azurerm_subnet.we_aks_es_subnet.id
    private_ip_address_allocation = "dynamic"
    public_ip_address_id          = length(azurerm_public_ip.main.*.id) > 0 ? element(concat(azurerm_public_ip.main.*.id, list("")), count.index) : ""

  }
}

resource "azurerm_public_ip" "main" {
  count                = "1"
  name                 = "test-PublicIP${count.index}"
  location             = var.we_region
  resource_group_name  = azurerm_resource_group.we_infra_rg.name
  allocation_method    = "Static"
}

Plan:

An execution plan has been generated and is shown below.
Resource actions are indicated with the following symbols:
  - destroy

Terraform will perform the following actions:

  # azurerm_network_interface.main[0] will be destroyed
  - resource "azurerm_network_interface" "main" {
      - applied_dns_servers           = [] -> null
      - dns_servers                   = [] -> null
      - enable_accelerated_networking = false -> null
      - enable_ip_forwarding          = false -> null
      - id                            = "/subscriptions/subscriptionid/resourceGroups/resourcegroup/providers/Microsoft.Network/networkInterfaces/test-nic0" -> null
      - internal_domain_name_suffix   = "tiehfmgko0ce3ivzp53urpfyxa.ax.internal.cloudapp.net" -> null
      - location                      = "westeurope" -> null
      - name                          = "test-nic0" -> null
      - private_ip_address            = "10.22.8.255" -> null
      - private_ip_addresses          = [
          - "10.22.8.255",
        ] -> null
      - resource_group_name           = "resourcegroup" -> null
      - tags                          = {} -> null

      - ip_configuration {
          - name                          = "test-ipaddress0" -> null
          - primary                       = true -> null
          - private_ip_address            = "10.22.8.255" -> null
          - private_ip_address_allocation = "Dynamic" -> null
          - private_ip_address_version    = "IPv4" -> null
          - public_ip_address_id          = "/subscriptions/subscriptionid/resourceGroups/resourcegroup/providers/Microsoft.Network/publicIPAddresses/test-PublicIP0" -> null
          - subnet_id                     = "/subscriptions/subscriptionid/resourceGroups/we-infra-network-rg/providers/Microsoft.Network/virtualNetworks/we-inf-vnet/subnets/we-infdev-subnet" -> null
        }
    }

  # azurerm_public_ip.main[0] will be destroyed
  - resource "azurerm_public_ip" "main" {
      - allocation_method       = "Static" -> null
      - id                      = "/subscriptions/subscriptionid/resourceGroups/resourcegroup/providers/Microsoft.Network/publicIPAddresses/test-PublicIP0" -> null
      - idle_timeout_in_minutes = 4 -> null
      - ip_address              = "13.80.21.200" -> null
      - ip_version              = "IPv4" -> null
      - location                = "westeurope" -> null
      - name                    = "test-PublicIP0" -> null
      - resource_group_name     = "resourcegroup" -> null
      - sku                     = "Basic" -> null
      - tags                    = {} -> null
      - zones                   = [] -> null
    }

Plan: 0 to add, 0 to change, 2 to destroy.

Apply:

Terraform v0.14.4
Initializing plugins and modules...
azurerm_network_interface.main[0]: Destroying... [id=/subscriptions/subscriptionid/resourceGroups/resourcegroup/providers/Microsoft.Network/networkInterfaces/test-nic0]
azurerm_network_interface.main[0]: Still destroying... [id=/subscriptions/subscriptionid...ft.Network/networkInterfaces/test-nic0, 10s elapsed]
azurerm_network_interface.main[0]: Destruction complete after 12s
azurerm_public_ip.main[0]: Destroying... [id=/subscriptions/subscriptionid/resourceGroups/resourcegroup/providers/Microsoft.Network/publicIPAddresses/test-PublicIP0]
azurerm_public_ip.main[0]: Still destroying... [id=/subscriptions/subscriptionid...twork/publicIPAddresses/test-PublicIP0, 10s elapsed]
azurerm_public_ip.main[0]: Still destroying... [id=/subscriptions/subscriptionid...twork/publicIPAddresses/test-PublicIP0, 20s elapsed]
azurerm_public_ip.main[0]: Destruction complete after 21s

Apply complete! Resources: 0 added, 0 changed, 2 destroyed.
sohel-m commented 3 years ago

@IanMoroney I confirm that the above issue seems resolved after upgrading to terraform 0.14.4. :) Thank you for getting back with this.

IanMoroney commented 3 years ago

Glad to help. @tombuildsstuff , can you close this issue?

tombuildsstuff commented 3 years ago

Closing as requested above.

ghost commented 3 years 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 feel this issue should be reopened, we encourage creating a new issue linking back to this one for added context. If you feel I made an error 🤖 🙉 , please reach out to my human friends 👉 hashibot-feedback@hashicorp.com. Thanks!