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

Case sensitivity of subnet_id in gateway_ip_configuration for azurerm_application_gateway causes perpetual changes #23940

Open
1 task done
tony-harverson-moonpig opened this issue Nov 17, 2023 · 9 comments

Comments

@tony-harverson-moonpig
Copy link

Is there an existing issue for this?

  • I have searched the existing issues

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 and review the contribution guide to help.

Terraform Version

1.6.3

AzureRM Provider Version

3.80.0

Affected Resource(s)/Data Source(s)

azurerm_application_gateway

Terraform Configuration Files

data "azurerm_client_config" "current" {}

resource "azurerm_resource_group" "spike" {
  location = "northeurope"
  name     = "Spike"

  lifecycle {
    ignore_changes = [
      # Ignore changes to tags, e.g. because a management agent
      # updates these based on some ruleset managed elsewhere.
      tags,
    ]
  }
}

resource "azurerm_public_ip" "test" {
  allocation_method   = "Static"
  location            = azurerm_resource_group.spike.location
  name                = "test"
  resource_group_name = azurerm_resource_group.spike.name
  sku                 = "Standard"
}

resource "azurerm_application_gateway" "test" {
  location            = azurerm_resource_group.spike.location
  name                = "test"
  resource_group_name = azurerm_resource_group.spike.name
  backend_address_pool {
    fqdns = ["www.notarealaddress.com"]
    name  = "test"
  }
  backend_http_settings {
    affinity_cookie_name                = "ApplicationGatewayAffinity"
    cookie_based_affinity               = "Enabled"
    name                                = "test"
    pick_host_name_from_backend_address = true
    port                                = 443
    protocol                            = "Https"
    request_timeout                     = 20
  }
  frontend_ip_configuration {
    name                 = "appGwPublicFrontendIpIPv4"
    public_ip_address_id = azurerm_public_ip.test.id
  }
  frontend_port {
    name = "port_80"
    port = 80
  }
  gateway_ip_configuration {
    name      = "appGatewayIpConfig"
    subnet_id = "/subscriptions/${data.azurerm_client_config.current.subscription_id}/resourceGroups/${upper(azurerm_resource_group.spike.name)}/providers/Microsoft.Network/virtualNetworks/${upper(azurerm_virtual_network.test.name)}/subnets/${upper(azurerm_subnet.lowercase.name)}"
  }
  http_listener {
    frontend_ip_configuration_name = "appGwPublicFrontendIpIPv4"
    frontend_port_name             = "port_80"
    name                           = "DefaultIp"
    protocol                       = "Http"
  }
  request_routing_rule {
    backend_address_pool_name  = "test"
    backend_http_settings_name = "test"
    http_listener_name         = "DefaultIp"
    name                       = "test"
    priority                   = 3
    rule_type                  = "Basic"
  }
  sku {
    capacity = 1
    name     = "Standard_v2"
    tier     = "Standard_v2"
  }
}

resource "azurerm_virtual_network" "test" {
  address_space       = ["10.0.0.0/16"]
  location            = azurerm_resource_group.spike.location
  name                = "TestNetwork"
  resource_group_name = azurerm_resource_group.spike.name
}

resource "azurerm_subnet" "lowercase" {
  address_prefixes     = ["10.0.2.0/24"]
  name                 = "lowercase"
  resource_group_name  = azurerm_resource_group.spike.name
  virtual_network_name = azurerm_virtual_network.test.name
}

Debug Output/Panic Output

# azurerm_application_gateway.test will be updated in-place
  ~ resource "azurerm_application_gateway" "test" {
        id                                = "/subscriptions/{subscription_id}/resourceGroups/Spike/providers/Microsoft.Network/applicationGateways/test"
        name                              = "test"
        tags                              = {}
        # (7 unchanged attributes hidden)

      ~ gateway_ip_configuration {
            id        = "/subscriptions/{subscription_id}/resourceGroups/Spike/providers/Microsoft.Network/applicationGateways/test/gatewayIPConfigurations/appGatewayIpConfig"
            name      = "appGatewayIpConfig"
          ~ subnet_id = "/subscriptions/{subscription_id}/resourceGroups/Spike/providers/Microsoft.Network/virtualNetworks/TestNetwork/subnets/lowercase" -> "/subscriptions/{subscription_id}/resourceGroups/SPIKE/providers/Microsoft.Network/virtualNetworks/TESTNETWORK/subnets/LOWERCASE"
        }

        # (8 unchanged blocks hidden)
    }

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

Expected Behaviour

The plan should settle, and not detect a change.

Actual Behaviour

The plan never settles, and will always attempt to update the subnet id.

Steps to Reproduce

  1. terraform apply --auto-approve
  2. terraform plan

Important Factoids

No response

References

No response

@wuxu92
Copy link
Contributor

wuxu92 commented Nov 20, 2023

Hi, @tony-harverson-moonpig Thank you for submitting this! The provider is case-sensitive, so the behavior you're experiencing is expected. I'm not sure why we need to manually composite a subnet ID here. Could we use data azurerm_subnet instead to resolve the issue?

data "azurerm_subnet" "test" {
  name                 = azurerm_subnet.test.name
  virtual_network_name = azurerm_virtual_network.test.name
  resource_group_name  = azurerm_resource_group.spike.name
}

resource "azurerm_application_gateway" "test" {

	....

  gateway_ip_configuration {
    name      = "appGatewayIpConfig"
    subnet_id = data.azurerm_subnet.test.id
  }

	....

If this is not what you want, then you need a ignore_changes meta argument to suppress the changes: ignore_changes

@tony-harverson-moonpig
Copy link
Author

tony-harverson-moonpig commented Nov 20, 2023

Hi @wuxu92 . We do usually use the azurerm_subnet data source for this, the manual construction of the subnet id in the example was used to show the issue. It's worth noting that the azurerm_subnet data source has a separate case-sensitivity bug where it returns the wrong casing for the subnet id (issue #23916).

Regardless of the case-sensitivity of the provider, having it never settle when there's been no changes in the terraform seems wrong. In terms of provider case sensitivity, it looks like past issues with other resources having similar problems have been fixed (#17090, #20484) by making those comparisons case insensitive.

@wuxu92
Copy link
Contributor

wuxu92 commented Nov 21, 2023

@tony-harverson-moonpig The case issue of the static segment of the ID can be fixed in the provider(just like #20484), but as for the dynamic segments, i,e the virtual network name and subnet name here, the provider has no knowledge to fix the case.

@xmaluenda
Copy link

Hello,
I'm having the same behaviour in an APIM resource since we upgraded from 2.99 into 3.79 for azurerm....
I understand that the property is case sensitive but the problem, for me, is why is it case sensitive in the APIM side but not in the subnet side?
Either it is always lowercase (in APIM, subnet, ...) either it is always "as written"

@wuxu92
Copy link
Contributor

wuxu92 commented Nov 22, 2023

Hi @xmaluenda Could you pleease share the configuration and more detailed output of your case? That way, I can check if it is the same issue.

@xmaluenda
Copy link

xmaluenda commented Dec 22, 2023

Hi @wuxu92 ,

First one, I apologize for my later answer... It wasn't possible for me to go ahead with this subject...

After some test (manly trying to upgrade our APIM service from stv1 to stv2 platform) I think that I found the root cause of the problem described here:

The main action to do to execute this upgrade, is to change the associated subnet (we are running our APIM service in a injected virtual network) by a new one honouring some constraints (be bound to a Network Security Group, etc...).

We were running terraform V1.5.0 and Azurerm provider V 3.81.

We get an error saying that upgrade were impossible because a Stv1 APIM service was in the subnet, the problem was Terrafom tryed to change the old subnet by the same old subnet (although the Plan shown that the subnet will get changed by the new on)....

After some investigation we found that the payload of the Apply Patch request to change the subnet DIDN'T set the new subnet reference in the body...

Looking at the Changelog of Azurerm provider, we found that in v 3.70 the provider was update to use the hashicorp/go-azure-sdk for Apim.

after that, we try the AzureRm provider V 3.69 and everything was Ok : No more problem to change the subnet, the service was upgraded to stv2 and some recurrent changes about the update of APIM endpoints certificates disappears from Terrafom Plan execution...)

So we understand that this new sdk is not going on as well as expected and it brings some instability to the provider for the APIM service .

I suppose that this sdk is not in your "perimeter" but could be that you have some clues to bring to me to drive this information to the right people/team...

@wuxu92
Copy link
Contributor

wuxu92 commented Dec 26, 2023

Hi @xmaluenda ,

Apologies for my delayed response and thank you for the update. I'm not quite clear on the details of the error you mentioned. Could you please provide more information, such as the error message or Terraform plan output? Additionally, @sinbai, could you kindly look into this APIM SDK related issue when you have a moment?

@sinbai
Copy link
Contributor

sinbai commented Dec 26, 2023

@wuxu92 sure. @xmaluenda thanks for providing the information regarding the APIM issue. It is recommended to create a new issue for your case. In addition, could you please provide the TF configuration and reproduction steps for the mentioned APIM issue ? In order to find the root cause faster, a TF configuration file (contains dependent resources and variable values) and steps would be of great help in quickly reproducing/troubleshooting the issue. Thanks in advance.

@xmaluenda
Copy link

@wuxu92 thanks a lot for your time and I apologizes to be not clear enough...
@sinbai sure, as it's my first bug report in terraform I'm not sure about the protocol... I'll try to do my best...
As out APIM declaration is a bit complex I'm going to isolate just the minimal needed to reproduce and I will open a new bug report

Thanks a lot for your time...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants