Skip to content

Azure FrontDoor Module

FrontDoor is made up of FrontEnd Endpoints, BackEnd Pools, and Routing Rules.

FrontEnds

The public-side, which have a DNS name and SSL Certificate.

Backend Pools

Where the FrontDoor makes the request to, typically an App Service. Each pool can be made up of multiple Backends, each with a DNS name, but typically only 1 is used. Multiple Backend Pool are often used, depending on routing behavior.

Routing Rules

They decide which backend to route the traffic, based on path, headers, etc.

Multiple Backends are used for Load Balancing at the FrontDoor level, inside the Backend Pool. Backend Pools are used as Routing targets.

Notes

  • This module only supports a single Backend per Backend Pool. App Services do not need FrontDoor Load Balancing as it is done at automatically at the App Service layer.

Usage

module "frontdoor" {
  source = "git::ssh://git@ssh.dev.azure.com/v3/cmgfidev/DevOps/shared-infrastructure//modules/azure-frontdoor?ref=v{x.y.z}"

  rg        = object    # Required
  name      = string    # Required
  waf_name  = string    # Optional, WAF disabled if not provided

  ## If a value isn't provided, the default will be used
   # Provide a populated object to overwrite the default
   #  The next section is where objects can be added, in addition to the default, rather than replacing it
   # Set to an empty object ({}) to not use the default at all
   #   See variables.tf for the default values
  default_frontend_endpoint           = object    # Optional, default azurefd.net frontend
  default_forwarding_rule             = object    # Optional, forwards all traffic to default frontend
  default_deployslot_forwarding_rule  = object    # Optional, /deploy-slot/* to deploy-slot backend
  default_redirect_rule               = object    # Optional, HTTP redirected to HTTPS

  ## These allow additional frontends, backends, and routing rules
  custom_frontend_endpoints   = list(object)    # Optional
  backend_pools               = list(object)    # Optional
  custom_routing_rules        = list(object)    # Optional

  tags = map(string)  # Optional
}

output "frontdoor" {
  value = module.frontdoor.this
}

Objects

frontend_endpoint {
  name      = string
  host_name = string

  session_affinity_enabled                = bool
  web_application_firewall_policy_link_id = string
}
backend_pool {
  name        = string
  host_header = string
  address     = string
  http_port   = number  # Default: 80
  https_port  = number  # Default: 443

  load_balancing   = {
    name = string
  }

  health_probe     = {
    name      = string
    protocol  = string  # Default: "Https"
    path      = string  # Default: "/diagnostics/ping"
    enabled   = bool    # Default: true
  }

}
routing_rule {
    name                = string
    enabled             = bool    # Default: true
    accepted_protocols  = list    # Default: All (Http and Https)
    patterns_to_match   = string  # Default: All (/*)
    frontend_endpoints  = list    # Default: All (frontend_endpoints[*])

    forwarding_configuration = [{
      backend_pool_name      = string   # Default: default backend_pool
      custom_forwarding_path = string   # Default: "/"
      cache_enabled          = bool     # Default: false
      forwarding_protocol    = string   # Default: "HttpsOnly"
    }]

    redirect_configuration = [{
      custom_path       = string  # Default: null
      redirect_protocol = string  # Default: "HttpsOnly"
      redirect_type     = string  # Default: "moved"
    }]

}

Examples

Create a single frontdoor with all defaults

module "frontdoor" {
  source = "git::ssh://git@ssh.dev.azure.com/v3/cmgfidev/DevOps/shared-infrastructure//modules/azure-frontdoor?ref=v{x.y.z}"

}
output "frontdoor" {
  value = module.frontdoor.this
}

Create multiple frontdoors with custom settings

module "frontdoor" {
  source = "git::ssh://git@ssh.dev.azure.com/v3/cmgfidev/DevOps/shared-infrastructure//modules/azure-frontdoor?ref=v{x.y.z}"
  for_each = {
    "CxUi" = {
      rg = azurerm_resource_group.main
      default_forwarding_rule = {
        cache_enabled = true
        cache_query_parameter_strip_directive = "StripNone"
        cache_use_dynamic_compression = true
      }
    }
    "CxApi" = {rg = azurerm_resource_group.main}
    "TpPublicApi" = {rg = azurerm_resource_group.third_party}
  }

  rg       = each.value.rg
  name     = format("Cmg%sFd%s01",
    each.name,
    var.env_name,
  )
  waf_name = lower(format("cmg%swafpolicy%s",
    each.name,
    var.env_name,
  ))

  backend_pools = [
    {
      name        = module.appservice[each.name].this.name
      host_name   = module.appservice[each.name].this.hostname
      probe_path  = "/"   # Use "/" instead of the default value for this pool
    },
    {
      name          = "backend-deploy-slot-pool"
      host_name     = module.appservice[each.name].slot["deploy"].hostname
      probe_enabled = false   # Disable the probe for this pool
    }
  ]

  custom_frontend_endpoints = [
    {
      name      = "public-frontend"
      host_name = var.public-hostname
    }
  ]

}
output "frontdoors" {
  value = {
    "ConX Ui" = module.frontdoor["CxUi"].this
    "ConX Api" = module.frontdoor["CxApi"].this
    "ThirdParty PublicApi" = module.frontdoor["TpPublicApi"].this
  }
}

Requirements

Name Version
terraform >= 1.0
azurerm >= 3.21.0

Providers

Name Version
azurerm >= 3.21.0

Resources

Name Type
azurerm_frontdoor.this resource
azurerm_frontdoor_custom_https_configuration.this resource
azurerm_frontdoor_firewall_policy.this resource

Inputs

Name Description Type Default Required
custom_backend_pools List of additional Backend Pools. This module only supports a single backend per backend pool, as load balancing is done at the App Service level.
list(object({
name = string # Required
host_name = string # Required
}))
[] no
custom_frontend_endpoints List of frontend endpoints, not counting the default list(map(any)) n/a yes
custom_routing_rules List of routing rules, not counting the default HTTP->HTTPS any [] no
default_backend_pool Object describing the default backend pool, which normally points to the App Service Production slot any {} no
default_deployslot_backend_pool Object describing the deployment slot backend pool, which normally points to the App Service Deploy slot any {} no
default_deployslot_forwarding_rule Default Deplyment Slot Forwarding Routing Rule, to send all /deploy-slot/* requests to the backend. Set to {} to disable any {} no
default_forwarding_rule Default Forwarding Routing Rule, to send all requests to the backend. Set to {} to disable any {} no
default_frontend_endpoint Object describing the default frontend endpoint map(any) {} no
default_redirect_rule Default Redirect Routing Rule to redirect HTTP to HTTPS. Set to {} to disable any {} no
name Required. Name of Frontdoor resource string n/a yes
rg Required. Resource Group object
object({
location = string
name = string
})
n/a yes
tags Tags to be merged with module tags (forming local.tags) map(string) {} no
waf_block_mode_enabled Optional. Should the WAF be in block mode? If false, it will be in detect-only mode. bool false no
waf_id Optional. Id of an existing Web Application Firewall resource, one will be created if not provided string null no

Outputs

Name Description
custom_frontend_endpoints n/a
this n/a