main.tf (515 lines of code) (raw):
/**
* Copyright 2023 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
locals {
### find all the preconfigured rule with no include or exclude expression
pre_configured_rules_no_cond_expr = { for name, policy in var.pre_configured_rules : name => {
expression = "evaluatePreconfiguredWaf('${policy["target_rule_set"]}', {'sensitivity': ${policy["sensitivity_level"]}})"
} if length(policy["include_target_rule_ids"]) == 0 && length(policy["exclude_target_rule_ids"]) == 0
}
### find all the preconfigured rule with include (Opt In rules) expression
pre_configured_rules_include = { for name, policy in var.pre_configured_rules : name => {
target_rule_set = policy.target_rule_set
include_target_rule_ids = replace(join(",", policy.include_target_rule_ids), ",", "','")
sensitivity_level = policy.sensitivity_level
action = policy.action
priority = 0
description = policy.description
preview = policy.preview
redirect_type = policy.redirect_type
redirect_target = policy.redirect_target
rate_limit_options = policy.rate_limit_options
} if length(policy["include_target_rule_ids"]) > 0
}
pre_configured_rules_include_expr = { for name, policy in local.pre_configured_rules_include : name => {
expression = "evaluatePreconfiguredWaf('${policy["target_rule_set"]}', {'sensitivity': 0, 'opt_in_rule_ids': ['${policy.include_target_rule_ids}']})"
}
}
### find all the preconfigured rule with Exclude (Opt out rules) expression
pre_configured_rules_exclude = { for name, policy in var.pre_configured_rules : name => {
target_rule_set = policy.target_rule_set
exclude_target_rule_ids = replace(join(",", policy.exclude_target_rule_ids), ",", "','")
sensitivity_level = policy.sensitivity_level
action = policy.action
priority = policy.priority
description = policy.description
preview = policy.preview
redirect_type = policy.redirect_type
redirect_target = policy.redirect_target
rate_limit_options = policy.rate_limit_options
} if length(policy["include_target_rule_ids"]) == 0 && length(policy["exclude_target_rule_ids"]) > 0
}
pre_configured_rules_exclude_expr = { for name, policy in local.pre_configured_rules_exclude : name => {
expression = "evaluatePreconfiguredWaf('${policy["target_rule_set"]}', {'sensitivity': ${policy.sensitivity_level}, 'opt_out_rule_ids': ['${policy.exclude_target_rule_ids}']})"
}
}
## Combine all the preconfigured rules
pre_configured_rules_expr = merge(local.pre_configured_rules_no_cond_expr, local.pre_configured_rules_include_expr, local.pre_configured_rules_exclude_expr)
}
resource "google_compute_security_policy" "policy" {
provider = google-beta
name = var.name
description = var.description
project = var.project_id
type = var.type
dynamic "recaptcha_options_config" {
for_each = var.recaptcha_redirect_site_key == null ? [] : ["redirect_site_key"]
content {
redirect_site_key = var.recaptcha_redirect_site_key
}
}
# Advanced options for Cloud Armor are currently only supported for security policies with CLOUD_ARMOR type
dynamic "advanced_options_config" {
for_each = var.type == "CLOUD_ARMOR" ? ["CLOUD_ARMOR"] : []
content {
json_parsing = var.json_parsing
log_level = var.log_level
user_ip_request_headers = var.user_ip_request_headers
dynamic "json_custom_config" {
for_each = var.json_parsing == "STANDARD" && length(var.json_custom_config_content_types) > 0 ? ["json_custom_config"] : []
content {
content_types = var.json_custom_config_content_types
}
}
}
}
##### Preconfigured WAF Rules
dynamic "rule" {
for_each = var.pre_configured_rules
content {
action = rule.value["action"]
priority = rule.value["priority"]
preview = rule.value["preview"]
description = rule.value["description"]
match {
expr {
expression = local.pre_configured_rules_expr[rule.key].expression
}
}
# Header Action Block. Only if header_action is provided
dynamic "header_action" {
for_each = length(rule.value["header_action"]) == 0 ? [] : ["header_action"]
content {
dynamic "request_headers_to_adds" {
for_each = { for x in rule.value["header_action"] : x.header_name => x }
content {
header_name = request_headers_to_adds.value.header_name
header_value = request_headers_to_adds.value.header_value
}
}
}
}
### Redirect option
dynamic "redirect_options" {
for_each = rule.value["action"] == "redirect" ? ["redirect"] : []
content {
type = rule.value["redirect_type"]
target = rule.value["redirect_type"] == "EXTERNAL_302" ? rule.value["redirect_target"] : null
}
}
### Rate limit. Execute only if Action is "rate_based_ban" or "throttle"
dynamic "rate_limit_options" {
for_each = rule.value["action"] == "rate_based_ban" || rule.value["action"] == "throttle" ? ["rate_limits"] : []
content {
conform_action = "allow"
ban_duration_sec = rule.value["action"] == "rate_based_ban" ? lookup(rule.value["rate_limit_options"], "ban_duration_sec") : null
exceed_action = lookup(rule.value["rate_limit_options"], "exceed_action")
enforce_on_key = lookup(rule.value["rate_limit_options"], "enforce_on_key_configs") == null ? lookup(rule.value["rate_limit_options"], "enforce_on_key", null) : ""
enforce_on_key_name = lookup(rule.value["rate_limit_options"], "enforce_on_key_configs") == null ? lookup(rule.value["rate_limit_options"], "enforce_on_key_name", null) : null
dynamic "enforce_on_key_configs" {
for_each = lookup(rule.value["rate_limit_options"], "enforce_on_key_configs") == null ? {} : { for x in lookup(rule.value["rate_limit_options"], "enforce_on_key_configs") : x.enforce_on_key_type => x }
content {
enforce_on_key_type = enforce_on_key_configs.value.enforce_on_key_type
enforce_on_key_name = enforce_on_key_configs.value.enforce_on_key_name
}
}
## Required for all rate limit options
dynamic "rate_limit_threshold" {
for_each = rule.value["action"] == "rate_based_ban" || rule.value["action"] == "throttle" ? ["rate_limit_options"] : []
content {
count = rule.value["rate_limit_options"].rate_limit_http_request_count
interval_sec = rule.value["rate_limit_options"].rate_limit_http_request_interval_sec
}
}
## Optional. Can be provided for for rate based ban. Not needed for throttle
dynamic "ban_threshold" {
for_each = rule.value["action"] == "rate_based_ban" && lookup(rule.value["rate_limit_options"], "ban_http_request_count", null) != null && lookup(rule.value["rate_limit_options"], "ban_http_request_interval_sec", null) != null ? ["ban_threshold"] : []
content {
count = lookup(rule.value["rate_limit_options"], "ban_http_request_count")
interval_sec = lookup(rule.value["rate_limit_options"], "ban_http_request_interval_sec")
}
}
}
}
# Optional preconfigured_waf_config Block if preconfigured_waf_config_exclusion is provided
dynamic "preconfigured_waf_config" {
for_each = rule.value.preconfigured_waf_config_exclusions == null ? [] : ["preconfigured_waf_config_exclusions"] #rule.value.preconfigured_waf_config_exclusions
content {
dynamic "exclusion" {
for_each = rule.value.preconfigured_waf_config_exclusions
content {
target_rule_set = exclusion.value.target_rule_set
target_rule_ids = exclusion.value.target_rule_ids
dynamic "request_header" {
for_each = exclusion.value.request_header == null ? {} : { for x in exclusion.value.request_header : "${x.operator}-${base64encode(coalesce(x.value, "test"))}" => x }
content {
operator = request_header.value.operator
value = request_header.value.operator == "EQUALS_ANY" ? null : request_header.value.value
}
}
dynamic "request_cookie" {
for_each = exclusion.value.request_cookie == null ? {} : { for x in exclusion.value.request_cookie : "${x.operator}-${base64encode(coalesce(x.value, "test"))}" => x }
content {
operator = request_cookie.value.operator
value = request_cookie.value.operator == "EQUALS_ANY" ? null : request_cookie.value.value
}
}
dynamic "request_uri" {
for_each = exclusion.value.request_uri == null ? {} : { for x in exclusion.value.request_uri : "${x.operator}-${base64encode(coalesce(x.value, "test"))}" => x }
content {
operator = request_uri.value.operator
value = request_uri.value.operator == "EQUALS_ANY" ? null : request_uri.value.value
}
}
dynamic "request_query_param" {
for_each = exclusion.value.request_query_param == null ? {} : { for x in exclusion.value.request_query_param : "${x.operator}-${base64encode(coalesce(x.value, "test"))}" => x }
content {
operator = request_query_param.value.operator
value = request_query_param.value.operator == "EQUALS_ANY" ? null : request_query_param.value.value
}
}
}
}
}
}
}
}
##### Security Rules IP
dynamic "rule" {
for_each = var.security_rules
content {
action = rule.value["action"]
priority = rule.value["priority"]
preview = rule.value["preview"]
description = rule.value["description"]
match {
versioned_expr = "SRC_IPS_V1"
config {
src_ip_ranges = rule.value["src_ip_ranges"]
}
}
# Header Action Block. Only if header_action is provided
dynamic "header_action" {
for_each = length(rule.value["header_action"]) == 0 ? [] : ["header_action"]
content {
dynamic "request_headers_to_adds" {
for_each = { for x in rule.value["header_action"] : x.header_name => x }
content {
header_name = request_headers_to_adds.value.header_name
header_value = request_headers_to_adds.value.header_value
}
}
}
}
### Redirect option. Execute only if Action is "redirect"
dynamic "redirect_options" {
for_each = rule.value["action"] == "redirect" ? ["redirect"] : []
content {
type = rule.value["redirect_type"]
target = rule.value["redirect_type"] == "EXTERNAL_302" ? rule.value["redirect_target"] : null
}
}
### Rate limit. Execute only if Action is "rate_based_ban" or "throttle"
dynamic "rate_limit_options" {
for_each = rule.value["action"] == "rate_based_ban" || rule.value["action"] == "throttle" ? ["rate_limits"] : []
content {
conform_action = "allow"
ban_duration_sec = rule.value["action"] == "rate_based_ban" ? lookup(rule.value["rate_limit_options"], "ban_duration_sec") : null
exceed_action = lookup(rule.value["rate_limit_options"], "exceed_action")
enforce_on_key = lookup(rule.value["rate_limit_options"], "enforce_on_key_configs") == null ? lookup(rule.value["rate_limit_options"], "enforce_on_key", null) : ""
enforce_on_key_name = lookup(rule.value["rate_limit_options"], "enforce_on_key_configs") == null ? lookup(rule.value["rate_limit_options"], "enforce_on_key_name", null) : null
dynamic "enforce_on_key_configs" {
for_each = lookup(rule.value["rate_limit_options"], "enforce_on_key_configs") == null ? {} : { for x in lookup(rule.value["rate_limit_options"], "enforce_on_key_configs") : x.enforce_on_key_type => x }
content {
enforce_on_key_type = enforce_on_key_configs.value.enforce_on_key_type
enforce_on_key_name = enforce_on_key_configs.value.enforce_on_key_name
}
}
## Required for all rate limit options
dynamic "rate_limit_threshold" {
for_each = rule.value["action"] == "rate_based_ban" || rule.value["action"] == "throttle" ? ["rate_limit_options"] : []
content {
count = rule.value["rate_limit_options"].rate_limit_http_request_count
interval_sec = rule.value["rate_limit_options"].rate_limit_http_request_interval_sec
}
}
## Optional. Can be provided for for rate based ban. Not needed for throttle
dynamic "ban_threshold" {
for_each = rule.value["action"] == "rate_based_ban" && lookup(rule.value["rate_limit_options"], "ban_http_request_count", null) != null && lookup(rule.value["rate_limit_options"], "ban_http_request_interval_sec", null) != null ? ["ban_threshold"] : []
content {
count = lookup(rule.value["rate_limit_options"], "ban_http_request_count")
interval_sec = lookup(rule.value["rate_limit_options"], "ban_http_request_interval_sec")
}
}
}
}
}
}
##### Custom Rules
dynamic "rule" {
for_each = var.custom_rules
content {
action = rule.value["action"]
priority = rule.value["priority"]
preview = rule.value["preview"]
description = rule.value["description"]
match {
expr {
expression = rule.value["expression"]
}
}
# Header Action Block. Only if header_action is provided
dynamic "header_action" {
for_each = length(rule.value["header_action"]) == 0 ? [] : ["header_action"]
content {
dynamic "request_headers_to_adds" {
for_each = { for x in rule.value["header_action"] : x.header_name => x }
content {
header_name = request_headers_to_adds.value.header_name
header_value = request_headers_to_adds.value.header_value
}
}
}
}
# Redirect option block
dynamic "redirect_options" {
for_each = rule.value["action"] == "redirect" ? ["redirect"] : []
content {
type = rule.value["redirect_type"]
target = rule.value["redirect_type"] == "EXTERNAL_302" ? rule.value["redirect_target"] : null
}
}
### Rate limit. Execute only if Action is "rate_based_ban" or "throttle"
dynamic "rate_limit_options" {
for_each = rule.value["action"] == "rate_based_ban" || rule.value["action"] == "throttle" ? ["rate_limits"] : []
content {
conform_action = "allow"
ban_duration_sec = rule.value["action"] == "rate_based_ban" ? lookup(rule.value["rate_limit_options"], "ban_duration_sec") : null
exceed_action = lookup(rule.value["rate_limit_options"], "exceed_action")
enforce_on_key = lookup(rule.value["rate_limit_options"], "enforce_on_key_configs") == null ? lookup(rule.value["rate_limit_options"], "enforce_on_key", null) : ""
enforce_on_key_name = lookup(rule.value["rate_limit_options"], "enforce_on_key_configs") == null ? lookup(rule.value["rate_limit_options"], "enforce_on_key_name", null) : null
dynamic "enforce_on_key_configs" {
for_each = lookup(rule.value["rate_limit_options"], "enforce_on_key_configs") == null ? {} : { for x in lookup(rule.value["rate_limit_options"], "enforce_on_key_configs") : x.enforce_on_key_type => x }
content {
enforce_on_key_type = enforce_on_key_configs.value.enforce_on_key_type
enforce_on_key_name = enforce_on_key_configs.value.enforce_on_key_name
}
}
## Required for all rate limit options
dynamic "rate_limit_threshold" {
for_each = rule.value["action"] == "rate_based_ban" || rule.value["action"] == "throttle" ? ["rate_limit_options"] : []
content {
count = rule.value["rate_limit_options"].rate_limit_http_request_count
interval_sec = rule.value["rate_limit_options"].rate_limit_http_request_interval_sec
}
}
## Optional. Can be provided for for rate based ban. Not needed for throttle
dynamic "ban_threshold" {
for_each = rule.value["action"] == "rate_based_ban" && lookup(rule.value["rate_limit_options"], "ban_http_request_count", null) != null && lookup(rule.value["rate_limit_options"], "ban_http_request_interval_sec", null) != null ? ["ban_threshold"] : []
content {
count = lookup(rule.value["rate_limit_options"], "ban_http_request_count")
interval_sec = lookup(rule.value["rate_limit_options"], "ban_http_request_interval_sec")
}
}
}
}
# Optional preconfigured_waf_config Block if preconfigured_waf_config_exclusion is provided
dynamic "preconfigured_waf_config" {
for_each = rule.value.preconfigured_waf_config_exclusions == null ? [] : ["preconfigured_waf_config_exclusions"] #rule.value.preconfigured_waf_config_exclusions
content {
dynamic "exclusion" {
for_each = rule.value.preconfigured_waf_config_exclusions
content {
target_rule_set = exclusion.value.target_rule_set
target_rule_ids = exclusion.value.target_rule_ids
dynamic "request_header" {
for_each = exclusion.value.request_header == null ? {} : { for x in exclusion.value.request_header : "${x.operator}-${base64encode(coalesce(x.value, "test"))}" => x }
content {
operator = request_header.value.operator
value = request_header.value.operator == "EQUALS_ANY" ? null : request_header.value.value
}
}
dynamic "request_cookie" {
for_each = exclusion.value.request_cookie == null ? {} : { for x in exclusion.value.request_cookie : "${x.operator}-${base64encode(coalesce(x.value, "test"))}" => x }
content {
operator = request_cookie.value.operator
value = request_cookie.value.operator == "EQUALS_ANY" ? null : request_cookie.value.value
}
}
dynamic "request_uri" {
for_each = exclusion.value.request_uri == null ? {} : { for x in exclusion.value.request_uri : "${x.operator}-${base64encode(coalesce(x.value, "test"))}" => x }
content {
operator = request_uri.value.operator
value = request_uri.value.operator == "EQUALS_ANY" ? null : request_uri.value.value
}
}
dynamic "request_query_param" {
for_each = exclusion.value.request_query_param == null ? {} : { for x in exclusion.value.request_query_param : "${x.operator}-${base64encode(coalesce(x.value, "test"))}" => x }
content {
operator = request_query_param.value.operator
value = request_query_param.value.operator == "EQUALS_ANY" ? null : request_query_param.value.value
}
}
}
}
}
}
}
}
##### Threat Intelligence Rules
dynamic "rule" {
for_each = var.threat_intelligence_rules
content {
action = rule.value["action"]
priority = rule.value["priority"]
preview = rule.value["preview"]
description = rule.value["description"]
match {
expr {
expression = lookup(rule.value, "exclude_ip", null) == null ? "evaluateThreatIntelligence('${rule.value["feed"]}')" : "evaluateThreatIntelligence('${rule.value["feed"]}', ${rule.value["exclude_ip"]})"
}
}
# Header Action Block. Only if header_action is provided
dynamic "header_action" {
for_each = length(rule.value["header_action"]) == 0 ? [] : ["header_action"]
content {
dynamic "request_headers_to_adds" {
for_each = { for x in rule.value["header_action"] : x.header_name => x }
content {
header_name = request_headers_to_adds.value.header_name
header_value = request_headers_to_adds.value.header_value
}
}
}
}
### Rate limit. Execute only if Action is "rate_based_ban" or "throttle"
dynamic "rate_limit_options" {
for_each = rule.value["action"] == "rate_based_ban" || rule.value["action"] == "throttle" ? ["rate_limits"] : []
content {
conform_action = "allow"
ban_duration_sec = rule.value["action"] == "rate_based_ban" ? lookup(rule.value["rate_limit_options"], "ban_duration_sec") : null
exceed_action = lookup(rule.value["rate_limit_options"], "exceed_action")
enforce_on_key = lookup(rule.value["rate_limit_options"], "enforce_on_key_configs") == null ? lookup(rule.value["rate_limit_options"], "enforce_on_key", null) : null
enforce_on_key_name = lookup(rule.value["rate_limit_options"], "enforce_on_key_configs") == null ? lookup(rule.value["rate_limit_options"], "enforce_on_key_name", null) : null
dynamic "enforce_on_key_configs" {
for_each = lookup(rule.value["rate_limit_options"], "enforce_on_key_configs") == null ? {} : { for x in lookup(rule.value["rate_limit_options"], "enforce_on_key_configs") : x.enforce_on_key_type => x }
content {
enforce_on_key_type = enforce_on_key_configs.value.enforce_on_key_type
enforce_on_key_name = enforce_on_key_configs.value.enforce_on_key_name
}
}
## Required for all rate limit options
dynamic "rate_limit_threshold" {
for_each = rule.value["action"] == "rate_based_ban" || rule.value["action"] == "throttle" ? ["rate_limit_options"] : []
content {
count = rule.value["rate_limit_options"].rate_limit_http_request_count
interval_sec = rule.value["rate_limit_options"].rate_limit_http_request_interval_sec
}
}
## Optional. Can be provided for for rate based ban. Not needed for throttle
dynamic "ban_threshold" {
for_each = rule.value["action"] == "rate_based_ban" && lookup(rule.value["rate_limit_options"], "ban_http_request_count", null) != null && lookup(rule.value["rate_limit_options"], "ban_http_request_interval_sec", null) != null ? ["ban_threshold"] : []
content {
count = lookup(rule.value["rate_limit_options"], "ban_http_request_count")
interval_sec = lookup(rule.value["rate_limit_options"], "ban_http_request_interval_sec")
}
}
}
}
}
}
##### Default Rule
rule {
action = var.default_rule_action
priority = "2147483647"
description = "Default rule, higher priority overrides it"
match {
versioned_expr = "SRC_IPS_V1"
config {
src_ip_ranges = ["*"]
}
}
}
# Cloud Armor Adaptive Protection is currently not supported for edge or network policies
dynamic "adaptive_protection_config" {
for_each = var.layer_7_ddos_defense_enable && var.type != "CLOUD_ARMOR_EDGE" ? ["adaptive_protection_config"] : []
content {
layer_7_ddos_defense_config {
enable = var.layer_7_ddos_defense_enable
rule_visibility = var.layer_7_ddos_defense_rule_visibility
dynamic "threshold_configs" {
for_each = var.layer_7_ddos_defense_threshold_configs == null ? {} : { for x in var.layer_7_ddos_defense_threshold_configs : x.name => x }
content {
name = threshold_configs.value["name"]
auto_deploy_load_threshold = threshold_configs.value["auto_deploy_load_threshold"]
auto_deploy_confidence_threshold = threshold_configs.value["auto_deploy_confidence_threshold"]
auto_deploy_impacted_baseline_threshold = threshold_configs.value["auto_deploy_impacted_baseline_threshold"]
auto_deploy_expiration_sec = threshold_configs.value["auto_deploy_expiration_sec"]
detection_load_threshold = threshold_configs.value["detection_load_threshold"]
detection_absolute_qps = threshold_configs.value["detection_absolute_qps"]
detection_relative_to_baseline_qps = threshold_configs.value["detection_relative_to_baseline_qps"]
dynamic "traffic_granularity_configs" {
for_each = threshold_configs.value["traffic_granularity_configs"] == null ? {} : { for x in threshold_configs.value["traffic_granularity_configs"] : x.type => x }
content {
type = traffic_granularity_configs.value["type"]
value = traffic_granularity_configs.value["value"]
enable_each_unique_value = traffic_granularity_configs.value["enable_each_unique_value"]
}
}
}
}
}
dynamic "auto_deploy_config" {
for_each = var.adaptive_protection_auto_deploy.enable && (var.adaptive_protection_auto_deploy.load_threshold != null || var.adaptive_protection_auto_deploy.confidence_threshold != null || var.adaptive_protection_auto_deploy.impacted_baseline_threshold != null || var.adaptive_protection_auto_deploy.expiration_sec != null) ? { auto_deploy = var.adaptive_protection_auto_deploy } : {}
content {
load_threshold = auto_deploy_config.value["load_threshold"]
confidence_threshold = auto_deploy_config.value["confidence_threshold"]
impacted_baseline_threshold = auto_deploy_config.value["impacted_baseline_threshold"]
expiration_sec = auto_deploy_config.value["expiration_sec"]
}
}
}
}
##### Automatic Adaptive protection rule deploy
dynamic "rule" {
for_each = var.layer_7_ddos_defense_enable && var.adaptive_protection_auto_deploy.enable && var.type != "CLOUD_ARMOR_EDGE" ? { auto_deploy = var.adaptive_protection_auto_deploy } : {}
content {
action = rule.value["action"]
priority = rule.value["priority"]
preview = rule.value["preview"]
description = rule.value["description"]
match {
expr {
expression = "evaluateAdaptiveProtectionAutoDeploy()"
}
}
# Redirect option block
dynamic "redirect_options" {
for_each = rule.value["action"] == "redirect" ? ["redirect"] : []
content {
type = rule.value["redirect_type"]
target = rule.value["redirect_type"] == "EXTERNAL_302" ? rule.value["redirect_target"] : null
}
}
### Rate limit. Execute only if Action is "rate_based_ban" or "throttle"
dynamic "rate_limit_options" {
for_each = rule.value["action"] == "rate_based_ban" || rule.value["action"] == "throttle" ? ["rate_limits"] : []
content {
conform_action = "allow"
ban_duration_sec = rule.value["action"] == "rate_based_ban" ? lookup(rule.value["rate_limit_options"], "ban_duration_sec") : null
exceed_action = lookup(rule.value["rate_limit_options"], "exceed_action")
enforce_on_key = lookup(rule.value["rate_limit_options"], "enforce_on_key_configs") == null ? lookup(rule.value["rate_limit_options"], "enforce_on_key", null) : ""
enforce_on_key_name = lookup(rule.value["rate_limit_options"], "enforce_on_key_configs") == null ? lookup(rule.value["rate_limit_options"], "enforce_on_key_name", null) : null
dynamic "enforce_on_key_configs" {
for_each = lookup(rule.value["rate_limit_options"], "enforce_on_key_configs") == null ? {} : { for x in lookup(rule.value["rate_limit_options"], "enforce_on_key_configs") : x.enforce_on_key_type => x }
content {
enforce_on_key_type = enforce_on_key_configs.value.enforce_on_key_type
enforce_on_key_name = enforce_on_key_configs.value.enforce_on_key_name
}
}
## Required for all rate limit options
dynamic "rate_limit_threshold" {
for_each = rule.value["action"] == "rate_based_ban" || rule.value["action"] == "throttle" ? ["rate_limit_options"] : []
content {
count = rule.value["rate_limit_options"].rate_limit_http_request_count
interval_sec = rule.value["rate_limit_options"].rate_limit_http_request_interval_sec
}
}
## Optional. Can be provided for for rate based ban. Not needed for throttle
dynamic "ban_threshold" {
for_each = rule.value["action"] == "rate_based_ban" && lookup(rule.value["rate_limit_options"], "ban_http_request_count", null) != null && lookup(rule.value["rate_limit_options"], "ban_http_request_interval_sec", null) != null ? ["ban_threshold"] : []
content {
count = lookup(rule.value["rate_limit_options"], "ban_http_request_count")
interval_sec = lookup(rule.value["rate_limit_options"], "ban_http_request_interval_sec")
}
}
}
}
}
}
}