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.52k stars 4.6k forks source link

Unable to create additional frontdoor frontend_endpoints with custom_https_configuration after first apply #10504

Open ericjohnson2 opened 3 years ago

ericjohnson2 commented 3 years ago

Community Note

Terraform (and AzureRM Provider) Version

Terraform v0.14.2
+ provider registry.terraform.io/hashicorp/azuread v1.3.0
+ provider registry.terraform.io/hashicorp/azurerm v2.46.0
+ provider registry.terraform.io/hashicorp/external v2.0.0
+ provider registry.terraform.io/hashicorp/random v3.0.1

Affected Resource(s)

Terraform Configuration Files

Module

resource "azurerm_frontdoor" "example-frontdoor" {
  name                                         = var.name
  resource_group_name                          = var.resource_group
  enforce_backend_pools_certificate_name_check = var.enforce_backend_pools_certificate_name_check
  load_balancer_enabled                        = var.load_balancer_enabled

  dynamic "routing_rule" {
    for_each = var.routing_rules
    content {
      name               = routing_rule.value.name
      accepted_protocols = ["Http", "Https"]
      patterns_to_match  = routing_rule.value.patterns_to_match
      enabled            = true
      frontend_endpoints = routing_rule.value.frontend_endpoints
      dynamic "forwarding_configuration" {
        for_each = routing_rule.value.configuration == "Forwarding" ? [routing_rule.value.forwarding_configuration] : []
        content {
          forwarding_protocol = "MatchRequest"
          backend_pool_name   = forwarding_configuration.value.backend_pool_name
        }
      }
      dynamic "redirect_configuration" {
        for_each = routing_rule.value.configuration == "Redirect" ? [routing_rule.value.redirect_configuration] : []
        content {
          custom_host         = redirect_configuration.value.custom_host
          redirect_protocol   = redirect_configuration.value.redirect_protocol
          redirect_type       = redirect_configuration.value.redirect_type
          custom_fragment     = redirect_configuration.value.custom_fragment
          custom_path         = redirect_configuration.value.custom_path
          custom_query_string = redirect_configuration.value.custom_query_string
        }
      }
    }
  }

  dynamic "backend_pool" {
    for_each = var.backend_pools
    content {
      name                = backend_pool.value.name
      load_balancing_name = "loadbalancer"
      health_probe_name   = "healthprobe"
      dynamic "backend" {
        for_each = backend_pool.value.backend
        content {
          host_header = backend.value.host_header
          address     = backend.value.address
          http_port   = 80
          https_port  = 443
        }
      }
    }
  }

  frontend_endpoint {
    name                              = "example-frontdoor"
    host_name                         = "${var.name}.azurefd.net"
    custom_https_provisioning_enabled = false
  }

  dynamic "frontend_endpoint" {
    for_each = var.frontend_endpoints
    content {
      name      = frontend_endpoint.value.name
      host_name = frontend_endpoint.value.host_name
    }
  }
}

resource "azurerm_frontdoor_custom_https_configuration" "custom_https_configuration" {
  for_each                          = { for frontend in azurerm_frontdoor.example-frontdoor.frontend_endpoint : frontend.name => frontend }
  frontend_endpoint_id              = each.value.id
  custom_https_provisioning_enabled = each.key != "example-frontdoor" ? local.frontend_https_configurations[each.key].custom_https_provisioning_enabled : false 
  dynamic "custom_https_configuration" {
    for_each = (each.key != "example-frontdoor" ? local.frontend_https_configurations[each.key].custom_https_provisioning_enabled : false) ? [1] : []
    content {
      certificate_source                         = "AzureKeyVault"
      azure_key_vault_certificate_secret_name    = XXXX
      azure_key_vault_certificate_secret_version = XXXX
      azure_key_vault_certificate_vault_id       = XXXX
    }
  }
}

locals {
  frontend_https_configurations = { for frontend in var.frontend_endpoints : frontend.name => frontend }
}

Module Usage

module "frontdoor" {
  source           = "./frontdoor"
  name             = "examplefd"
  az_region      = "eastus"
  keyvault_id   = XXXX
  resource_group = "examplerg"
  azure_key_vault_certificate_secret_name = XXXX
  azure_key_vault_certificate_secret_version = XXXX
  backend_pools = [{ 
    name = "name"
    backend = [{
      host_header = "host"
      address     = "host"
    }]
  }]
  routing_rules = [{
    name               = "name"
    patterns_to_match  = ["/*"]
    configuration      = "Forwarding"
    frontend_endpoints = ["name"]
    forwarding_configuration = {
      backend_pool_name = "name"
    }
  }]
  frontend_endpoints = [{
    name = "name"
    host_name = "frontend"
    custom_https_provisioning_enabled = true
  },
 {
    name = "name2"
    host_name = "frontend2"
    custom_https_provisioning_enabled = true
  }]
}

Debug Output

2021/02/08 11:14:42 [WARN] Provider "registry.terraform.io/hashicorp/azurerm" produced an unexpected new value for module.frontdoor["eastus"].azurerm_frontdoor.example-frontdoor during refresh.
      - .tags: was null, but now cty.MapValEmpty(cty.String)
      - .frontend_endpoint[0].custom_https_provisioning_enabled: was cty.False, but now cty.True
      - .frontend_endpoint[0].custom_https_configuration: block count changed from 0 to 1
      - .frontend_endpoint[2].custom_https_provisioning_enabled: was cty.False, but now cty.True
      - .frontend_endpoint[2].custom_https_configuration: block count changed from 0 to 1
      - .frontend_endpoint[3].custom_https_provisioning_enabled: was cty.False, but now cty.True
      - .frontend_endpoint[3].custom_https_configuration: block count changed from 0 to 1
      - .frontend_endpoint[4].custom_https_provisioning_enabled: was cty.False, but now cty.True
      - .frontend_endpoint[4].custom_https_configuration: block count changed from 0 to 1
      - .frontend_endpoint[5].custom_https_provisioning_enabled: was cty.False, but now cty.True
      - .frontend_endpoint[5].custom_https_configuration: block count changed from 0 to 1
2021/02/08 11:14:42 [WARN] Provider "registry.terraform.io/hashicorp/azurerm" produced an invalid plan for module.frontdoor["eastus"].azurerm_frontdoor.example-frontdoor, but we are tolerating it because it is using the legacy plugin SDK.
    The following problems may be the cause of any confusing errors from downstream operations:
      - .frontend_endpoint[0].custom_https_configuration: block count in plan (1) disagrees with count in config (0)
      - .frontend_endpoint[2].custom_https_configuration: block count in plan (1) disagrees with count in config (0)
      - .frontend_endpoint[3].custom_https_configuration: block count in plan (1) disagrees with count in config (0)
      - .frontend_endpoint[4].custom_https_configuration: block count in plan (1) disagrees with count in config (0)
      - .frontend_endpoint[5].custom_https_configuration: block count in plan (1) disagrees with count in config (0)
      ...

Panic Output

Expected Behaviour

Initial creation of frontdoor with custom https configuration works.

Adding a new frontend_endpoint should be added to the frontdoor resource and the custom https configuration should be created

Actual Behaviour

Initial creation of frontdoor with custom https configuration works.

Adding a new frontend_endpoint causes

Error: "frontend_endpoint_id": required field is not set

  on frontdoor/main.tf line 89, in resource "azurerm_frontdoor_custom_https_configuration" "custom_https_configuration":
  89: resource "azurerm_frontdoor_custom_https_configuration" "custom_https_configuration" {

The frontend_endpoint.id is set to null

Steps to Reproduce

Create frontdoor with a few frontend_endpoints that use the azurerm_frontdoor_custom_https_configuration to do the custom frontend configuration. Using the same frontdoor, add an additional frontend_endpoint with a azurerm_frontdoor_custom_https_configuration. Perform a plan after you have added the additional endpoint.

  1. terraform apply frontdoor and custom https config
  2. add additional frontend
  3. terraform plan
  4. id of the new frontend endpoint is set to null so the plan will fail on the custom https configuration

Important Factoids

none

favoretti commented 3 years ago

I'm 99% certain it's related to what we're trying to partially address with #9357. As soon as that one is merged, hopefully the release after that will fix sorting of the properties. As it is now such advanced terraforming of frontdoor leads to these sad results.

Abhishekqwerty commented 3 years ago

Yeah, I am also facing the same issue. Hoping to get this resolve when #9357 gets merged.

ericjohnson2 commented 3 years ago

@WodansSon, I think https://github.com/terraform-providers/terraform-provider-azurerm/pull/11456 will address this issue as well. Once v2.58.0 is released I can test and update.

WodansSon commented 3 years ago

@WodansSon, I think #11456 will address this issue as well. Once v2.58.0 is released I can test and update.

@ericjohnson2 I absolutely think that 11456 will address this issue... lmk πŸš€

veronicapetersen commented 3 years ago

This is still an issue with 2.58.0

ericjohnson2 commented 3 years ago

I tried to force dependency with depends_on as a long shot, as expected that did not work. This issue takes longer to manually resolve now that Azure requires you to delete all associated CNAME records in order to completely destroy a Front Door instance 😦

edit: as noted in the #11456 comments you can get around this for now by hard coding

LoW0lf commented 3 years ago

Related issues: #11857 #11348

yube-sitecore commented 2 years ago

Is there are any updates or plans regarding this issue? We facing the same problem, so it's not possible to add or change the existing frontendendpoint, without removing azurerm_frontdoor_custom_https_configuration, because azurerm_frontdoor_custom_https_configuration doesn't track upcoming changes from the frontendpoint resources and as result, we need to comment all azurerm_frontdoor_custom_https_configuration resources, apply changes to frontendendpoints and after deploy azurerm_frontdoor_custom_https_configuration. If azurerm_frontdoor_custom_https_configuration will evaluate upcoming changes to frontendendpoints.

mkeller25 commented 2 years ago

+1 here. Can't believe it took me this long to find this thread. I've been wrenching on this for FAR longer than I'd like to admit and I've come to the same conclusion.

frontend_endpoint_id is jacked up for new frontend_endpoints

PbALpi7xEX commented 2 years ago

I just hit this issue now as well... Added a new endpoint, and running into a wall. I have my terraform deployments all setup in ADO pipelines... but what seems to have worked for now, is running targeted plan/apply for the FD instance to force it pickup and apply the endpoint.. then a plan/apply again which will pickup the remaining custom https configurations .. at which point, the new FD endpoint is visible

jasric89 commented 2 years ago

I have the same problem this is not fixed nor is it part of any other PR just spent hours browsing through github problems. Needs fixing.