Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Azure API Resource Group casing change calling for resource replacement #8289

Closed
i-m-wisch opened this issue Aug 28, 2020 · 5 comments
Closed
Labels
upstream/microsoft Indicates that there's an upstream issue blocking this issue/PR

Comments

@i-m-wisch
Copy link

Community Note

  • Please vote on this issue by adding a 👍 reaction to the original issue to help the community and maintainers prioritize this request
  • Please do not leave "+1" or "me too" comments, they generate extra noise for issue followers and do not help prioritize the request
  • If you are interested in working on this issue or have submitted a pull request, please leave a comment

Terraform (and AzureRM Provider) Version

Started with:
Terraform v0.12.28
provider.azurerm v1.44.0

Also Tested with:
Terraform v0.12.28
provider.azurerm v2.25.0

Affected Resource(s)

  • azurerm_virtual_network_peering

Terraform Configuration Files

provider "azurerm" {
  features {}
}

provider "azurerm" {
  alias           = "dynamic"
  subscription_id = local.subscription_id
  features {}
}

locals {
  subscription_id = var.dev_subscription ? var.dev_subscription_id : var.prod_subscription_id
}

data "azurerm_virtual_network" "virtual_network" {
  name                = var.vnet_virtual_network_name
  resource_group_name = var.vnet_resource_group_name
}

data "azurerm_virtual_network" "virtual_network_peer" {
  for_each = var.vnet_peer_names
  provider = azurerm.dynamic

  name                = each.key
  resource_group_name = each.value
}

resource "azurerm_virtual_network_peering" "hub_peering" {
  for_each = var.vnet_peer_names

  name                      = "${data.azurerm_virtual_network.virtual_network.name}-to-${data.azurerm_virtual_network.virtual_network_peer[each.key].name}-PEER1"
  resource_group_name       = var.vnet_resource_group_name
  virtual_network_name      = data.azurerm_virtual_network.virtual_network.name
  remote_virtual_network_id = data.azurerm_virtual_network.virtual_network_peer[each.key].id

  allow_virtual_network_access = true
  allow_forwarded_traffic      = (var.dev_subscription ? false : true)

  allow_gateway_transit = true
  use_remote_gateways   = false
}

resource "azurerm_virtual_network_peering" "peering_to_hub" {
  for_each = var.vnet_peer_names
  provider = azurerm.dynamic

  name                      = "${data.azurerm_virtual_network.virtual_network_peer[each.key].name}-to-${data.azurerm_virtual_network.virtual_network.name}-PEER1"
  resource_group_name       = each.value
  virtual_network_name      = each.key
  remote_virtual_network_id = data.azurerm_virtual_network.virtual_network.id

  allow_virtual_network_access = true
  allow_forwarded_traffic      = true

  allow_gateway_transit = false
  use_remote_gateways   = true
}

Example portion of the module definition

  dev_subscription     = true
  prod_subscription_id = "xxxxxxxx-yyyy-zzzz-aaaa-bbbbbbbbbbbb"
  dev_subscription_id  = "aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee"

  vnet_resource_group_name        = "BDAIM-P-NA26-HUB-VNET-RGRP"
  vnet_virtual_network_name       = "BDAIM-P-NA26-HUB-VNET"
  vnet_peer_names = {
    BDAIM-D-NA26-Demo-VNET      = "BDAIM-D-NA26-Demo-RGRP"
    BDAIM-D-NA26-CONCOURSE-VNET = "BDAIM-D-NA26-Concourse-RGRP"
  }

Debug Output

Panic Output

Expected Behavior

Terraform treats the Resource Group Name as case insensitive just like the Azure API, and sees there are no changes required for the pre-existing virtual_network_peering resources.

  # module.hub_vnet_peering.azurerm_virtual_network_peering.peering_to_hub["BDAIM-D-NA26-Demo-VNET"] will be created
  + resource "azurerm_virtual_network_peering" "peering_to_hub" {
      + allow_forwarded_traffic      = true
      + allow_gateway_transit        = false
      + allow_virtual_network_access = true
      + id                           = (known after apply)
      + name                         = "BDAIM-D-NA26-Demo-VNET-to-BDAIM-P-NA26-HUB-VNET-PEER1"
      + remote_virtual_network_id    = "/subscriptions/xxxxxxxx-yyyy-zzzz-aaaa-bbbbbbbbbbbb/resourceGroups/BDAIM-P-NA26-HUB-VNET-RGRP/providers/Microsoft.Network/virtualNetworks/BDAIM-P-NA26-HUB-VNET"
      + resource_group_name          = "BDAIM-D-NA26-Demo-RGRP"
      + use_remote_gateways          = true
      + virtual_network_name         = "BDAIM-D-NA26-Demo-VNET"
    }

  # module.hub_vnet_peering.azurerm_virtual_network_peering.hub_peering["BDAIM-D-NA26-Demo-VNET"] will be created
  + resource "azurerm_virtual_network_peering" "hub_peering" {
      + allow_forwarded_traffic      = false
      + allow_gateway_transit        = true
      + allow_virtual_network_access = true
      + id                           = (known after apply)
      + name                         = "BDAIM-P-NA26-HUB-VNET-to-BDAIM-D-NA26-Demo-VNET-PEER1"
      + remote_virtual_network_id    = "/subscriptions/xxxxxxxx-yyyy-zzzz-aaaa-bbbbbbbbbbbb/resourceGroups/BDAIM-D-NA26-Demo-RGRP/providers/Microsoft.Network/virtualNetworks/BDAIM-D-NA26-Demo-VNET"
      + resource_group_name          = "BDAIM-P-NA26-HUB-VNET-RGRP"
      + use_remote_gateways          = false
      + virtual_network_name         = "BDAIM-P-NA26-HUB-VNET"
    }

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

Actual Behavior

Terraform wants to replace all virtual_network_peering resources because the API is now returning the Resource Group Name in the remote_virtual_network_id as lower case. This id is provided by the azurerm_virtual_network data source.

  # module.hub_vnet_peering.azurerm_virtual_network_peering.hub_peering["BDAIM-D-NA26-Demo-VNET"] will be created
  + resource "azurerm_virtual_network_peering" "hub_peering" {
      + allow_forwarded_traffic      = false
      + allow_gateway_transit        = true
      + allow_virtual_network_access = true
      + id                           = (known after apply)
      + name                         = "BDAIM-P-NA26-HUB-VNET-to-BDAIM-D-NA26-Demo-VNET-PEER1"
      + remote_virtual_network_id    = "/subscriptions/xxxxxxxx-yyyy-zzzz-aaaa-bbbbbbbbbbbb/resourceGroups/BDAIM-D-NA26-Demo-RGRP/providers/Microsoft.Network/virtualNetworks/BDAIM-D-NA26-Demo-VNET"
      + resource_group_name          = "BDAIM-P-NA26-HUB-VNET-RGRP"
      + use_remote_gateways          = false
      + virtual_network_name         = "BDAIM-P-NA26-HUB-VNET"
    }

  # module.hub_vnet_peering.azurerm_virtual_network_peering.peering_to_hub["BDAIM-D-NA26-CONCOURSE-VNET"] must be replaced
-/+ resource "azurerm_virtual_network_peering" "peering_to_hub" {
        allow_forwarded_traffic      = true
        allow_gateway_transit        = false
        allow_virtual_network_access = true
      ~ id                           = "/subscriptions/xxxxxxxx-yyyy-zzzz-aaaa-bbbbbbbbbbbb/resourceGroups/BDAIM-D-NA26-Concourse-RGRP/providers/Microsoft.Network/virtualNetworks/BDAIM-D-NA26-CONCOURSE-VNET/virtualNetworkPeerings/BDAIM-D-NA26-CONCOURSE-VNET-to-BDAIM-P-NA26-HUB-VNET-PEER1" -> (known after apply)
        name                         = "BDAIM-D-NA26-CONCOURSE-VNET-to-BDAIM-P-NA26-HUB-VNET-PEER1"
      ~ remote_virtual_network_id    = "/subscriptions/xxxxxxxx-yyyy-zzzz-aaaa-bbbbbbbbbbbb/resourceGroups/BDAIM-P-NA26-HUB-VNET-RGRP/providers/Microsoft.Network/virtualNetworks/BDAIM-P-NA26-HUB-VNET" -> "/subscriptions/xxxxxxxx-yyyy-zzzz-aaaa-bbbbbbbbbbbb/resourceGroups/bdaim-p-na26-hub-vnet-rgrp/providers/Microsoft.Network/virtualNetworks/BDAIM-P-NA26-HUB-VNET" # forces replacement
        resource_group_name          = "BDAIM-D-NA26-Concourse-RGRP"
        use_remote_gateways          = true
        virtual_network_name         = "BDAIM-D-NA26-CONCOURSE-VNET"
    }

  # module.hub_vnet_peering.azurerm_virtual_network_peering.peering_to_hub["BDAIM-D-NA26-Demo-VNET"] will be created
  + resource "azurerm_virtual_network_peering" "peering_to_hub" {
      + allow_forwarded_traffic      = true
      + allow_gateway_transit        = false
      + allow_virtual_network_access = true
      + id                           = (known after apply)
      + name                         = "BDAIM-D-NA26-Demo-VNET-to-BDAIM-P-NA26-HUB-VNET-PEER1"
      + remote_virtual_network_id    = "/subscriptions/xxxxxxxx-yyyy-zzzz-aaaa-bbbbbbbbbbbb/resourceGroups/bdaim-p-na26-hub-vnet-rgrp/providers/Microsoft.Network/virtualNetworks/BDAIM-P-NA26-HUB-VNET"
      + resource_group_name          = "BDAIM-D-NA26-Demo-RGRP"
      + use_remote_gateways          = true
      + virtual_network_name         = "BDAIM-D-NA26-Demo-VNET"
    }

Plan: 3 to add, 0 to change, 1 to destroy.

Steps to Reproduce

  1. Have virtual_network_peerings that pre-date the change.

  2. terraform plan to gather required changes or terraform apply to update the infrastructure.

Important Factoids

References

Resource Group Name is case insensitive in the URI:
https://docs.microsoft.com/en-us/rest/api/resources/resources/get#uri-parameters

API Issue on if this should be the case:
Azure/azure-rest-api-specs#6641

  • #0000
@tombuildsstuff tombuildsstuff added the upstream/microsoft Indicates that there's an upstream issue blocking this issue/PR label Aug 29, 2020
@tombuildsstuff
Copy link
Contributor

hey @i-m-wisch

Thanks for opening this issue.

Whilst this API treats the Resource Group name as case-insensitive in the Request URI - it should be case-sensitive in the response - so unfortunately this is a bug in the Azure API here (as such I've tagged this with "upstream-microsoft") - once that's fixed Terraform should pick this up automatically.

Thanks!

@i-m-wisch
Copy link
Author

i-m-wisch commented Sep 14, 2020

Hi @tombuildsstuff, in my support case with Microsoft, they are not backing down from their stance that resource names are case-insensitive, and referenced this page Resource Name Rules.

Resource names are case-insensitive unless specifically noted in the valid characters column.

They are stating that the sudden change from actual case, to lower, only in the Subnet and VNet Resource ID responses are "expected behavior", and that they "expect management tools to comply with the documented behavior of the platform.", referring to the Terraform AzureRM provider.

@tombuildsstuff
Copy link
Contributor

@i-m-wisch unfortunately that's not strictly true - the Azure API's (per the ARM Specification, and the ARM Team) are supposed to follow Postel's Law, that is, it should accept any case but return the canonical casing (e.g. accept HeLlO but return Hello for the Resource Group name).

As such unfortunately this is an issue within the Networking API that needs to be resolved - since this is being tracked in Azure/azure-rest-api-specs#6641 I'm going to close this issue in favour of that one - would you mind subscribing to that for updates?

Thanks!

@i-m-wisch
Copy link
Author

@tombuildsstuff Something changed in the 2.48 release of the AzureRM provider. Testing with both 2.48 and 2.49 the resource group names come back in the correct camel case:

~ remote_virtual_network_id = "/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/bdaim-p-na26-concourse-rgrp/providers/Microsoft.Network/virtualNetworks/BDAIM-P-NA26-CONCOURSE-VNET" -> "/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/BDAIM-P-NA26-Concourse-RGRP/providers/Microsoft.Network/virtualNetworks/BDAIM-P-NA26-CONCOURSE-VNET" # forces replacement

With 2.47 prior we are seeing the lower case resource group names and no changes.

@ghost
Copy link

ghost commented Mar 18, 2021

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 👉 [email protected]. Thanks!

@ghost ghost locked as resolved and limited conversation to collaborators Mar 18, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
upstream/microsoft Indicates that there's an upstream issue blocking this issue/PR
Projects
None yet
Development

No branches or pull requests

2 participants