This module creates and manages an Azure Front Door/Application gateway, and associated WAF policy.
Example module usage:
module "azurerm_waf" {
source = "github.com/dfe-digital/terraform-azurerm-front-door-app-gateway-waf?ref=v0.3.2"
## General configuration
environment = "dev"
project_name = "waf"
azure_location = "uksouth"
existing_resource_group = "my-existing-rg"
# existing_virtual_network = ""
virtual_network_address_space = "172.16.0.0/12"
# enable_latency_monitor = false
# latency_monitor_threshold = 5000 # ms
# response_request_timeout = 60 # seconds
## Web Application Firewall configuration
enable_waf = true
waf_mode = "Prevention" # or "Detection"
## Choose whether to deploy an Azure Front Door, or an App Gateway
waf_application = "CDN" # or "AppGatewayV2"
waf_targets = {
"my-origin-name" = {
domain = "my-fqdn.example.tld",
# create_custom_domain = true,
# enable_health_probe = true,
# health_probe_interval = 60,
# health_probe_request_type = "HEAD", # or "GET"
# health_probe_path = "/",
# cdn_add_response_headers = [
# {
# name = "X-Custom-Http-Header",
# value = "My-Favourite-Value"
# }
# ],
# cdn_add_request_headers = [
# {
# name = "X-Request-Header",
# value = "My-Favourite-Value"
# }
# ],
# cdn_remove_response_headers = [
# "X-Remove-This-Header"
# ]
# cdn_remove_request_headers = [
# "X-Remove-Me"
# ]
}
}
waf_custom_rules = {
"PostParamValuesfoo" = {
priority = 10,
action = "Allow",
match_conditions = {
"allow-any-foo" = {
match_variable = "PostArgs",
match_values = []
operator = "Any",
selector = "foo"
}
}
}
}
## Azure Front Door specific configuration
cdn_sku = "Premium_AzureFrontDoor" # or "Standard_AzureFrontDoor"
# cdn_host_redirects = [
# "my-site-redirect" = {
# from = "example.com",
# to = "my.example.com"
# }
# ]
## Add custom HTTP Response Headers to all origins
# cdn_add_response_headers = [
# {
# name = "X-Apply-To-All-Origins",
# value = "MyValue"
# }
# ]
## Remove HTTP Response Headers from all origins
# cdn_remove_response_headers = [
# "X-Remove-Me"
# ]
# cdn_waf_enable_rate_limiting = false
# cdn_waf_rate_limiting_duration_in_minutes = 5
# cdn_waf_rate_limiting_threshold = 1000
# cdn_waf_rate_limiting_bypass_ip_list = [ 1.1.1.1, 8.8.8.8 ]
# cdn_waf_rate_limiting_action = "Block" # one of "Allow", "Block", "Log"
cdn_waf_managed_rulesets = {
"BotProtection" = {
version = "preview-0.1",
action = "Block"
},
"DefaultRuleSet" = {
version = "1.0",
action = "Block"
# overrides = {
# "SQLI" = {
# "942440" = { # SQL Comment Sequence Detected
# action = "Block"
# exclusions = {
# "rcn-sw-cookies" = {
# match_variable = "RequestCookieNames"
# operator = "StartsWith"
# selector = ".MyCustom.Cookies" # .NET
# },
# }
# }
# }
# }
}
}
cdn_waf_custom_block_response_status_code = 503
cdn_waf_custom_block_response_body = "<h1>Service unavailable</h1>"
## Azure App Gateway specific configuration
# app_gateway_v2_capacity_units = 1
# app_gateway_v2_frontend_port = 443
# app_gateway_v2_cookie_based_affinity = "Disabled" # or "Enabled"
# app_gateway_v2_tls_disabled_protocols = ["TLSv1_0", "TLSv1_1"]
# app_gateway_v2_identity_ids = []
app_gateway_v2_waf_managed_rulesets = {
"OWASP" = {
version = "3.2",
# overrides = {
# "0000-RULE-GROUP-NAME-0000" = {
# rules = {
# "000001" = {
# enabled = false
# },
# "000002" = {
# enabled = true,
# action = "Log"
# },
# }
# }
# }
},
"Microsoft_BotManagerRuleSet" = {
version = "1.0"
}
}
# app_gateway_v2_waf_managed_rulesets_exclusions = {
# "rcn-sw-cookies" : {
# match_variable = "RequestCookieNames",
# selector = ".MyCustom.Cookies",
# selector_match_operator = "StartsWith"
# excluded_rule_set = {
# "OWASP" = {
# version = "3.2",
# rule_group_name = "0000-RULE-GROUP-NAME-0000",
# excluded_rules = [
# "12345",
# "67890"
# ]
# }
# "Microsoft_BotManagerRuleSet" = {
# version = "1.0",
# rule_group_name = "1111-RULE-GROUP-NAME-1111",
# excluded_rules = [
# "12345",
# ]
# }
# }
# },
# }
## If your App Gateway is expected to sit behind Azure Front Door, then set this to True to only permit inbound traffic from that source
# restrict_app_gateway_v2_to_front_door_inbound_only = true
# restrict_app_gateway_v2_to_front_door_inbound_only_destination_prefixes = [ "*" ]
tags = {
"Environment" = "Dev"
}
}
Name | Version |
---|---|
terraform | >= 1.5.0 |
azuread | >= 2.39.0 |
azurerm | >= 3.51.0 |
Name | Version |
---|---|
azuread | 2.40.0 |
azurerm | 3.66.0 |
Name | Description | Type | Default | Required |
---|---|---|---|---|
app_gateway_v2_capacity_units | App Gateway V2 capacity units | number |
1 |
no |
app_gateway_v2_cookie_based_affinity | App Gateway V2 Cookie Based Affinity. Sets an affinity cookie in the response with a hash value which contains the session details, so that the subsequent requests carrying the affinity cookie will be routed to the same backend server for maintaining stickiness. | string |
"Disabled" |
no |
app_gateway_v2_enable_http2 | App Gateway V2 enable HTTP2 | bool |
true |
no |
app_gateway_v2_frontend_port | App Gateway V2 frontend port | number |
80 |
no |
app_gateway_v2_identity_ids | App Gateway V2 User Assigned identity ids. If empty, one will be created. | list(any) |
[] |
no |
app_gateway_v2_waf_managed_rulesets | Map of all Managed rules you want to apply to the App Gateway WAF, including any overrides | map(object({ |
{ |
no |
app_gateway_v2_waf_managed_rulesets_exclusions | Map of all exlusions and the assoicated Managed rules to apply to the App Gateway WAF | map(object({ |
{} |
no |
azure_location | Azure location in which to launch resources. | string |
n/a | yes |
cdn_add_response_headers | List of response headers to add at the CDN Front Door for all endpoints [{ "Name" = "Strict-Transport-Security", "value" = "max-age=31536000" }] |
list(map(string)) |
[] |
no |
cdn_host_redirects | CDN FrontDoor host redirects [{ "from" = "example.com", "to" = "www.example.com" }] |
list(map(string)) |
[] |
no |
cdn_remove_response_headers | List of response headers to remove at the CDN Front Door for all endpoints | list(string) |
[] |
no |
cdn_sku | Azure CDN Front Door SKU | string |
"Standard_AzureFrontDoor" |
no |
cdn_waf_custom_block_response_body | Base64 encoded custom response body when the WAF blocks a request | string |
"" |
no |
cdn_waf_custom_block_response_status_code | Custom response status code when the WAF blocks a request. | number |
0 |
no |
cdn_waf_enable_rate_limiting | Deploy a Rate Limiting Policy on the Front Door WAF | bool |
false |
no |
cdn_waf_managed_rulesets | Map of all Managed rules you want to apply to the CDN WAF, including any overrides, or exclusions | map(object({ |
{ |
no |
cdn_waf_rate_limiting_action | Action to take when rate limiting (Block/Log) | string |
"Block" |
no |
cdn_waf_rate_limiting_bypass_ip_list | List if IP CIDRs to bypass the Rate Limit Policy | list(string) |
[] |
no |
cdn_waf_rate_limiting_duration_in_minutes | Number of minutes to BLOCK requests that hit the Rate Limit threshold | number |
1 |
no |
cdn_waf_rate_limiting_threshold | Maximum number of concurrent requests before Rate Limiting policy is applied | number |
300 |
no |
enable_latency_monitor | Enable CDN latency monitor | bool |
false |
no |
enable_waf | Enable WAF | bool |
false |
no |
environment | Environment name. Will be used along with project_name as a prefix for all resources. |
string |
n/a | yes |
existing_monitor_action_group_id | ID of an existing monitor action group | string |
"" |
no |
existing_resource_group | Conditionally launch resources into an existing resource group. Specifying this will NOT create a resource group. | string |
"" |
no |
existing_virtual_network | Conditionally use an existing virtual network. The virtual_network_address_space must match an existing address space in the VNet. This also requires the resource group name. |
string |
"" |
no |
key_vault_app_gateway_certificates_access_ipv4 | List of IPv4 Addresses that are permitted to access the App Gateway Certificates Key Vault | list(string) |
[] |
no |
key_vault_app_gateway_certificates_access_subnet_ids | List of Azure Subnet IDs that are permitted to access the App Gateway Certificates Key Vault | list(string) |
[] |
no |
key_vault_app_gateway_certificates_access_users | List of users that require access to the App Gateway Certificates Key Vault. This should be a list of User Principle Names (Found in Active Directory) that need to run terraform | list(string) |
[] |
no |
latency_monitor_threshold | CDN latency monitor threshold in milliseconds | number |
5000 |
no |
project_name | Project name. Will be used along with environment as a prefix for all resources. |
string |
n/a | yes |
response_request_timeout | Azure CDN Front Door response timeout, or app gateway v2 request timeout in seconds | number |
120 |
no |
restrict_app_gateway_v2_to_front_door_inbound_only | Restricts access to the App Gateway V2 by creating a network security group that only allows 'AzureFrontDoor.Backend' inbound, and attaches it to the subnet of the application gateway. | bool |
false |
no |
restrict_app_gateway_v2_to_front_door_inbound_only_destination_prefixes | If app gateway v2 has access restricted to front door only (by enabling restrict_app_gateway_v2_to_front_door_inbound_only ), use this to set the destination prefixes for the security group rule. |
list(string) |
[ |
no |
tags | Tags to be applied to all resources | map(string) |
{} |
no |
virtual_network_address_space | Virtual Network address space CIDR | string |
"172.16.0.0/12" |
no |
waf_application | Which product to apply the WAF to. Must be either CDN or AppGatewayV2 | string |
"CDN" |
no |
waf_custom_rules | Map of all Custom rules you want to apply to the WAF | map(object({ |
{} |
no |
waf_mode | WAF mode | string |
"Prevention" |
no |
waf_targets | Target endpoints to configure the WAF to point towards | map( |
{} |
no |
Name | Description |
---|---|
environment | n/a |