带有 Terraform 的 Azure Front Door 中的多个 frontend_enpoint

Multiple frontend_enpoint in Azure Front Door with Terraform

我正在尝试使用 Terraform 构建 Azure FrontDoor,但在尝试配置两个前端然后将其中之一绑定到自定义 HTTPS 配置时遇到问题。但是我收到以下错误 The argument "frontend_endpoint_id" is required, but no definition was found.

我只是想不通您将如何指定两个 Front Door 端点,然后在自定义 https 配置中引用其中一个。下面的代码。

resource "azurerm_frontdoor" "jccroutingrule" {
  depends_on = [
    cloudflare_record.create_frontdoor_CNAME,
    azurerm_key_vault.jctestingenv_keyvault,
    azurerm_key_vault_certificate.jcimportedcert
  ]
  name                = "testingfrontdoor"
  resource_group_name = azurerm_resource_group.Terraform.name
  #enforce_backend_pools_certificate_name_check = false
  routing_rule {
    name               = "jccroutingrule"
    accepted_protocols = ["Http", "Https"]
    patterns_to_match  = ["/*"]
    frontend_endpoints = ["jccfrontendendpoint","frontendendpoint2"]
    forwarding_configuration {
      forwarding_protocol = "MatchRequest"
      backend_pool_name   = "jccbackendpool"
    }
  }

  backend_pool_load_balancing {
    name                        = "jccloadbalancesettings"
    sample_size                 = 255
    successful_samples_required = 1
  }

  backend_pool_health_probe {
    name                = "jcchealthprobesettings"
    path                = "/health/probe"
    protocol            = "Https"
    interval_in_seconds = 240
}


  backend_pool {
    name = "jccbackendpool"
    backend {
      host_header = format("portal-staging-westeurope.jason.website")
      address     = format("portal-staging-westeurope.jason.website")
      http_port   = 80
      https_port  = 443
      weight      = 50
      priority    = 1
      enabled     = true
    }

    load_balancing_name = "jccloadbalancesettings"
    health_probe_name   = "jcchealthprobesettings"
  }

  frontend_endpoint {
    name      = "jccfrontendendpoint"
    host_name = format("testingfrontdoor.azurefd.net")
  }

  frontend_endpoint {
    name      = "frontendendpoint2"
    host_name = format("portal-staging.jason.website")
  }

}

resource "azurerm_frontdoor_custom_https_configuration" "portal_staging_https_config" {
  frontend_endpoint_id              = azurerm_frontdoor.jccroutingrule.frontend_endpoint[1].id
  custom_https_provisioning_enabled = true

  custom_https_configuration {
    certificate_source                      = "AzureKeyVault"
    azure_key_vault_certificate_secret_name = "imported-cert"
    azure_key_vault_certificate_vault_id    = azurerm_key_vault_certificate.jcimportedcert.id
  }
}

因此,从此处 azurerm_frontdoor 的文档中,我看到它们在我认为您感兴趣的字段下方导出..

frontend_endpoints - A map/dictionary of Frontend Endpoint Names (key) to the Frontend Endpoint ID (value)

frontend_endpoints 是一个地图对象,包含端点名称作为键,id 作为值。因此,您可以使用 lookup 函数从键中提取值。

最后你的 azurerm_frontdoor_custom_https_configuration 如下所示::

resource "azurerm_frontdoor_custom_https_configuration" "portal_staging_https_config" {
  frontend_endpoint_id              = lookup(azurerm_frontdoor.jccroutingrule.frontend_endpoints, "frontendendpoint2", "what?")
  custom_https_provisioning_enabled = true

  custom_https_configuration {
    certificate_source                      = "AzureKeyVault"
    azure_key_vault_certificate_secret_name = "imported-cert"
    azure_key_vault_certificate_vault_id    = azurerm_key_vault_certificate.jcimportedcert.id
  }
}

以防万一,如果您改变主意使用 jccfrontendendpoint 端点,请随时将该密钥放入 lookup 函数 :-)

来自 terraform docs:

resource "azurerm_frontdoor_custom_https_configuration" "portal_staging_https_config" {
  frontend_endpoint_id              = azurerm_frontdoor.jccroutingrule.frontend_endpoint["frontendendpoint2"]
  custom_https_provisioning_enabled = true

  custom_https_configuration {
    certificate_source                      = "AzureKeyVault"
    azure_key_vault_certificate_secret_name = "imported-cert"
    azure_key_vault_certificate_vault_id    = azurerm_key_vault_certificate.jcimportedcert.id
  }
}

我最终解决了这个问题,在 github 上 post 之后:https://github.com/hashicorp/terraform-provider-azurerm/pull/11456

最后我不得不改变一些东西,首先我不得不将 frontend_endpoint_id 更改为 "${azurerm_frontdoor.jccroutingrule.id}/frontendEndpoints/${local.frontendendpoint2}" 出于某种原因你需要制作 frontend_endpoint 名称值到一个局部变量。所以您的代码将如下所示:

frontend_endpoint {
    name      = local.frontendendpoint2
    host_name = format("portal-staging.jason.website")
  }

resource "azurerm_frontdoor_custom_https_configuration" "portal_staging_https_config" {
  frontend_endpoint_id              = "${azurerm_frontdoor.jccroutingrule.id}/frontendEndpoints/${local.frontendendpoint2}"
  custom_https_provisioning_enabled = true

  custom_https_configuration {
    certificate_source                      = "AzureKeyVault"
    azure_key_vault_certificate_secret_name = "imported-cert"
    azure_key_vault_certificate_vault_id    = azurerm_key_vault_certificate.jcimportedcert.id
  }
}

现在,如果您在执行 https_configuration 之前构建 Frontdoor,您实际上必须销毁状态文件,以便构建前门,然后应用自定义 HTTPS 配置。我无法在不破坏状态文件的情况下构建它,我分享的 link 上的其他人也这么说。

此外,frontend_endpoint_id 的文档是错误的,如果您选择不使用我提供的格式并想要执行类似以下操作:azurerm_frontdoor.jccroutingrule.frontend_endpoint["frontendendpoint2"] 您必须确保在末尾附加 .id否则它不会正确查找键值,您只会得到一个错误。示例:azurerm_frontdoor.jccroutingrule.frontend_endpoint["frontendendpoint2"].id

最后一点要注意,您需要在路由规则下更改 frontend_endpoints 以包含您的本地值,如下所示:frontend_endpoints = ["jccfrontendendpoint","${local.frontendendpoint2}"] 否则当您再次访问 https 自定义配置时,查找将失败。

老实说,这个前门配置充其量是错误的,它的文档非常空泛,在某些地方甚至是错误的。

我的完整配置使其易于理解:

resource "azurerm_frontdoor" "jccroutingrule" {
  depends_on = [
    cloudflare_record.create_frontdoor_CNAME,
    azurerm_key_vault.jctestingenv_keyvault,
    azurerm_key_vault_certificate.jcimportedcert
  ]
  name                = "testingfrontdoor"
  resource_group_name = azurerm_resource_group.Terraform.name
  #enforce_backend_pools_certificate_name_check = false
  routing_rule {
    name               = "jccroutingrule"
    accepted_protocols = ["Http", "Https"]
    patterns_to_match  = ["/*"]
    frontend_endpoints = ["jccfrontendendpoint","${local.frontendendpoint2}"]
    forwarding_configuration {
      forwarding_protocol = "MatchRequest"
      backend_pool_name   = "jccbackendpool"
    }
  }

  backend_pool_load_balancing {
    name                        = "jccloadbalancesettings"
    sample_size                 = 255
    successful_samples_required = 1
  }

  backend_pool_health_probe {
    name                = "jcchealthprobesettings"
    path                = "/health/probe"
    protocol            = "Https"
    interval_in_seconds = 240
}


  backend_pool {
    name = "jccbackendpool"
    backend {
      host_header = format("portal-staging-westeurope.jason.website")
      address     = format("portal-staging-westeurope.jason.website")
      http_port   = 80
      https_port  = 443
      weight      = 50
      priority    = 1
      enabled     = true
    }

    load_balancing_name = "jccloadbalancesettings"
    health_probe_name   = "jcchealthprobesettings"
  }

  frontend_endpoint {
    name      = "jccfrontendendpoint"
    host_name = format("testingfrontdoor.azurefd.net")
  }

  frontend_endpoint {
    name      = local.frontendendpoint2
    host_name = format("portal-staging.jason.website")
  }

}

resource "azurerm_frontdoor_custom_https_configuration" "portal_staging_https_config" {
  frontend_endpoint_id              = "${azurerm_frontdoor.jccroutingrule.id}/frontendEndpoints/${local.frontendendpoint2}"
  custom_https_provisioning_enabled = true

  custom_https_configuration {
    certificate_source                      = "AzureKeyVault"
    azure_key_vault_certificate_secret_name = "imported-cert"
    azure_key_vault_certificate_vault_id    = azurerm_key_vault.jctestingenv_keyvault.id
  }
}