From 56e938658380f556c1dfe8dd7b169b1ab4449fbe Mon Sep 17 00:00:00 2001 From: Imran Nayer Date: Sun, 1 Oct 2023 22:13:57 -0500 Subject: [PATCH] feat(TPG >= 4.79)!: added preconfigured_waf_config block in custom_rule (#71) --- README.md | 2 +- examples/simple-example/main.tf | 19 ++++++++++++++++ main.tf | 40 +++++++++++++++++++++++++++++++++ variables.tf | 22 ++++++++++++++++++ versions.tf | 4 ++-- 5 files changed, 84 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 27f9f5e..f65c3c4 100644 --- a/README.md +++ b/README.md @@ -278,7 +278,7 @@ module "security_policy" { | Name | Description | Type | Default | Required | |------|-------------|------|---------|:--------:| | adaptive\_protection\_auto\_deploy | Configuration for Automatically deploy Cloud Armor Adaptive Protection suggested rules. priority and action fields are required if enable is set to true |
object({
enable = bool
priority = optional(number, null)
action = optional(string, null)
preview = optional(bool, false)
description = optional(string, "Adaptive Protection auto-deploy")
load_threshold = optional(number, 0.1)
confidence_threshold = optional(number, 0.5)
impacted_baseline_threshold = optional(number, 0.01)
expiration_sec = optional(number, 7200)
redirect_type = optional(string)
redirect_target = optional(string)

rate_limit_options = optional(object({
enforce_on_key = optional(string)
enforce_on_key_name = optional(string)

enforce_on_key_configs = optional(list(object({
enforce_on_key_name = optional(string)
enforce_on_key_type = optional(string)
})))

exceed_action = optional(string)
rate_limit_http_request_count = optional(number)
rate_limit_http_request_interval_sec = optional(number)
ban_duration_sec = optional(number)
ban_http_request_count = optional(number)
ban_http_request_interval_sec = optional(number)
}), {})
})
|
{
"enable": false
}
| no | -| custom\_rules | Custome security rules |
map(object({
action = string
priority = number
description = optional(string)
preview = optional(bool, false)
expression = string
redirect_type = optional(string, null)
redirect_target = optional(string, null)
rate_limit_options = optional(object({
enforce_on_key = optional(string)
enforce_on_key_name = optional(string)
enforce_on_key_configs = optional(list(object({
enforce_on_key_name = optional(string)
enforce_on_key_type = optional(string)
})))
exceed_action = optional(string)
rate_limit_http_request_count = optional(number)
rate_limit_http_request_interval_sec = optional(number)
ban_duration_sec = optional(number)
ban_http_request_count = optional(number)
ban_http_request_interval_sec = optional(number)
}),
{})
header_action = optional(list(object({
header_name = optional(string)
header_value = optional(string)
})), [])
}))
| `{}` | no | +| custom\_rules | Custome security rules |
map(object({
action = string
priority = number
description = optional(string)
preview = optional(bool, false)
expression = string
redirect_type = optional(string, null)
redirect_target = optional(string, null)
rate_limit_options = optional(object({
enforce_on_key = optional(string)
enforce_on_key_name = optional(string)
enforce_on_key_configs = optional(list(object({
enforce_on_key_name = optional(string)
enforce_on_key_type = optional(string)
})))
exceed_action = optional(string)
rate_limit_http_request_count = optional(number)
rate_limit_http_request_interval_sec = optional(number)
ban_duration_sec = optional(number)
ban_http_request_count = optional(number)
ban_http_request_interval_sec = optional(number)
}),
{})
header_action = optional(list(object({
header_name = optional(string)
header_value = optional(string)
})), [])

preconfigured_waf_config_exclusion = optional(object({
target_rule_set = string
target_rule_ids = optional(list(string), [])
request_header = optional(list(object({
operator = string
value = optional(string)
})))
request_cookie = optional(list(object({
operator = string
value = optional(string)
})))
request_uri = optional(list(object({
operator = string
value = optional(string)
})))
request_query_param = optional(list(object({
operator = string
value = optional(string)
})))
}), { target_rule_set = null })

}))
| `{}` | no | | default\_rule\_action | default rule that allows/denies all traffic with the lowest priority (2,147,483,647) | `string` | `"allow"` | no | | description | An optional description of this security policy. Max size is 2048. | `string` | `null` | no | | json\_custom\_config\_content\_types | A list of custom Content-Type header values to apply the JSON parsing. Only applicable when json\_parsing is set to STANDARD. Not supported for CLOUD\_ARMOR\_EDGE policy type | `list(string)` | `[]` | no | diff --git a/examples/simple-example/main.tf b/examples/simple-example/main.tf index 4452d6f..29e5789 100644 --- a/examples/simple-example/main.tf +++ b/examples/simple-example/main.tf @@ -285,6 +285,25 @@ module "cloud_armor" { } + "methodenforcement-v33-stable_level_1" = { + action = "deny(403)" + priority = 6 + description = "Method enforcement Level 1" + preview = true + expression = "evaluatePreconfiguredWaf('methodenforcement-v33-stable', {'sensitivity': 1}) && !request.path.matches('/keyword/here/')" + + preconfigured_waf_config_exclusion = { + target_rule_set = "methodenforcement-v33-stable" + target_rule_ids = ["owasp-crs-v030301-id911100-methodenforcement"] + request_uri = [ + { + operator = "CONTAINS" + value = "/keyword/here/" + }, + ] + } + } + } } diff --git a/main.tf b/main.tf index 3aacfc6..6d2d3a1 100644 --- a/main.tf +++ b/main.tf @@ -367,6 +367,46 @@ resource "google_compute_security_policy" "policy" { } } + # Optional preconfigured_waf_config Block if preconfigured_waf_config_exclusion is provided + dynamic "preconfigured_waf_config" { + for_each = rule.value.preconfigured_waf_config_exclusion.target_rule_set == null ? [] : ["preconfigured_waf_config_exclusion"] + content { + exclusion { + target_rule_set = rule.value.preconfigured_waf_config_exclusion.target_rule_set + target_rule_ids = rule.value.preconfigured_waf_config_exclusion.target_rule_ids + dynamic "request_header" { + for_each = rule.value.preconfigured_waf_config_exclusion.request_header == null ? {} : { for x in rule.value.preconfigured_waf_config_exclusion.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 = rule.value.preconfigured_waf_config_exclusion.request_cookie == null ? {} : { for x in rule.value.preconfigured_waf_config_exclusion.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 = rule.value.preconfigured_waf_config_exclusion.request_uri == null ? {} : { for x in rule.value.preconfigured_waf_config_exclusion.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 = rule.value.preconfigured_waf_config_exclusion.request_query_param == null ? {} : { for x in rule.value.preconfigured_waf_config_exclusion.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 + } + } + } + } + } + + } } diff --git a/variables.tf b/variables.tf index af991dd..eb910dd 100644 --- a/variables.tf +++ b/variables.tf @@ -164,6 +164,28 @@ variable "custom_rules" { header_name = optional(string) header_value = optional(string) })), []) + + preconfigured_waf_config_exclusion = optional(object({ + target_rule_set = string + target_rule_ids = optional(list(string), []) + request_header = optional(list(object({ + operator = string + value = optional(string) + }))) + request_cookie = optional(list(object({ + operator = string + value = optional(string) + }))) + request_uri = optional(list(object({ + operator = string + value = optional(string) + }))) + request_query_param = optional(list(object({ + operator = string + value = optional(string) + }))) + }), { target_rule_set = null }) + })) default = {} } diff --git a/versions.tf b/versions.tf index 9e1cbd7..16c87b0 100644 --- a/versions.tf +++ b/versions.tf @@ -19,11 +19,11 @@ terraform { required_providers { google = { source = "hashicorp/google" - version = ">= 4.59.0, < 5.0" + version = ">= 4.79.0, < 5.0" } google-beta = { source = "hashicorp/google-beta" - version = ">= 4.59.0, < 5.0" + version = ">= 4.79.0, < 5.0" } } provider_meta "google" {