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.6k stars 4.65k forks source link

Azurerm_public_ip forces replacement due to ip_tags {} -> null #17112

Open fheinonen opened 2 years ago

fheinonen commented 2 years ago

Is there an existing issue for this?

Community Note

Terraform Version

1.2.2

AzureRM Provider Version

3.9.0

Affected Resource(s)/Data Source(s)

azurerm_public_ip

Terraform Configuration Files

resource "azurerm_public_ip" "example" {
    name                = "example_public_ip"
    location            = azurerm_resource_group.example.location
    resource_group_name = azurerm_resource_group.example.name
    allocation_method   = "Static"
    sku                 = "Standard"
}

Debug Output/Panic Output

"module": "module.example",
      "mode": "managed",
      "type": "azurerm_public_ip",
      "name": "example",
      "provider": "provider[\"registry.terraform.io/hashicorp/azurerm\"]",
      "instances": [
        {
          "index_key": 0,
          "schema_version": 0,
          "attributes": {
            "allocation_method": "Static",
            "availability_zone": "Zone-Redundant",
            "domain_name_label": null,
            "fqdn": null,
            "id": "example",
            "idle_timeout_in_minutes": 4,
            "ip_address": "example_ip",
            "ip_tags": {},
            "ip_version": "IPv4",
            "location": "westeurope",
            "name": "example",
            "public_ip_prefix_id": null,
            "resource_group_name": "example",
            "reverse_fqdn": null,
            "sku": "Standard",
            "sku_tier": "Regional",
            "tags": {
              "example": "general",
            },
            "timeouts": null,
            "zones": []
          },

{
  "name": "example",
  "id": "example",
  "etag": "W/\"example\"",
  "location": "westeurope",
  "tags": {
    "example": "general"
  },
  "zones": [
    "1",
    "2",
    "3"
  ],
  "properties": {
    "provisioningState": "Succeeded",
    "resourceGuid": "example",
    "ipAddress": "example_ip",
    "publicIPAddressVersion": "IPv4",
    "publicIPAllocationMethod": "Static",
    "idleTimeoutInMinutes": 4,
    "ipTags": [],
    "ipConfiguration": {
      "id": "example"
    }
  },
  "type": "Microsoft.Network/publicIPAddresses",
  "sku": {
    "name": "Standard",
    "tier": "Regional"
  }

Expected Behaviour

Not having an optional field doesn't force a replacement of a resource.

Actual Behaviour

Running terraform plan on an existing resource upgrading from terraform 1.0.0 and Azure RM 2.84.0, with no ip_tags defined. This also happens when you insert a tag. - ip_tags = {} -> null -> null # forces replacement everything else is untouched

Steps to Reproduce

  1. terraform plan

Important Factoids

No response

References

No response

magodo commented 2 years ago

@fheinonen Thank you for submitting this! The replacement is caused due to the zones rather than ip_tags. This breaking change is as expected between two major versions and is recorded here: https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/guides/3.0-upgrade-guide#resource-azurerm_public_ip.

fheinonen commented 2 years ago

Thanks for the quick reply. The explanation on the document page and the exhibited behaviour are not easily understood as a causal relationship.

mwcotey commented 2 years ago

Encountering the same issue. Also agree the link breaks down the use of "zones" but does not indicate why when I import the existing resource (Regional) and run "tf plan" it wants to destroy/replace the public IPs.

  - zones                   = [
      - "1",
      - "2",
      - "3",
    ] -> null # forces replacement
magodo commented 2 years ago

The fix is as simple as modifying your configuration to be the same as the remote state. For this case, just add a property zones = [1,2,3]. Afterwards, you might want to do a terraform apply -refresh-only to sync the state.

The sanity behind can be found from here: https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/guides/3.0-upgrade-guide#behavioural-updates

drjwelch commented 2 years ago

Changing from azurerm provider v2 to v3 Azurerm_public_ip forces replacement due to zones [] -> null

I also had this problem. I wasn't clear what I needed to do just from the comment above, but if anyone else arrives here with the same issue, just add "zones = [1,2,3]" in the public IP definition in your tf file. TF no longer wants to destroy the resource.

e.g. BEFORE

resource "azurerm_public_ip" "bastion_pip" {
  name                = "${var.resource_prefix}-bastion-pip"
  location            = var.location
  resource_group_name = azurerm_resource_group.bastion_rg.name
  allocation_method   = "Static"
  sku                 = "Standard"
  tags                = var.tags
}

AFTER

resource "azurerm_public_ip" "bastion_pip" {
  name                = "${var.resource_prefix}-bastion-pip"
  location            = var.location
  resource_group_name = azurerm_resource_group.bastion_rg.name
  allocation_method   = "Static"
  sku                 = "Standard"
  zones               = [1,2,3]                # added for azurerm v3.x
  tags                = var.tags
}