terraform-provider-azurerm: azurerm_frontdoor ordering of frontend_endpoint means apply fails

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

Terraform v0.13.5
+ provider registry.terraform.io/hashicorp/azurerm v2.23.0

Affected Resource(s)

azurerm_frontdoor

Terraform Configuration Files

resource "azurerm_frontdoor" "frontdoor" {
  name                                         = "${var.name_prefix}-fd"
  resource_group_name                          = azurerm_resource_group.frontdoor.name
  enforce_backend_pools_certificate_name_check = false
  backend_pools_send_receive_timeout_seconds   = 30

  routing_rule {
    name               = "HTTP-Redirect"
    accepted_protocols = ["Http"]
    patterns_to_match  = ["/*"]
    frontend_endpoints = ["${var.name_prefix}-fd-endpoint-int","${var.name_prefix}-fd-endpoint-ext"]
    redirect_configuration  {
      redirect_type = "PermanentRedirect"
      redirect_protocol = "HttpsOnly"

    }
  }

  routing_rule {
    name               = "HTTPS-DefaultHost-Redirect"
    accepted_protocols = ["Https"]
    patterns_to_match  = ["/*"]
    frontend_endpoints = ["${var.name_prefix}-fd-endpoint-int"]
    redirect_configuration  {
      redirect_type = "PermanentRedirect"
      redirect_protocol = "HttpsOnly"
      custom_host = "${var.cname}.ourdomain.org"
    }
  }

  routing_rule {
    name               = "HTTPS-Root-Redirect"
    accepted_protocols = ["Https"]
    patterns_to_match  = ["/","/*"]
    frontend_endpoints = ["${var.name_prefix}-fd-endpoint-ext"]
    redirect_configuration  {
      redirect_type = "PermanentRedirect"
      redirect_protocol = "HttpsOnly"
      custom_host = "www.ourdomain.org"
      custom_path = "/"
    }
  }

  dynamic "routing_rule" {
    for_each = toset(var.tenant_paths)
    content {
      name               = "HTTPS-${upper(routing_rule.value)}-Forward"
      accepted_protocols = ["Https"]
      patterns_to_match  = ["/${routing_rule.value}/","/${routing_rule.value}/*"]
      frontend_endpoints = ["${var.name_prefix}-fd-endpoint-ext"]
      forwarding_configuration {
        backend_pool_name = "${routing_rule.value}-pool"
        custom_forwarding_path = "/"
        forwarding_protocol = "HttpsOnly"
        cache_enabled = false
        cache_query_parameter_strip_directive = "StripNone"
      }

    }
  }

  dynamic "routing_rule" {
    for_each = toset(var.tenant_paths)
    content {
      name               = "HTTPS-${upper(routing_rule.value)}-Redirect"
      accepted_protocols = ["Https"]
      patterns_to_match  = ["/${routing_rule.value}"]
      frontend_endpoints = ["${var.name_prefix}-fd-endpoint-ext"]
      redirect_configuration  {
        redirect_type = "Moved"
        redirect_protocol = "HttpsOnly"
        custom_path = "/${routing_rule.value}/"
      }
    }
  }

  backend_pool_load_balancing {
    name = "${var.name_prefix}-LoadBalancingSettings1"
  }

  backend_pool_health_probe {
    name = "${var.name_prefix}-HealthProbeSetting1"
    protocol = "Https"
    interval_in_seconds = "30"
    probe_method = "HEAD"
  }

  dynamic "backend_pool" {
    for_each = toset(var.webapps)
    content {
      name = "${backend_pool.value}-pool"
      backend {
        host_header = "${backend_pool.value}-${var.Environment}-web-0-webapp.azurewebsites.net"
        address     = "${backend_pool.value}-${var.Environment}-web-0-webapp.azurewebsites.net"
        http_port   = 80
        https_port  = 443
      }

      backend {
        host_header = "${backend_pool.value}-${var.Environment}-web-1-webapp.azurewebsites.net"
        address     = "${backend_pool.value}-${var.Environment}-web-1-webapp.azurewebsites.net"
        http_port   = 80
        https_port  = 443
        enabled = length(var.location) == 2 ? true : false
      }

      load_balancing_name = "${var.name_prefix}-LoadBalancingSettings1"
      health_probe_name   = "${var.name_prefix}-HealthProbeSetting1"
    }
  }

  frontend_endpoint {
    name                              = "${var.name_prefix}-fd-endpoint-int"
    host_name                         = "${var.name_prefix}-fd.azurefd.net"
    custom_https_provisioning_enabled = false 
  }

  frontend_endpoint {
    name                              = "${var.name_prefix}-fd-endpoint-ext"
    host_name                         = "${var.cname}.ourdomain.org"
    session_affinity_enabled          = true
    web_application_firewall_policy_link_id = azurerm_frontdoor_firewall_policy.frontdoor.id
    custom_https_provisioning_enabled = true
    custom_https_configuration {
      certificate_source = "FrontDoor"
    }
  }
  
  lifecycle {
    ignore_changes = [tags]
  }
}

Expected Behavior

Nothing should change

Actual Behavior

The order of the frontend_endpoint seems to have change which makes all these changes

An execution plan has been generated and is shown below.
Resource actions are indicated with the following symbols:
  ~ update in-place

Terraform will perform the following actions:

  # module.scaleUnit.module.frontdoor.azurerm_frontdoor.frontdoor will be updated in-place
  ~ resource "azurerm_frontdoor" "frontdoor" {
        backend_pools_send_receive_timeout_seconds   = 30
        cname                                        = "canary-fd.azurefd.net"
        enforce_backend_pools_certificate_name_check = false
        header_frontdoor_id                          = "xxxx"
        id                                           = "/subscriptions/xxxx/resourcegroups/canary-frontdoor/providers/Microsoft.Network/frontdoors/canary-fd"
        load_balancer_enabled                        = true
        location                                     = "global"
        name                                         = "canary-fd"
        resource_group_name                          = "canary-frontdoor"
        tags                                         = {
            "CostSource"  = "Internal"
            "Environment" = "Canary"
        }

      ~ backend_pool {
            health_probe_name   = "canary-HealthProbeSetting1"
            id                  = "/subscriptions/xxxx/resourcegroups/canary-frontdoor/providers/Microsoft.Network/Frontdoors/canary-fd/BackendPools/sandbox-pool"
            load_balancing_name = "canary-LoadBalancingSettings1"
          ~ name                = "sandbox-pool" -> "tenantc-pool"

          ~ backend {
              ~ address     = "sandbox-Canary-web-0-webapp.azurewebsites.net" -> "tenantc-Canary-web-0-webapp.azurewebsites.net"
                enabled     = true
              ~ host_header = "sandbox-Canary-web-0-webapp.azurewebsites.net" -> "tenantc-Canary-web-0-webapp.azurewebsites.net"
                http_port   = 80
                https_port  = 443
                priority    = 1
                weight      = 50
            }
          ~ backend {
              ~ address     = "sandbox-Canary-web-1-webapp.azurewebsites.net" -> "tenantc-Canary-web-1-webapp.azurewebsites.net"
                enabled     = true
              ~ host_header = "sandbox-Canary-web-1-webapp.azurewebsites.net" -> "tenantc-Canary-web-1-webapp.azurewebsites.net"
                http_port   = 80
                https_port  = 443
                priority    = 1
                weight      = 50
            }
        }
      ~ backend_pool {
            health_probe_name   = "canary-HealthProbeSetting1"
            id                  = "/subscriptions/xxxx/resourcegroups/canary-frontdoor/providers/Microsoft.Network/Frontdoors/canary-fd/BackendPools/tenantc-pool"
            load_balancing_name = "canary-LoadBalancingSettings1"
          ~ name                = "tenantc-pool" -> "sandbox-pool"

          ~ backend {
              ~ address     = "tenantc-Canary-web-0-webapp.azurewebsites.net" -> "sandbox-Canary-web-0-webapp.azurewebsites.net"
                enabled     = true
              ~ host_header = "tenantc-Canary-web-0-webapp.azurewebsites.net" -> "sandbox-Canary-web-0-webapp.azurewebsites.net"
                http_port   = 80
                https_port  = 443
                priority    = 1
                weight      = 50
            }
          ~ backend {
              ~ address     = "tenantc-Canary-web-1-webapp.azurewebsites.net" -> "sandbox-Canary-web-1-webapp.azurewebsites.net"
                enabled     = true
              ~ host_header = "tenantc-Canary-web-1-webapp.azurewebsites.net" -> "sandbox-Canary-web-1-webapp.azurewebsites.net"
                http_port   = 80
                https_port  = 443
                priority    = 1
                weight      = 50
            }
        }
      ~ backend_pool {
            health_probe_name   = "canary-HealthProbeSetting1"
            id                  = "/subscriptions/xxxx/resourcegroups/canary-frontdoor/providers/Microsoft.Network/Frontdoors/canary-fd/BackendPools/tenantb-pool"
            load_balancing_name = "canary-LoadBalancingSettings1"
          ~ name                = "tenantb-pool" -> "tenantd-pool"

          ~ backend {
              ~ address     = "tenantb-Canary-web-0-webapp.azurewebsites.net" -> "tenantd-Canary-web-0-webapp.azurewebsites.net"
                enabled     = true
              ~ host_header = "tenantb-Canary-web-0-webapp.azurewebsites.net" -> "tenantd-Canary-web-0-webapp.azurewebsites.net"
                http_port   = 80
                https_port  = 443
                priority    = 1
                weight      = 50
            }
          ~ backend {
              ~ address     = "tenantb-Canary-web-1-webapp.azurewebsites.net" -> "tenantd-Canary-web-1-webapp.azurewebsites.net"
                enabled     = true
              ~ host_header = "tenantb-Canary-web-1-webapp.azurewebsites.net" -> "tenantd-Canary-web-1-webapp.azurewebsites.net"
                http_port   = 80
                https_port  = 443
                priority    = 1
                weight      = 50
            }
        }
      ~ backend_pool {
            health_probe_name   = "canary-HealthProbeSetting1"
            id                  = "/subscriptions/xxxx/resourcegroups/canary-frontdoor/providers/Microsoft.Network/Frontdoors/canary-fd/BackendPools/tenantd-pool"
            load_balancing_name = "canary-LoadBalancingSettings1"
          ~ name                = "tenantd-pool" -> "tenanta-pool"

          ~ backend {
              ~ address     = "tenantd-Canary-web-0-webapp.azurewebsites.net" -> "tenanta-Canary-web-0-webapp.azurewebsites.net"
                enabled     = true
              ~ host_header = "tenantd-Canary-web-0-webapp.azurewebsites.net" -> "tenanta-Canary-web-0-webapp.azurewebsites.net"
                http_port   = 80
                https_port  = 443
                priority    = 1
                weight      = 50
            }
          ~ backend {
              ~ address     = "tenantd-Canary-web-1-webapp.azurewebsites.net" -> "tenanta-Canary-web-1-webapp.azurewebsites.net"
                enabled     = true
              ~ host_header = "tenantd-Canary-web-1-webapp.azurewebsites.net" -> "tenanta-Canary-web-1-webapp.azurewebsites.net"
                http_port   = 80
                https_port  = 443
                priority    = 1
                weight      = 50
            }
        }
      ~ backend_pool {
            health_probe_name   = "canary-HealthProbeSetting1"
            id                  = "/subscriptions/xxxx/resourcegroups/canary-frontdoor/providers/Microsoft.Network/Frontdoors/canary-fd/BackendPools/tenanta-pool"
            load_balancing_name = "canary-LoadBalancingSettings1"
          ~ name                = "tenanta-pool" -> "tenantb-pool"

          ~ backend {
              ~ address     = "tenanta-Canary-web-0-webapp.azurewebsites.net" -> "tenantb-Canary-web-0-webapp.azurewebsites.net"
                enabled     = true
              ~ host_header = "tenanta-Canary-web-0-webapp.azurewebsites.net" -> "tenantb-Canary-web-0-webapp.azurewebsites.net"
                http_port   = 80
                https_port  = 443
                priority    = 1
                weight      = 50
            }
          ~ backend {
              ~ address     = "tenanta-Canary-web-1-webapp.azurewebsites.net" -> "tenantb-Canary-web-1-webapp.azurewebsites.net"
                enabled     = true
              ~ host_header = "tenanta-Canary-web-1-webapp.azurewebsites.net" -> "tenantb-Canary-web-1-webapp.azurewebsites.net"
                http_port   = 80
                https_port  = 443
                priority    = 1
                weight      = 50
            }
        }

        backend_pool_health_probe {
            enabled             = true
            id                  = "/subscriptions/xxxx/resourcegroups/canary-frontdoor/providers/Microsoft.Network/Frontdoors/canary-fd/HealthProbeSettings/canary-HealthProbeSetting1"
            interval_in_seconds = 30
            name                = "canary-HealthProbeSetting1"
            path                = "/"
            probe_method        = "HEAD"
            protocol            = "Https"
        }

        backend_pool_load_balancing {
            additional_latency_milliseconds = 0
            id                              = "/subscriptions/xxxx/resourcegroups/canary-frontdoor/providers/Microsoft.Network/Frontdoors/canary-fd/LoadBalancingSettings/canary-LoadBalancingSettings1"
            name                            = "canary-LoadBalancingSettings1"
            sample_size                     = 4
            successful_samples_required     = 2
        }

      ~ frontend_endpoint {
          ~ custom_https_provisioning_enabled       = true -> false
          ~ host_name                               = "canary.ourdomain.org" -> "canary-fd.azurefd.net"
            id                                      = "/subscriptions/xxxx/resourcegroups/canary-frontdoor/providers/Microsoft.Network/frontdoors/canary-fd/frontendendpoints/canary-fd-endpoint-ext"
          ~ name                                    = "canary-fd-endpoint-ext" -> "canary-fd-endpoint-int"
          ~ session_affinity_enabled                = true -> false
            session_affinity_ttl_seconds            = 0
          - web_application_firewall_policy_link_id = "/subscriptions/xxxx/resourcegroups/canary-frontdoor/providers/Microsoft.Network/frontdoorwebapplicationfirewallpolicies/frontdoorfdwafpolicy" -> null

            custom_https_configuration {
                certificate_source    = "FrontDoor"
                minimum_tls_version   = "1.2"
                provisioning_state    = "Enabled"
                provisioning_substate = "CertificateDeployed"
            }
        }
      ~ frontend_endpoint {
          ~ custom_https_provisioning_enabled       = false -> true
          ~ host_name                               = "canary-fd.azurefd.net" -> "canary.ourdomain.org"
            id                                      = "/subscriptions/xxxx/resourcegroups/canary-frontdoor/providers/Microsoft.Network/frontdoors/canary-fd/frontendendpoints/canary-fd-endpoint-int"
          ~ name                                    = "canary-fd-endpoint-int" -> "canary-fd-endpoint-ext"
          ~ session_affinity_enabled                = false -> true
            session_affinity_ttl_seconds            = 0
          + web_application_firewall_policy_link_id = "/subscriptions/xxxx/resourcegroups/canary-frontdoor/providers/Microsoft.Network/frontdoorwebapplicationfirewallpolicies/frontdoorfdwafpolicy"

          + custom_https_configuration {
              + certificate_source = "FrontDoor"
            }
        }

      ~ routing_rule {
          ~ accepted_protocols = [
              - "Https",
              + "Http",
            ]
            enabled            = true
          ~ frontend_endpoints = [
              + "canary-fd-endpoint-int",
                "canary-fd-endpoint-ext",
            ]
            id                 = "/subscriptions/xxxx/resourcegroups/canary-frontdoor/providers/Microsoft.Network/Frontdoors/canary-fd/RoutingRules/HTTPS-Root-Redirect"
          ~ name               = "HTTPS-Root-Redirect" -> "HTTP-Redirect"
          ~ patterns_to_match  = [
              - "/",
                "/*",
            ]

          ~ redirect_configuration {
              - custom_host       = "www.ourdomain.org" -> null
              - custom_path       = "/" -> null
                redirect_protocol = "HttpsOnly"
                redirect_type     = "PermanentRedirect"
            }
        }
      ~ routing_rule {
          ~ accepted_protocols = [
              - "Http",
              + "Https",
            ]
            enabled            = true
          ~ frontend_endpoints = [
                "canary-fd-endpoint-int",
              - "canary-fd-endpoint-ext",
            ]
            id                 = "/subscriptions/xxxx/resourcegroups/canary-frontdoor/providers/Microsoft.Network/Frontdoors/canary-fd/RoutingRules/HTTP-Redirect"
          ~ name               = "HTTP-Redirect" -> "HTTPS-DefaultHost-Redirect"
            patterns_to_match  = [
                "/*",
            ]

          ~ redirect_configuration {
              + custom_host       = "canary.ourdomain.org"
                redirect_protocol = "HttpsOnly"
                redirect_type     = "PermanentRedirect"
            }
        }
      ~ routing_rule {
            accepted_protocols = [
                "Https",
            ]
            enabled            = true
          ~ frontend_endpoints = [
              - "canary-fd-endpoint-int",
              + "canary-fd-endpoint-ext",
            ]
            id                 = "/subscriptions/xxxx/resourcegroups/canary-frontdoor/providers/Microsoft.Network/Frontdoors/canary-fd/RoutingRules/HTTPS-DefaultHost-Redirect"
          ~ name               = "HTTPS-DefaultHost-Redirect" -> "HTTPS-Root-Redirect"
          ~ patterns_to_match  = [
              + "/",
                "/*",
            ]

          ~ redirect_configuration {
              ~ custom_host       = "canary.ourdomain.org" -> "www.ourdomain.org"
              + custom_path       = "/"
                redirect_protocol = "HttpsOnly"
                redirect_type     = "PermanentRedirect"
            }
        }
      ~ routing_rule {
            accepted_protocols = [
                "Https",
            ]
            enabled            = true
            frontend_endpoints = [
                "canary-fd-endpoint-ext",
            ]
            id                 = "/subscriptions/xxxx/resourcegroups/canary-frontdoor/providers/Microsoft.Network/Frontdoors/canary-fd/RoutingRules/HTTPS-SANDBOX-Forward"
          ~ name               = "HTTPS-SANDBOX-Forward" -> "HTTPS-tenantc-Forward"
          ~ patterns_to_match  = [
              - "/sandbox/",
              - "/sandbox/*",
              + "/tenantc/",
              + "/tenantc/*",
            ]

          ~ forwarding_configuration {
              ~ backend_pool_name                     = "sandbox-pool" -> "tenantc-pool"
                cache_enabled                         = false
                cache_query_parameter_strip_directive = "StripNone"
                cache_use_dynamic_compression         = false
                custom_forwarding_path                = "/"
                forwarding_protocol                   = "HttpsOnly"
            }
        }
      ~ routing_rule {
            accepted_protocols = [
                "Https",
            ]
            enabled            = true
            frontend_endpoints = [
                "canary-fd-endpoint-ext",
            ]
            id                 = "/subscriptions/xxxx/resourcegroups/canary-frontdoor/providers/Microsoft.Network/Frontdoors/canary-fd/RoutingRules/HTTPS-tenantc-Forward"
          ~ name               = "HTTPS-tenantc-Forward" -> "HTTPS-SANDBOX-Forward"
          ~ patterns_to_match  = [
              - "/tenantc/",
              - "/tenantc/*",
              + "/sandbox/",
              + "/sandbox/*",
            ]

          ~ forwarding_configuration {
              ~ backend_pool_name                     = "tenantc-pool" -> "sandbox-pool"
                cache_enabled                         = false
                cache_query_parameter_strip_directive = "StripNone"
                cache_use_dynamic_compression         = false
                custom_forwarding_path                = "/"
                forwarding_protocol                   = "HttpsOnly"
            }
        }
        routing_rule {
            accepted_protocols = [
                "Https",
            ]
            enabled            = true
            frontend_endpoints = [
                "canary-fd-endpoint-ext",
            ]
            id                 = "/subscriptions/xxxx/resourcegroups/canary-frontdoor/providers/Microsoft.Network/Frontdoors/canary-fd/RoutingRules/HTTPS-tenantd-Forward"
            name               = "HTTPS-tenantd-Forward"
            patterns_to_match  = [
                "/tenantd/",
                "/tenantd/*",
            ]

            forwarding_configuration {
                backend_pool_name                     = "tenantd-pool"
                cache_enabled                         = false
                cache_query_parameter_strip_directive = "StripNone"
                cache_use_dynamic_compression         = false
                custom_forwarding_path                = "/"
                forwarding_protocol                   = "HttpsOnly"
            }
        }
      ~ routing_rule {
            accepted_protocols = [
                "Https",
            ]
            enabled            = true
            frontend_endpoints = [
                "canary-fd-endpoint-ext",
            ]
            id                 = "/subscriptions/xxxx/resourcegroups/canary-frontdoor/providers/Microsoft.Network/Frontdoors/canary-fd/RoutingRules/HTTPS-TENANTB-Forward"
          ~ name               = "HTTPS-TENANTB-Forward" -> "HTTPS-TENANTA-Forward"
          ~ patterns_to_match  = [
              - "/tenantb/",
              - "/tenantb/*",
              + "/tenanta/",
              + "/tenanta/*",
            ]

          ~ forwarding_configuration {
              ~ backend_pool_name                     = "tenantb-pool" -> "tenanta-pool"
                cache_enabled                         = false
                cache_query_parameter_strip_directive = "StripNone"
                cache_use_dynamic_compression         = false
                custom_forwarding_path                = "/"
                forwarding_protocol                   = "HttpsOnly"
            }
        }
      ~ routing_rule {
            accepted_protocols = [
                "Https",
            ]
            enabled            = true
            frontend_endpoints = [
                "canary-fd-endpoint-ext",
            ]
            id                 = "/subscriptions/xxxx/resourcegroups/canary-frontdoor/providers/Microsoft.Network/Frontdoors/canary-fd/RoutingRules/HTTPS-tenantc-Redirect"
          ~ name               = "HTTPS-tenantc-Redirect" -> "HTTPS-TENANTB-Forward"
          ~ patterns_to_match  = [
              - "/tenantc",
              + "/tenantb/",
              + "/tenantb/*",
            ]

          + forwarding_configuration {
              + backend_pool_name                     = "tenantb-pool"
              + cache_enabled                         = false
              + cache_query_parameter_strip_directive = "StripNone"
              + cache_use_dynamic_compression         = false
              + custom_forwarding_path                = "/"
              + forwarding_protocol                   = "HttpsOnly"
            }

          - redirect_configuration {
              - custom_path       = "/tenantc/" -> null
              - redirect_protocol = "HttpsOnly" -> null
              - redirect_type     = "Moved" -> null
            }
        }
      ~ routing_rule {
            accepted_protocols = [
                "Https",
            ]
            enabled            = true
            frontend_endpoints = [
                "canary-fd-endpoint-ext",
            ]
            id                 = "/subscriptions/xxxx/resourcegroups/canary-frontdoor/providers/Microsoft.Network/Frontdoors/canary-fd/RoutingRules/HTTPS-SANDBOX-Redirect"
          ~ name               = "HTTPS-SANDBOX-Redirect" -> "HTTPS-tenantc-Redirect"
          ~ patterns_to_match  = [
              - "/sandbox",
              + "/tenantc",
            ]

          ~ redirect_configuration {
              ~ custom_path       = "/sandbox/" -> "/tenantc/"
                redirect_protocol = "HttpsOnly"
                redirect_type     = "Moved"
            }
        }
      ~ routing_rule {
            accepted_protocols = [
                "Https",
            ]
            enabled            = true
            frontend_endpoints = [
                "canary-fd-endpoint-ext",
            ]
            id                 = "/subscriptions/xxxx/resourcegroups/canary-frontdoor/providers/Microsoft.Network/Frontdoors/canary-fd/RoutingRules/HTTPS-tenantd-Redirect"
          ~ name               = "HTTPS-tenantd-Redirect" -> "HTTPS-SANDBOX-Redirect"
          ~ patterns_to_match  = [
              - "/tenantd",
              + "/sandbox",
            ]

          ~ redirect_configuration {
              ~ custom_path       = "/tenantd/" -> "/sandbox/"
                redirect_protocol = "HttpsOnly"
                redirect_type     = "Moved"
            }
        }
      ~ routing_rule {
            accepted_protocols = [
                "Https",
            ]
            enabled            = true
            frontend_endpoints = [
                "canary-fd-endpoint-ext",
            ]
            id                 = "/subscriptions/xxxx/resourcegroups/canary-frontdoor/providers/Microsoft.Network/Frontdoors/canary-fd/RoutingRules/HTTPS-TENANTA-Forward"
          ~ name               = "HTTPS-TENANTA-Forward" -> "HTTPS-tenantd-Redirect"
          ~ patterns_to_match  = [
              - "/tenanta/",
              - "/tenanta/*",
              + "/tenantd",
            ]

          - forwarding_configuration {
              - backend_pool_name                     = "tenanta-pool" -> null
              - cache_enabled                         = false -> null
              - cache_query_parameter_strip_directive = "StripNone" -> null
              - cache_use_dynamic_compression         = false -> null
              - custom_forwarding_path                = "/" -> null
              - forwarding_protocol                   = "HttpsOnly" -> null
            }

          + redirect_configuration {
              + custom_path       = "/tenantd/"
              + redirect_protocol = "HttpsOnly"
              + redirect_type     = "Moved"
            }
        }
        routing_rule {
            accepted_protocols = [
                "Https",
            ]
            enabled            = true
            frontend_endpoints = [
                "canary-fd-endpoint-ext",
            ]
            id                 = "/subscriptions/xxxx/resourcegroups/canary-frontdoor/providers/Microsoft.Network/Frontdoors/canary-fd/RoutingRules/HTTPS-TENANTA-Redirect"
            name               = "HTTPS-TENANTA-Redirect"
            patterns_to_match  = [
                "/tenanta",
            ]

            redirect_configuration {
                custom_path       = "/tenanta/"
                redirect_protocol = "HttpsOnly"
                redirect_type     = "Moved"
            }
        }
        routing_rule {
            accepted_protocols = [
                "Https",
            ]
            enabled            = true
            frontend_endpoints = [
                "canary-fd-endpoint-ext",
            ]
            id                 = "/subscriptions/xxxx/resourcegroups/canary-frontdoor/providers/Microsoft.Network/Frontdoors/canary-fd/RoutingRules/HTTPS-TENANTB-Redirect"
            name               = "HTTPS-TENANTB-Redirect"
            patterns_to_match  = [
                "/tenantb",
            ]

            redirect_configuration {
                redirect_protocol = "HttpsOnly"
                redirect_type     = "Moved"
            }
        }
    }

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

Which isn’t so bad assuming it can deploy these changes as everything will just end up back as it was, but the apply fails because of:

Apply Plan
module.scaleUnit.module.frontdoor.azurerm_frontdoor.frontdoor: Modifying... [id=/subscriptions/xxxx/resourcegroups/canary-frontdoor/providers/Microsoft.Network/frontdoors/canary-fd]
module.scaleUnit.module.frontdoor.azurerm_frontdoor.frontdoor: Still modifying... [id=/subscriptions/xxxx...rosoft.Network/frontdoors/canary-fd, 10s elapsed]
module.scaleUnit.module.frontdoor.azurerm_frontdoor.frontdoor: Still modifying... [id=/subscriptions/xxxx...rosoft.Network/frontdoors/canary-fd, 20s elapsed]
module.scaleUnit.module.frontdoor.azurerm_frontdoor.frontdoor: Still modifying... [id=/subscriptions/xxxx...rosoft.Network/frontdoors/canary-fd, 30s elapsed]
module.scaleUnit.module.frontdoor.azurerm_frontdoor.frontdoor: Still modifying... [id=/subscriptions/xxxx...rosoft.Network/frontdoors/canary-fd, 40s elapsed]
module.scaleUnit.module.frontdoor.azurerm_frontdoor.frontdoor: Still modifying... [id=/subscriptions/xxxx...rosoft.Network/frontdoors/canary-fd, 50s elapsed]
module.scaleUnit.module.frontdoor.azurerm_frontdoor.frontdoor: Still modifying... [id=/subscriptions/xxxx...rosoft.Network/frontdoors/canary-fd, 1m0s elapsed]
module.scaleUnit.module.frontdoor.azurerm_frontdoor.frontdoor: Still modifying... [id=/subscriptions/xxxx...rosoft.Network/frontdoors/canary-fd, 1m10s elapsed]

Error: unable to update Custom HTTPS configuration for Frontend Endpoint "canary-fd-endpoint-ext" (Resource Group "canary-frontdoor"): unable to enable/update Custom Domain HTTPS for Frontend Endpoint "canary-fd-endpoint-ext" (Resource Group "canary-frontdoor"): enabling Custom Domain HTTPS for Frontend Endpoint: frontdoor.FrontendEndpointsClient#EnableHTTPS: Failure sending request: StatusCode=400 -- Original Error: Code="BadRequest" Message="That action isn’t allowed in this profile."

  on ..\..\..\infra\terraform\frontdoor\main.tf line 12, in resource "azurerm_frontdoor" "frontdoor":
  12: resource "azurerm_frontdoor" "frontdoor" {

Steps to Reproduce

Run plan - this only started happening today and no terraform changes were made between yesterday and today when it started happening. So can only presume something has changed in how azure API is returning data.

I have tried the following:

  1. Editing the state file to change the order of the frontend_endpoints
  2. Updating frontdoor through management azure api to change order of end points.

Both do not change the behaviour

This has now rended our pipeline stuck and we cannot deploy any changes which is quite a big deal!

About this issue

  • Original URL
  • State: closed
  • Created 4 years ago
  • Reactions: 93
  • Comments: 38 (9 by maintainers)

Commits related to this issue

Most upvoted comments

Bear with us a bit longer please. 2.47 has prep work to get this sorted (pun intended) for good.

Starting April 9th Azure Frontdoor will require the CNAME records to be destroyed before the Frontdoor Resource is destroyed. So recreation/constantly changing order will probably cause even more troubles soon.

I am experiencing this issue and i do not have dynamic blocks in my terraform config. every time terraform runs it says there is a change, it applies the change, and then the next run still exhibits the same change

it appears that the frontend_endpoints block isn’t trying to match on the name field, but rather is forcing a specific ordering of the resources in the spec

Through some investigation, it seems like our dynamic block on the FrontDoor resource causes the diff in state. We’ve since removed the dynamic block implementation, manually ordered it and it seems to expect no changes.

I also thought this might be the case and I rewrote my entire infrastructure removing those dynamic blocks. Only to have it still have the same issues with ordering.

I the tried to reorder my blocks to match FrontDoor but every time it returned something different.

I don’t think we can assume it’s an issue with dynamic blocks. Seems as though terraform’s logic on matching the block to FrontDoor returned values isn’t solid. It shouldn’t assume it’s going to get the same order of items on each run. But that’s only am assumption based on testing.

I had a similar experience. I was using dynamic blocks to configure routing_rule’s, backend_pool’s, backend_pool_load_balancing’s, and backend_pool_health_probe’s. I switched this configuration to use a static set of those blocks and found that the provider still wanted to reorder them. It appears that Azure’s API is returning the blocks in a near-random order, and the provider is going to need to account for that.

How do we get attention on this issue? It seems lots of us have the problem but no traction on getting anyone to take interest

I am also facing into this issue, every time a reordering diff is shown.

Error: updating Custom HTTPS configuration for Frontend Endpoint "portalFrontendpoint" (Front Door "asgardio-1994" / Resource Group "dhananjaya-test"): unable to enable/update Custom Domain HTTPS for Frontend Endpoint "portalFrontendpoint" (Resource Group "dhananjaya-test"): enabling Custom Domain HTTPS for Frontend Endpoint: frontdoor.FrontendEndpointsClient#EnableHTTPS: Failure sending request: StatusCode=400 -- Original Error: Code="BadRequest" Message="That action isn’t allowed in this profile."

  on ../../../modules/azurerm/Front-Door/azurerm_frontdoor.tf line 13, in resource "azurerm_frontdoor" "front-door":
  13: resource "azurerm_frontdoor" "front-door" {

Starting April 9th Azure Frontdoor will require the CNAME records to be destroyed before the Frontdoor Resource is destroyed. So recreation/constantly changing order will probably cause even more troubles soon.

NOTE: If you have not disabled the behavior on your subscription, it will cause a PANIC in the terraform runtime when you call destroy. This is not a bug, it is an expected behavior at this point in time because the delete call does not return a future object causing a nil reference. šŸ˜•

You can disable the behavior on your subscription by registering the feature flag: az feature register --namespace Microsoft.Network --name BypassCnameCheckForCustomDomainDeletion

@GarethOates , I’m under the impression that the re-order was a one time necessity if you’re re-importing it back into the state, and after the first re-order, it shouldn’t need to order it again, but I could be wrong on that.

You may be right. I have the added complication that my code is deployed to two separate environments so the order has to end up being the same in both. I thought destroying and recreating the resource in my QA env would alleviate this problem but alas it did not.