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

azurerm_application_gateway always replaces backend_http_settings when cookie_based_affinity is disabled and no affinity_cookie_name is defined #23467

Open omgjlk opened 1 year ago

omgjlk commented 1 year ago

Is there an existing issue for this?

Community Note

I've got an application gateway with an http backend. That backend has cookie_based_affinity set to Disabled. There is no definition for a affinity_cookie_name. However every run of Terraform wants to replace the resource, and in the details I can see:

      - backend_http_settings {
          - affinity_cookie_name                = "ApplicationGatewayAffinity" -> null

The replacement resource does not show an attribute for affinity_cookie_name being added.

I assume that there is something on Azure side that is automatically creating an affinity cookie name when the resource is created, and now Terraform is comparing state to resource and notices a difference.

If I add the attribute to my terraform file the resource is no longer refreshed.

Terraform Version

1.4.4

AzureRM Provider Version

3.50.0

Affected Resource(s)/Data Source(s)

azurerm_application_gateway

Terraform Configuration Files

resource "azurerm_application_gateway" "tfe_prod" { name = tfe_prod resource_group_name = module.site.rg_network_name location = module.site.rg_network_location

zones = ["1", "2", "3"]

sku { name = "Standard_v2" tier = "Standard_v2" }

gateway_ip_configuration { name = "${local.tfe_prod_full_name}-gw-subnet" subnet_id = module.site.app_gateway_subnet_id }

autoscale_configuration { min_capacity = 2 max_capacity = 125 }

frontend_ip_configuration { name = local.tfe_prod_frontend_ip_configuration_name public_ip_address_id = azurerm_public_ip.tfe_prod.id }

backend_address_pool { name = local.tfe_prod_backend_address_pool_name }

TFE Application

backend_http_settings { name = local.tfe_prod_backend_https_settings_name cookie_based_affinity = "Disabled" port = 443 protocol = "Https" request_timeout = 60 host_name = local.tfe_prod_service_fqdn connection_draining { enabled = true drain_timeout_sec = 300 } } }

Debug Output/Panic Output

Terraform will perform the following actions:

azurerm_application_gateway.tfe_prod will be updated in-place

~ resource "azurerm_application_gateway" "tfe_prod" { id = "/subscriptions//resourceGroups/network/providers/Microsoft.Network/applicationGateways/azure-eastus-terraform-enterprise-production" name = "azure-eastus-terraform-enterprise-production" tags = { "catalog_service" = "terraform-enterprise" "environment" = "production" }

  - backend_http_settings {
      - affinity_cookie_name                = "ApplicationGatewayAffinity" -> null
      - cookie_based_affinity               = "Disabled" -> null
      - host_name                           = "terraform.githubapp.com" -> null
      - id                                  = "/subscriptions/<sub>/resourceGroups/network/providers/Microsoft.Network/applicationGateways/azure-eastus-terraform-enterprise-production/backendHttpSettingsCollection/azure-eastus-terraform-enterprise-production-be-https-settings" -> null
      - name                                = "azure-eastus-terraform-enterprise-production-be-https-settings" -> null
      - pick_host_name_from_backend_address = false -> null
      - port                                = 443 -> null
      - protocol                            = "Https" -> null
      - request_timeout                     = 60 -> null
      - trusted_root_certificate_names      = [] -> null

      - connection_draining {
          - drain_timeout_sec = 300 -> null
          - enabled           = true -> null
        }
    }
  + backend_http_settings {
      + cookie_based_affinity               = "Disabled"
      + host_name                           = "terraform.githubapp.com"
      + id                                  = (known after apply)
      + name                                = "azure-eastus-terraform-enterprise-production-be-https-settings"
      + pick_host_name_from_backend_address = false
      + port                                = 443
      + probe_id                            = (known after apply)
      + protocol                            = "Https"
      + request_timeout                     = 60
      + trusted_root_certificate_names      = []

      + connection_draining {
          + drain_timeout_sec = 300
          + enabled           = true
        }
    }

    # (18 unchanged blocks hidden)
}

Expected Behaviour

The resource does not change every plan.

Actual Behaviour

The resource is changing every plan.

Steps to Reproduce

Create an application gateway with a backend_http_settings that disable cookie_based_affinity and do not define an affinity_cookie_name. Plan/apply. Plan again and notice Terraform wanting to replace the backend_http_settings.

Important Factoids

No response

References

Looks similar to https://github.com/hashicorp/terraform-provider-azurerm/issues/16695

teowa commented 1 year ago

Hi @omgjlk , I try to reproduce the issue but seems I can't with below config. Could it be the affinity_cookie_name property has been changed out of Terraform scope? And could you please export the debug log with TF_LOG=DEBUG TF_LOG_PATH=/home/test/tf.log terraform apply?

Thanks.

tf config ```hcl provider "azurerm" { features {} } data "azurerm_client_config" "test" { } resource "azurerm_resource_group" "test" { name = "wt-test-appgw2" location = "West Europe" } resource "azurerm_virtual_network" "test" { name = "test-network1" resource_group_name = azurerm_resource_group.test.name location = azurerm_resource_group.test.location address_space = ["10.254.0.0/16"] } resource "azurerm_subnet" "frontend" { name = "frontend" resource_group_name = azurerm_resource_group.test.name virtual_network_name = azurerm_virtual_network.test.name address_prefixes = ["10.254.0.0/24"] } resource "azurerm_subnet" "backend" { name = "backend" resource_group_name = azurerm_resource_group.test.name virtual_network_name = azurerm_virtual_network.test.name address_prefixes = ["10.254.2.0/24"] } resource "azurerm_public_ip" "test" { name = "test-pip" resource_group_name = azurerm_resource_group.test.name location = azurerm_resource_group.test.location allocation_method = "Static" sku = "Standard" } locals { backend_address_pool_name = "${azurerm_virtual_network.test.name}-beap" frontend_port_name = "${azurerm_virtual_network.test.name}-feport" frontend_ip_configuration_name = "${azurerm_virtual_network.test.name}-feip" http_setting_name = "${azurerm_virtual_network.test.name}-be-htst" listener_name = "${azurerm_virtual_network.test.name}-httplstn" request_routing_rule_name = "${azurerm_virtual_network.test.name}-rqrt" redirect_configuration_name = "${azurerm_virtual_network.test.name}-rdrcfg" } resource "azurerm_application_gateway" "network" { name = "testi2-appgateway" resource_group_name = azurerm_resource_group.test.name location = azurerm_resource_group.test.location sku { name = "Standard_v2" tier = "Standard_v2" capacity = 2 } gateway_ip_configuration { name = "my-gateway-ip-configuration" subnet_id = azurerm_subnet.frontend.id } frontend_port { name = local.frontend_port_name port = 80 } frontend_ip_configuration { name = local.frontend_ip_configuration_name public_ip_address_id = azurerm_public_ip.test.id } backend_address_pool { name = "bap3" ip_addresses = [] fqdns = [] } backend_address_pool { ip_addresses = [] fqdns = ["foobar.com"] name = local.backend_address_pool_name } backend_http_settings { name = local.http_setting_name cookie_based_affinity = "Disabled" port = 443 protocol = "Https" host_name = "terraform.githubapp.com" request_timeout = 60 pick_host_name_from_backend_address = false connection_draining { drain_timeout_sec = 300 enabled = true } } http_listener { name = local.listener_name frontend_ip_configuration_name = local.frontend_ip_configuration_name frontend_port_name = local.frontend_port_name protocol = "Http" } request_routing_rule { name = local.request_routing_rule_name priority = 10 rule_type = "Basic" http_listener_name = local.listener_name backend_address_pool_name = local.backend_address_pool_name backend_http_settings_name = local.http_setting_name } } ```
omgjlk commented 1 year ago

I'll work on a real reproduction instead of an edited version of what we're doing in production. At the same time I'll get DEBUG log output.

For our production workload I've just set the affinity_cookie_name to what TF was saying it was and that resulted in TF saying that there were no changes necessary.

justinmchase commented 8 months ago

Its always replacing for me no matter what. I am using AKS and that enables AGIC which replacess all the backends, whenver I deploy terraform again after that it completely replaces it all again, breaking my ingress.

ravick4u commented 2 months ago

Same for me. It always updates.