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

terraform azure app gateway force recreate the child objects which are managed by dynamic blocks #22013

Open
1 task done
raakesh593812 opened this issue Jun 1, 2023 · 3 comments

Comments

@raakesh593812
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

Terraform Version

1.3.2

AzureRM Provider Version

3.29.0

Affected Resource(s)/Data Source(s)

azurerm_application_gateway

Terraform Configuration Files

resource "azurerm_application_gateway" "app_gateway" {
  for_each = local.application_gateways

  name                = each.key
  resource_group_name = data.azurerm_resource_group.resource_group.name
  location            = data.azurerm_resource_group.resource_group.location
  enable_http2        = each.value.enable_http2
  zones               = each.value.zones

  sku {
    name     = each.value.sku.name
    tier     = each.value.sku.tier
    capacity = try(each.value.sku.capacity, null)
  }
  gateway_ip_configuration {
    name      = "${each.key}-gic"
    subnet_id = data.azurerm_subnet.lookups[each.value.subnet].id
  }
  dynamic "frontend_ip_configuration" {
    for_each = each.value.frontend_ip_configurations
    content {
      name                          = frontend_ip_configuration.value.name
      private_ip_address            = frontend_ip_configuration.value.private_ip_address
      public_ip_address_id          = frontend_ip_configuration.value.public_ip_address_id
      private_ip_address_allocation = frontend_ip_configuration.value.private_ip_address_allocation
      subnet_id                     = frontend_ip_configuration.value.subnet_id
    }
  }
  dynamic "frontend_port" {
    for_each = each.value.frontend_ports
    content {
      name = frontend_port.value.name
      port = frontend_port.value.port
    }
  }
  dynamic "backend_address_pool" {
    for_each = each.value.backend_address_pools
    content {
      name         = backend_address_pool.value.name
      fqdns        = backend_address_pool.value.fqdns
      ip_addresses = backend_address_pool.value.ip_addresses
    }
  }
  dynamic "backend_http_settings" {
    for_each = each.value.backend_http_settings
    content {
      name                                = backend_http_settings.value.name
      cookie_based_affinity               = backend_http_settings.value.cookie_based_affinity
      affinity_cookie_name                = backend_http_settings.value.affinity_cookie_name
      port                                = backend_http_settings.value.port
      protocol                            = backend_http_settings.value.protocol
      pick_host_name_from_backend_address = backend_http_settings.value.pick_host_name_from_backend_address
      host_name                           = backend_http_settings.value.host_name
      request_timeout                     = backend_http_settings.value.request_timeout
      probe_name                          = backend_http_settings.value.probe_name
      trusted_root_certificate_names      = backend_http_settings.value.trusted_root_certificate_names
    }
  }
  dynamic "http_listener" {
    for_each = each.value.http_listeners
    content {
      name                           = http_listener.value.name
      frontend_ip_configuration_name = http_listener.value.frontend_ip_configuration_name
      frontend_port_name             = http_listener.value.frontend_port_name
      protocol                       = http_listener.value.protocol
      host_name                      = http_listener.value.host_name
      host_names                     = http_listener.value.host_names
      require_sni                    = http_listener.value.require_sni
      ssl_certificate_name           = http_listener.value.ssl_certificate_name
    }
  }


  dynamic "request_routing_rule" {
    for_each = each.value.request_routing_rules
    content {
      name                       = request_routing_rule.value.name
      rule_type                  = request_routing_rule.value.rule_type
      http_listener_name         = request_routing_rule.value.http_listener_name
      backend_http_settings_name = request_routing_rule.value.backend_http_settings_name
      backend_address_pool_name  = request_routing_rule.value.backend_address_pool_name
      priority                    = request_routing_rule.value.priority
    }
  }




  firewall_policy_id = each.value.firewall_policy_id
  tags               = each.value.tags
}

Debug Output/Panic Output

- http_listener {
          - frontend_ip_configuration_id   = "/subscriptions/23691e30-29e0-45f0-9efa-9e38d2d8358e/resourceGroups/rg-shared-westeurope-gw/providers/Microsoft.Network/applicationGateways/appgatewaysc38/frontendIPConfigurations/appGwFrontendIp1" -> null
          - frontend_ip_configuration_name = "appGwFrontendIp1" -> null
          - frontend_port_id               = "/subscriptions/23691e30-29e0-45f0-9efa-9e38d2d8358e/resourceGroups/rg-shared-westeurope-gw/providers/Microsoft.Network/applicationGateways/appgatewaysc38/frontendPorts/port_80" -> null
          - frontend_port_name             = "port_80" -> null
          - host_name                      = "sapd.cmpny.com" -> null
          - host_names                     = [] -> null
          - id                             = "/subscriptions/23691e30-29e0-45f0-9efa-9e38d2d8358e/resourceGroups/rg-shared-westeurope-gw/providers/Microsoft.Network/applicationGateways/appgatewaysc38/httpListeners/httplistner1" -> null
          - name                           = "httplistner1" -> null
          - protocol                       = "Http" -> null
          - require_sni                    = false -> null
        }
      + http_listener {
          + frontend_ip_configuration_id   = (known after apply)
          + frontend_ip_configuration_name = "appGwFrontendIp1"
          + frontend_port_id               = (known after apply)
          + frontend_port_name             = "port_8080"
          + host_name                      = "sapd2.cmpny.com"
          + host_names                     = []
          + id                             = (known after apply)
          + name                           = "httplistner2"
          + protocol                       = "Http"
          + require_sni                    = false
          + ssl_certificate_id             = (known after apply)
          + ssl_profile_id                 = (known after apply)
        }
      + http_listener {
          + frontend_ip_configuration_id   = "/subscriptions/23691e30-29e0-45f0-9efa-9e38d2d8358e/resourceGroups/rg-shared-westeurope-gw/providers/Microsoft.Network/applicationGateways/appgatewaysc38/frontendIPConfigurations/appGwFrontendIp1"
          + frontend_ip_configuration_name = "appGwFrontendIp1"
          + frontend_port_id               = "/subscriptions/23691e30-29e0-45f0-9efa-9e38d2d8358e/resourceGroups/rg-shared-westeurope-gw/providers/Microsoft.Network/applicationGateways/appgatewaysc38/frontendPorts/port_80"
          + frontend_port_name             = "port_80"
          + host_name                      = "sapd.cmpny.com"
          + host_names                     = []
          + id                             = "/subscriptions/23691e30-29e0-45f0-9efa-9e38d2d8358e/resourceGroups/rg-shared-westeurope-gw/providers/Microsoft.Network/applicationGateways/appgatewaysc38/httpListeners/httplistner1"
          + name                           = "httplistner1"
          + protocol                       = "Http"
          + require_sni                    = false
        }

        # (17 unchanged blocks hidden)
    }


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

Expected Behaviour

ideally the child resource http_listener (name: httplistner1) was already created and when i try to add new listener , terraform should create only new listener which was added in input file

Actual Behaviour

ideally the child resource http_listener (name: httplistner1) was already created and when i try to add new listener , terraform force recreating the child resource http_listener (name: httplistner1).

Steps to Reproduce

No response

Important Factoids

No response

References

As per GitHub issue #6896 , its was fixed in PR #15800.

I still see it in azurerm 3.29.0 and 3.58.0 (latest)

@aristosvo
Copy link
Collaborator

Hi @raakesh593812! Thanks for filing this issue.

I am aware this is confusing and know this is not something you'd like to see. Fortunately, the call towards Azure APIs would contain the same information as if there was only a HTTP listener added, as it is just one call with both listeners in the body. I'm unaware that the order of HTTP listeners is influencing the (re)creation of a listener.

Do you see downtime related to this issue?

@raakesh593812
Copy link
Author

yes its causing downtime for those application onboarded on this appgw. Along with http_listener below child resources also has same behavior. Do you know the workaround ?
backend_http_settings
http_listener
request_routing_rule
ssl_certificate

@aristosvo
Copy link
Collaborator

aristosvo commented Jun 2, 2023

Do you know the workaround ?

A possible solution could be to make sure the oldest/existing child resources are first in the list, but I'm not sure if that influences anything. There is no other option I could think of.

TBH, I think this issue is a duplicate of #16136, and behaviour will therefore probably not change until v4.0.0 is in the picture.

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