{"id":15221786,"url":"https://github.com/googlecloudplatform/terraform-google-cloud-armor","last_synced_at":"2025-04-09T16:05:32.504Z","repository":{"id":66041351,"uuid":"583464316","full_name":"GoogleCloudPlatform/terraform-google-cloud-armor","owner":"GoogleCloudPlatform","description":"Deploy Cloud Armor security policy","archived":false,"fork":false,"pushed_at":"2025-03-13T01:59:05.000Z","size":375,"stargazers_count":41,"open_issues_count":9,"forks_count":32,"subscribers_count":33,"default_branch":"main","last_synced_at":"2025-04-09T16:05:22.279Z","etag":null,"topics":["cft-terraform","compute","networking"],"latest_commit_sha":null,"homepage":"https://registry.terraform.io/modules/GoogleCloudPlatform/cloud-armor/google","language":"HCL","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/GoogleCloudPlatform.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":"CODEOWNERS","security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2022-12-29T21:28:17.000Z","updated_at":"2025-04-01T18:41:33.000Z","dependencies_parsed_at":"2024-01-14T06:53:10.979Z","dependency_job_id":"81577f56-10f8-47b7-9cec-d00eeaf30436","html_url":"https://github.com/GoogleCloudPlatform/terraform-google-cloud-armor","commit_stats":{"total_commits":98,"total_committers":11,"mean_commits":8.909090909090908,"dds":0.7551020408163265,"last_synced_commit":"c2b72f1dc2aa38764dfbffd09d16d6cf41f0ae2a"},"previous_names":[],"tags_count":12,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/GoogleCloudPlatform%2Fterraform-google-cloud-armor","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/GoogleCloudPlatform%2Fterraform-google-cloud-armor/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/GoogleCloudPlatform%2Fterraform-google-cloud-armor/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/GoogleCloudPlatform%2Fterraform-google-cloud-armor/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/GoogleCloudPlatform","download_url":"https://codeload.github.com/GoogleCloudPlatform/terraform-google-cloud-armor/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248065288,"owners_count":21041871,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["cft-terraform","compute","networking"],"created_at":"2024-09-28T15:07:32.911Z","updated_at":"2025-04-09T16:05:32.487Z","avatar_url":"https://github.com/GoogleCloudPlatform.png","language":"HCL","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Cloud Armor Terraform Module\nThis module makes it easy to setup [Cloud Armor Global Backend Security Policy](https://cloud.google.com/armor/docs/security-policy-overview#expandable-1) with Security rules. You can attach the global Security policy to the backend services exposed by the following load balancer types:\n- Global external Application Load Balancer (HTTP/HTTPS)\n- Classic Application Load Balancer (HTTP/HTTPS)\n- Global external proxy Network Load Balancer (TCP/SSL)\n- Classic proxy Network Load Balancer (TCP/SSL)\n\nThere are `five` type of rules you can create in each policy:\n1) [Pre-Configured Rules](#pre_configured_rules): These are based on [pre-configured waf rules](https://cloud.google.com/armor/docs/waf-rules).\n2) [Security Rules](#security_rules): Allow or Deny traffic from list of IP addresses or IP address ranges.\n3) [Custom Rules](#custom_rules): You can create your own rules using [Common Expression Language (CEL)](https://cloud.google.com/armor/docs/rules-language-reference).\n4) [Threat Intelligence Rules](#threat_intelligence_rules): Add Rules based on [threat intelligence](https://cloud.google.com/armor/docs/threat-intelligence). [Managed protection plus](https://cloud.google.com/armor/docs/managed-protection-overview) subscription is needed to use this feature.\n5) [Automatically deploy Adaptive Protection Suggested Rules](#adaptive_protection_auto_deploy); When enable module will create a rule for automatically deploying the suggested rules that [Adaptive Protection generates](https://cloud.google.com/armor/docs/adaptive-protection-auto-deploy).\n\n**NOTE:** For `external passthrough Network Load Balancers`, `protocol forwarding` and `VMs with public IP addresses` create [network Edge Security policy](https://cloud.google.com/armor/docs/security-policy-overview#network-edge-policies) using [advanced network DDoS protection](./modules/advanced-network-ddos-protection/) and [network edge security policy](./modules/network-edge-security-policy/) sub-modules.\n\n**NOTE:** For `Regional external Application Load Balancer` and `Regional internal Application Load Balancer` create [Regionl Backend Security policy](https://cloud.google.com/armor/docs/security-policy-overview#expandable-2) using [regional backend serity policy sub-module](./modules/regional-backend-security-policy/).\n\n## Compatibility\n\nThis module is meant for use with Terraform 1.3+ and tested using Terraform 1.3+. If you find incompatibilities using Terraform \u003e=1.3, please open an issue.\n\n## Version\n\nCurrent version is 2.X. Upgrade guides:\n\n- [0.X -\u003e 1.0.](/docs/upgrading_to_v1.0.md)\n- [1.X -\u003e 2.0.](/docs/upgrading_to_v2.0.md)\n- [2.X -\u003e 2.1.](/docs/upgrading_to_v2.1.md)\n- [2.X -\u003e 3.X.](/docs/upgrading_to_v3.0.md)\n\n##  Module Format\n\n```\nmodule security_policy {\n  source = \"GoogleCloudPlatform/cloud-armor/google\"\n\n  project_id                           = \"my-project-id\"\n  name                                 = \"my-test-ca-policy\"\n  description                          = \"Test Cloud Armor security policy with preconfigured rules, security rules and custom rules\"\n  default_rule_action                  = \"deny(403)\"\n  type                                 = \"CLOUD_ARMOR\"\n  layer_7_ddos_defense_enable          = true\n  layer_7_ddos_defense_rule_visibility = \"STANDARD\"\n  recaptcha_redirect_site_key          = google_recaptcha_enterprise_key.primary.name\n  json_parsing                         = \"STANDARD\"\n  log_level                            = \"VERBOSE\"\n\n  pre_configured_rules                 = {}\n  security_rules                       = {}\n  custom_rules                         = {}\n  threat_intelligence_rules            = {}\n  adaptive_protection_auto_deploy      = {}\n}\n```\n\nRule details and Sample Code for each type of rule is available [here](#Rules)\n\n## Usage\nThere are examples included in the [examples](https://github.com/GoogleCloudPlatform/terraform-google-cloud-armor/tree/main/examples) folder but simple usage is as follows:\n\n```\nmodule \"security_policy\" {\n  source   = \"GoogleCloudPlatform/cloud-armor/google\"\n  version  = \"~\u003e 5.0\"\n\n  project_id                           = var.project_id\n  name                                 = \"my-test-security-policy\"\n  description                          = \"Test Security Policy\"\n  recaptcha_redirect_site_key          = google_recaptcha_enterprise_key.primary.name\n  default_rule_action                  = \"allow\"\n  type                                 = \"CLOUD_ARMOR\"\n  layer_7_ddos_defense_enable          = true\n  layer_7_ddos_defense_rule_visibility = \"STANDARD\"\n\n  # Pre-configured WAF Rules\n\n  pre_configured_rules = {\n\n    \"sqli_sensitivity_level_4\" = {\n      action          = \"deny(502)\"\n      priority        = 1\n      target_rule_set = \"sqli-v33-stable\"\n\n      sensitivity_level = 4\n      description       = \"sqli-v33-stable Sensitivity Level 4 and 2 preconfigured_waf_config_exclusions\"\n    }\n\n    \"xss-stable_level_2_with_exclude\" = {\n      action                  = \"deny(502)\"\n      priority                = 2\n      description             = \"XSS Sensitivity Level 2 with excluded rules\"\n      preview                 = true\n      target_rule_set         = \"xss-v33-stable\"\n      sensitivity_level       = 2\n      exclude_target_rule_ids = [\"owasp-crs-v030301-id941380-xss\", \"owasp-crs-v030301-id941280-xss\"]\n    }\n\n    \"php-stable_level_0_with_include\" = {\n      action                  = \"deny(502)\"\n      priority                = 3\n      description             = \"PHP Sensitivity Level 0 with included rules\"\n      target_rule_set         = \"php-v33-stable\"\n      include_target_rule_ids = [\"owasp-crs-v030301-id933190-php\", \"owasp-crs-v030301-id933111-php\"]\n    }\n\n  }\n\n  # Action against specific IP addresses or IP adress ranges\n\n  security_rules = {\n\n    \"deny_project_bad_actor1\" = {\n      action        = \"deny(502)\"\n      priority      = 11\n      description   = \"Deny Malicious IP address from project bad_actor1\"\n      src_ip_ranges = [\"190.217.68.211/32\", \"45.116.227.68/32\", \"103.43.141.122\", \"123.11.215.36\", \"123.11.215.37\", ]\n      preview       = true\n    }\n\n    \"rate_ban_project_actor3\" = {\n      action        = \"rate_based_ban\"\n      priority      = 14\n      description   = \"Rate based ban for address from project actor3 only if they cross banned threshold\"\n      src_ip_ranges = [\"190.217.68.213\", \"45.116.227.70\", ]\n      rate_limit_options = {\n        exceed_action                        = \"deny(502)\"\n        rate_limit_http_request_count        = 10\n        rate_limit_http_request_interval_sec = 60\n        ban_duration_sec                     = 600\n        ban_http_request_count               = 1000\n        ban_http_request_interval_sec        = 300\n        enforce_on_key                       = \"ALL\"\n      }\n    }\n  }\n\n  # Custom Rules using CEL\n\n  custom_rules = {\n\n    deny_specific_regions = {\n      action      = \"deny(502)\"\n      priority    = 21\n      description = \"Deny specific Regions\"\n      expression  = \u003c\u003c-EOT\n        '[AU,BE]'.contains(origin.region_code)\n      EOT\n    }\n\n    deny_specific_ip = {\n      action      = \"deny(502)\"\n      priority    = 22\n      description = \"Deny specific IP address in US Region\"\n      expression  = \u003c\u003c-EOT\n        origin.region_code == \"US\" \u0026\u0026 inIpRange(origin.ip, '47.185.201.159/32')\n      EOT\n    }\n\n    allow_path_token_header = {\n      action      = \"allow\"\n      priority    = 25\n      description = \"Allow path and token match with addition of header\"\n\n      expression = \u003c\u003c-EOT\n        request.path.matches('/login.html') \u0026\u0026 token.recaptcha_session.score \u003c 0.2\n      EOT\n\n      header_action = [\n        {\n          header_name  = \"reCAPTCHA-Warning\"\n          header_value = \"high\"\n        },\n        {\n          header_name  = \"X-Resource\"\n          header_value = \"test\"\n        }\n      ]\n\n    }\n  }\n\n  # Threat Intelligence Rules\n\n  threat_intelligence_rules = {\n\n    deny_malicious_ips = {\n      action      = \"deny(502)\"\n      priority    = 200\n      description = \"Deny IP addresses known to attack web applications\"\n      preview     = false\n      feed        = \"iplist-known-malicious-ips\"\n      exclude_ip  = \"['47.100.100.100', '47.189.12.139']\"\n    }\n  }\n\n}\n\nresource \"google_compute_backend_service\" \"backend_service\" {\n  provider = google-beta\n\n  ## Attach Cloud Armor policy to the backend service\n  security_policy = module.cloud_armor.policy.self_link\n\n  project = var.project_id\n\n  name        = \"glb-ca-web-backend-svc-a\"\n  port_name   = \"http\"\n  protocol    = \"HTTP\"\n  timeout_sec = 10\n\n  backend {\n    group           = google_compute_instance_group.ca_vm_1_ig.self_link\n    max_utilization = 0.5\n  }\n\n  health_checks         = [google_compute_http_health_check.default.id]\n  load_balancing_scheme = \"EXTERNAL\"\n}\n\n```\n\n\n\u003c!-- BEGINNING OF PRE-COMMIT-TERRAFORM DOCS HOOK --\u003e\n## Inputs\n\n| Name | Description | Type | Default | Required |\n|------|-------------|------|---------|:--------:|\n| 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. Requires `layer_7_ddos_defense_enable` set to `true`. `load_threshold`, `confidence_threshold`, `expiration_sec`, `impacted_baseline_threshold` cannot be provided if `layer_7_ddos_defense_threshold_configs` is not null. `exceed_redirect_options` can be provided only if `rate_limit_options.exceed_action` is `redirect` | \u003cpre\u003eobject({\u003cbr\u003e    enable      = bool\u003cbr\u003e    priority    = optional(number, null)\u003cbr\u003e    action      = optional(string, null)\u003cbr\u003e    preview     = optional(bool, false)\u003cbr\u003e    description = optional(string, \"Adaptive Protection auto-deploy\")\u003cbr\u003e\u003cbr\u003e    load_threshold              = optional(number)\u003cbr\u003e    confidence_threshold        = optional(number)\u003cbr\u003e    impacted_baseline_threshold = optional(number)\u003cbr\u003e    expiration_sec              = optional(number)\u003cbr\u003e\u003cbr\u003e    redirect_type   = optional(string)\u003cbr\u003e    redirect_target = optional(string)\u003cbr\u003e\u003cbr\u003e    rate_limit_options = optional(object({\u003cbr\u003e      enforce_on_key      = optional(string)\u003cbr\u003e      enforce_on_key_name = optional(string)\u003cbr\u003e\u003cbr\u003e      enforce_on_key_configs = optional(list(object({\u003cbr\u003e        enforce_on_key_name = optional(string)\u003cbr\u003e        enforce_on_key_type = optional(string)\u003cbr\u003e      })))\u003cbr\u003e\u003cbr\u003e      exceed_action                        = optional(string)\u003cbr\u003e      rate_limit_http_request_count        = optional(number)\u003cbr\u003e      rate_limit_http_request_interval_sec = optional(number)\u003cbr\u003e      ban_duration_sec                     = optional(number)\u003cbr\u003e      ban_http_request_count               = optional(number)\u003cbr\u003e      ban_http_request_interval_sec        = optional(number)\u003cbr\u003e      exceed_redirect_options = optional(object({\u003cbr\u003e        type   = string\u003cbr\u003e        target = optional(string)\u003cbr\u003e      }))\u003cbr\u003e    }), {})\u003cbr\u003e  })\u003c/pre\u003e | \u003cpre\u003e{\u003cbr\u003e  \"enable\": false\u003cbr\u003e}\u003c/pre\u003e | no |\n| custom\\_rules | Custome security rules | \u003cpre\u003emap(object({\u003cbr\u003e    action          = string\u003cbr\u003e    priority        = number\u003cbr\u003e    description     = optional(string)\u003cbr\u003e    preview         = optional(bool, false)\u003cbr\u003e    expression      = string\u003cbr\u003e    redirect_type   = optional(string, null)\u003cbr\u003e    redirect_target = optional(string, null)\u003cbr\u003e    rate_limit_options = optional(object({\u003cbr\u003e      enforce_on_key      = optional(string)\u003cbr\u003e      enforce_on_key_name = optional(string)\u003cbr\u003e      enforce_on_key_configs = optional(list(object({\u003cbr\u003e        enforce_on_key_name = optional(string)\u003cbr\u003e        enforce_on_key_type = optional(string)\u003cbr\u003e      })))\u003cbr\u003e      exceed_action                        = optional(string)\u003cbr\u003e      rate_limit_http_request_count        = optional(number)\u003cbr\u003e      rate_limit_http_request_interval_sec = optional(number)\u003cbr\u003e      ban_duration_sec                     = optional(number)\u003cbr\u003e      ban_http_request_count               = optional(number)\u003cbr\u003e      ban_http_request_interval_sec        = optional(number)\u003cbr\u003e      }),\u003cbr\u003e    {})\u003cbr\u003e    header_action = optional(list(object({\u003cbr\u003e      header_name  = optional(string)\u003cbr\u003e      header_value = optional(string)\u003cbr\u003e    })), [])\u003cbr\u003e\u003cbr\u003e    preconfigured_waf_config_exclusions = optional(map(object({\u003cbr\u003e      target_rule_set = string\u003cbr\u003e      target_rule_ids = optional(list(string), [])\u003cbr\u003e      request_header = optional(list(object({\u003cbr\u003e        operator = string\u003cbr\u003e        value    = optional(string)\u003cbr\u003e      })))\u003cbr\u003e      request_cookie = optional(list(object({\u003cbr\u003e        operator = string\u003cbr\u003e        value    = optional(string)\u003cbr\u003e      })))\u003cbr\u003e      request_uri = optional(list(object({\u003cbr\u003e        operator = string\u003cbr\u003e        value    = optional(string)\u003cbr\u003e      })))\u003cbr\u003e      request_query_param = optional(list(object({\u003cbr\u003e        operator = string\u003cbr\u003e        value    = optional(string)\u003cbr\u003e      })))\u003cbr\u003e    })), null)\u003cbr\u003e\u003cbr\u003e  }))\u003c/pre\u003e | `{}` | no |\n| default\\_rule\\_action | default rule that allows/denies all traffic with the lowest priority (2,147,483,647). | `string` | `\"allow\"` | no |\n| description | An optional description of this security policy. Max size is 2048. | `string` | `null` | no |\n| 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 |\n| json\\_parsing | Whether or not to JSON parse the payload body. Possible values are DISABLED and STANDARD. Not supported for CLOUD\\_ARMOR\\_EDGE policy type. | `string` | `\"DISABLED\"` | no |\n| layer\\_7\\_ddos\\_defense\\_enable | (Optional) If set to true, enables Cloud Armor Adaptive Protection for L7 DDoS detection. Cloud Armor Adaptive Protection is only supported in Global Security Policies of type CLOUD\\_ARMOR. Set this variable `true` for Adaptive Protection Auto Deploy. | `bool` | `false` | no |\n| layer\\_7\\_ddos\\_defense\\_rule\\_visibility | (Optional) Rule visibility can be one of the following: STANDARD - opaque rules. PREMIUM - transparent rules. This field is only supported in Global Security Policies of type CLOUD\\_ARMOR. | `string` | `\"STANDARD\"` | no |\n| layer\\_7\\_ddos\\_defense\\_threshold\\_configs | (Optional) Configuration options for layer7 adaptive protection for various customizable thresholds. `adaptive_protection_auto_deploy.load_threshold`, `adaptive_protection_auto_deploy.confidence_threshold`, `adaptive_protection_auto_deploy.expiration_sec`, `adaptive_protection_auto_deploy.impacted_baseline_threshold` cannot be provided if `layer_7_ddos_defense_threshold_configs` is not null | \u003cpre\u003elist(object({\u003cbr\u003e    name                                    = string\u003cbr\u003e    auto_deploy_load_threshold              = optional(number)\u003cbr\u003e    auto_deploy_confidence_threshold        = optional(number)\u003cbr\u003e    auto_deploy_impacted_baseline_threshold = optional(number)\u003cbr\u003e    auto_deploy_expiration_sec              = optional(number)\u003cbr\u003e    detection_load_threshold                = optional(number)\u003cbr\u003e    detection_absolute_qps                  = optional(number)\u003cbr\u003e    detection_relative_to_baseline_qps      = optional(number)\u003cbr\u003e    traffic_granularity_configs = optional(list(object({\u003cbr\u003e      type                     = string\u003cbr\u003e      value                    = optional(string)\u003cbr\u003e      enable_each_unique_value = optional(bool)\u003cbr\u003e    })))\u003cbr\u003e  }))\u003c/pre\u003e | `null` | no |\n| log\\_level | Log level to use. Possible values are NORMAL and VERBOSE. Not supported for CLOUD\\_ARMOR\\_EDGE policy type. | `string` | `\"NORMAL\"` | no |\n| name | Name of the security policy. | `string` | n/a | yes |\n| pre\\_configured\\_rules | Map of pre-configured rules with Sensitivity levels. | \u003cpre\u003emap(object({\u003cbr\u003e    action                  = string\u003cbr\u003e    priority                = number\u003cbr\u003e    description             = optional(string)\u003cbr\u003e    preview                 = optional(bool, false)\u003cbr\u003e    redirect_type           = optional(string, null)\u003cbr\u003e    redirect_target         = optional(string, null)\u003cbr\u003e    target_rule_set         = string\u003cbr\u003e    sensitivity_level       = optional(number, 4)\u003cbr\u003e    include_target_rule_ids = optional(list(string), [])\u003cbr\u003e    exclude_target_rule_ids = optional(list(string), [])\u003cbr\u003e    rate_limit_options = optional(object({\u003cbr\u003e      enforce_on_key      = optional(string)\u003cbr\u003e      enforce_on_key_name = optional(string)\u003cbr\u003e      enforce_on_key_configs = optional(list(object({\u003cbr\u003e        enforce_on_key_name = optional(string)\u003cbr\u003e        enforce_on_key_type = optional(string)\u003cbr\u003e      })))\u003cbr\u003e      exceed_action                        = optional(string)\u003cbr\u003e      rate_limit_http_request_count        = optional(number)\u003cbr\u003e      rate_limit_http_request_interval_sec = optional(number)\u003cbr\u003e      ban_duration_sec                     = optional(number)\u003cbr\u003e      ban_http_request_count               = optional(number)\u003cbr\u003e      ban_http_request_interval_sec        = optional(number)\u003cbr\u003e    }), {})\u003cbr\u003e\u003cbr\u003e    header_action = optional(list(object({\u003cbr\u003e      header_name  = optional(string)\u003cbr\u003e      header_value = optional(string)\u003cbr\u003e    })), [])\u003cbr\u003e\u003cbr\u003e    preconfigured_waf_config_exclusions = optional(map(object({\u003cbr\u003e      target_rule_set = string\u003cbr\u003e      target_rule_ids = optional(list(string), [])\u003cbr\u003e      request_header = optional(list(object({\u003cbr\u003e        operator = string\u003cbr\u003e        value    = optional(string)\u003cbr\u003e      })))\u003cbr\u003e      request_cookie = optional(list(object({\u003cbr\u003e        operator = string\u003cbr\u003e        value    = optional(string)\u003cbr\u003e      })))\u003cbr\u003e      request_uri = optional(list(object({\u003cbr\u003e        operator = string\u003cbr\u003e        value    = optional(string)\u003cbr\u003e      })))\u003cbr\u003e      request_query_param = optional(list(object({\u003cbr\u003e        operator = string\u003cbr\u003e        value    = optional(string)\u003cbr\u003e      })))\u003cbr\u003e    })), null)\u003cbr\u003e\u003cbr\u003e  }))\u003c/pre\u003e | `{}` | no |\n| project\\_id | The project in which the resource belongs. | `string` | n/a | yes |\n| recaptcha\\_redirect\\_site\\_key | reCAPTCHA site key to be used for all the rules using the redirect action with the redirect type of GOOGLE\\_RECAPTCHA. | `string` | `null` | no |\n| security\\_rules | Map of Security rules with list of IP addresses to block or unblock. | \u003cpre\u003emap(object({\u003cbr\u003e    action          = string\u003cbr\u003e    priority        = number\u003cbr\u003e    description     = optional(string)\u003cbr\u003e    preview         = optional(bool, false)\u003cbr\u003e    redirect_type   = optional(string, null)\u003cbr\u003e    redirect_target = optional(string, null)\u003cbr\u003e    src_ip_ranges   = list(string)\u003cbr\u003e    rate_limit_options = optional(object({\u003cbr\u003e      enforce_on_key      = optional(string)\u003cbr\u003e      enforce_on_key_name = optional(string)\u003cbr\u003e      enforce_on_key_configs = optional(list(object({\u003cbr\u003e        enforce_on_key_name = optional(string)\u003cbr\u003e        enforce_on_key_type = optional(string)\u003cbr\u003e      })))\u003cbr\u003e      exceed_action                        = optional(string)\u003cbr\u003e      rate_limit_http_request_count        = optional(number)\u003cbr\u003e      rate_limit_http_request_interval_sec = optional(number)\u003cbr\u003e      ban_duration_sec                     = optional(number)\u003cbr\u003e      ban_http_request_count               = optional(number)\u003cbr\u003e      ban_http_request_interval_sec        = optional(number)\u003cbr\u003e    }), {})\u003cbr\u003e    header_action = optional(list(object({\u003cbr\u003e      header_name  = optional(string)\u003cbr\u003e      header_value = optional(string)\u003cbr\u003e    })), [])\u003cbr\u003e  }))\u003c/pre\u003e | `{}` | no |\n| threat\\_intelligence\\_rules | Map of Threat Intelligence Feed rules | \u003cpre\u003emap(object({\u003cbr\u003e    action      = string\u003cbr\u003e    priority    = number\u003cbr\u003e    description = optional(string)\u003cbr\u003e    preview     = optional(bool, false)\u003cbr\u003e    feed        = string\u003cbr\u003e    exclude_ip  = optional(string)\u003cbr\u003e    rate_limit_options = optional(object({\u003cbr\u003e      enforce_on_key      = optional(string)\u003cbr\u003e      enforce_on_key_name = optional(string)\u003cbr\u003e      enforce_on_key_configs = optional(list(object({\u003cbr\u003e        enforce_on_key_name = optional(string)\u003cbr\u003e        enforce_on_key_type = optional(string)\u003cbr\u003e      })))\u003cbr\u003e      exceed_action                        = optional(string)\u003cbr\u003e      rate_limit_http_request_count        = optional(number)\u003cbr\u003e      rate_limit_http_request_interval_sec = optional(number)\u003cbr\u003e      ban_duration_sec                     = optional(number)\u003cbr\u003e      ban_http_request_count               = optional(number)\u003cbr\u003e      ban_http_request_interval_sec        = optional(number)\u003cbr\u003e    }), {})\u003cbr\u003e    header_action = optional(list(object({\u003cbr\u003e      header_name  = optional(string)\u003cbr\u003e      header_value = optional(string)\u003cbr\u003e    })), [])\u003cbr\u003e  }))\u003c/pre\u003e | `{}` | no |\n| type | Type indicates the intended use of the security policy. Possible values are CLOUD\\_ARMOR and CLOUD\\_ARMOR\\_EDGE. | `string` | `\"CLOUD_ARMOR\"` | no |\n| user\\_ip\\_request\\_headers | An optional list of case-insensitive request header names to use for resolving the callers client IP address. | `list(string)` | `[]` | no |\n\n## Outputs\n\n| Name | Description |\n|------|-------------|\n| policy | Security policy created |\n\n\u003c!-- END OF PRE-COMMIT-TERRAFORM DOCS HOOK --\u003e\n\n\n\n## Rules\n\n[Pre-Configured Rules](#pre_configured_rules), [Security Rules](#security_rules), [Custom Rules](#custom_rules) and [Threat Intelligence Rules](#threat_intelligence_rules) are maps of rules. Each rule is a map which provides details about the rule. Here is an example of `pre_configured_rules`:\n\n```\n  \"my_rule\" = {\n    action                             = \"deny(502)\"\n    priority                             = 1\n    description                          = \"SQL Sensitivity Level 4\"\n    preview                              = false\n    redirect_type                        = null\n    redirect_target                      = null\n    target_rule_set                      = \"sqli-v33-stable\"\n    sensitivity_level                    = 4\n    include_target_rule_ids              = []\n    exclude_target_rule_ids              = []\n    header_action                        = []\n    rate_limit_options                   = {}\n    preconfigured_waf_config_exclusions  = {}\n  }\n```\n\n`action, priority, description, preview, rate_limit_options, header_action, redirect_type and redirect_target` are common in all the rule types. Some of then are optional and some have default value see [Input](#Inputs).\n\n## Rate limit\n`rate_limit_options` is needed for the rules where action is set to `throttle` or `rate_based_ban`. `rate_limit_options` is a map of strings with following key pairs. You can find more details about rate limit [here](https://cloud.google.com/armor/docs/rate-limiting-overview).\n\n```\nrate_limit_options = {\n  exceed_action                        = \"deny(502)\"\n  rate_limit_http_request_count        = 10\n  rate_limit_http_request_interval_sec = 60    # 10, 30, 60, 120, 180, 240, 300, 600, 900, 1200, 1800, 2700, 3600 seconds\n  ban_duration_sec                     = 600   # needed only if action is rate_based_ban\n  ban_http_request_count               = 1000  # needed only if action is rate_based_ban\n  ban_http_request_interval_sec        = 300   # 60, 120, 180, 240, 300, 600, 900, 1200, 1800, 2700, 3600 seconds. needed only if action is rate_based_ban\n  enforce_on_key                       = \"ALL\" # All is default value. If null is passed terraform will use ALL as the value. Will be set to \"\" when `enforce_on_key_configs` is not null\n\n  enforce_on_key_configs = [\n    {\n      enforce_on_key_type = \"HTTP_PATH\"\n    },\n    {\n      enforce_on_key_type = \"HTTP_COOKIE\"\n      enforce_on_key_name = \"site_id\"\n    }\n  ]\n}\n```\n\n## Preconfigured WAF Config\n\n`preconfigured_waf_config_exclusions` is needed for custom application that might contain content in request fields (like headers, cookies, query parameters, or URIs) that matches signatures in preconfigured WAF rules, but which you know is legitimate. In this case, you can reduce false positives by excluding those request fields from inspection by associating a list of exclusions for request fields with the security policy rule. You can pass `request_header`, `request_uri`, `request_cookie` and `request_query_param`. It is available in [Pre-Configured Rules](#pre_configured_rules). You can find more details about `preconfigured_waf_config` [here](https://cloud.google.com/armor/docs/rule-tuning#exclude_request_fields_from_inspection)\n\n```\npreconfigured_waf_config_exclusions = {\n\n  exclusion_1 = {\n    target_rule_set = \"sqli-v33-stable\"\n    target_rule_ids = [\"owasp-crs-v030301-id942120-sqli\", \"owasp-crs-v030301-id942130-sqli\"]\n    request_cookie = [\n      {\n        operator = \"STARTS_WITH\"\n        value    = \"abc\"\n      }\n    ]\n    request_header = [\n      {\n        operator = \"STARTS_WITH\"\n        value    = \"xyz\"\n      },\n      {\n        operator = \"STARTS_WITH\"\n        value    = \"uvw\"\n      }\n    ]\n  }\n\n  exclusion_2 = {\n    target_rule_set = \"sqli-v33-stable\"\n    target_rule_ids = [\"owasp-crs-v030301-id942150-sqli\", \"owasp-crs-v030301-id942180-sqli\"]\n    request_header = [\n      {\n        operator = \"STARTS_WITH\"\n        value    = \"lmn\"\n      },\n      {\n        operator = \"ENDS_WITH\"\n        value    = \"opq\"\n      }\n    ]\n    request_uri = [\n      {\n        operator = \"CONTAINS\"\n        value    = \"https://hashicorp.com\"\n      },\n      {\n        operator = \"CONTAINS\"\n        value    = \"https://xyz.com\"\n      },\n    ]\n  }\n\n}\n```\n\n## pre_configured_rules\nList of preconfigured rules are available [here](https://cloud.google.com/armor/docs/waf-rules). Following is the key value pairs for setting up pre configured rules. `include_target_rule_ids` and `exclude_target_rule_ids` are mutually exclusive. If `include_target_rule_ids` is provided, sensitivity_level is automatically set to 0 by the module as it is a [requirement for opt in rule signature](https://cloud.google.com/armor/docs/rule-tuning#opt_in_rule_signatures). `exclude_target_rule_ids` is ignored when `include_target_rule_ids` is provided.\n\n### Format:\n\n```\n  \"sqli_sensitivity_level_4\" = {\n    action                               = \"deny(502)\"\n    priority                             = 1\n    description                          = \"SQL Sensitivity Level 4\"\n    preview                              = false\n    redirect_type                        = null\n    redirect_target                      = null\n    target_rule_set                      = \"sqli-v33-stable\"\n    sensitivity_level                    = 4\n    include_target_rule_ids              = []\n    exclude_target_rule_ids              = []\n    rate_limit_options                   = {}\n    header_action                        = []\n    preconfigured_waf_config_exclusions  = {}\n  }\n```\n\n\n### Sample:\n\n```\npre_configured_rules = {\n\n  \"php-stable_level_1_with_include\" = {\n    action                  = \"deny(502)\"\n    priority                = 3\n    description             = \"PHP Sensitivity Level 1 with included rules\"\n    target_rule_set         = \"xss-v33-stable\"\n    sensitivity_level       = 0\n    include_target_rule_ids = [\"owasp-crs-v030301-id933190-php\", \"owasp-crs-v030301-id933111-php\"]\n  }\n\n  \"sqli_sensitivity_level_4\" = {\n    action            = \"deny(502)\"\n    priority          = 1\n    target_rule_set   = \"sqli-v33-stable\"\n    sensitivity_level = 4\n\n    preconfigured_waf_config_exclusions = {\n\n      exclusion_1 = {\n        target_rule_set = \"sqli-v33-stable\"\n        target_rule_ids = [\"owasp-crs-v030301-id942120-sqli\", \"owasp-crs-v030301-id942130-sqli\"]\n        request_cookie = [\n          {\n            operator = \"STARTS_WITH\"\n            value    = \"abc\"\n          }\n        ]\n        request_header = [\n          {\n            operator = \"STARTS_WITH\"\n            value    = \"xyz\"\n          },\n          {\n            operator = \"STARTS_WITH\"\n            value    = \"uvw\"\n          }\n        ]\n      }\n\n      exclusion_2 = {\n        target_rule_set = \"sqli-v33-stable\"\n        target_rule_ids = [\"owasp-crs-v030301-id942150-sqli\", \"owasp-crs-v030301-id942180-sqli\"]\n        request_header = [\n          {\n            operator = \"STARTS_WITH\"\n            value    = \"lmn\"\n          },\n          {\n            operator = \"ENDS_WITH\"\n            value    = \"opq\"\n          }\n        ]\n        request_uri = [\n          {\n            operator = \"CONTAINS\"\n            value    = \"https://hashicorp.com\"\n          },\n          {\n            operator = \"CONTAINS\"\n            value    = \"https://xyz.com\"\n          },\n        ]\n      }\n\n    }\n\n  }\n\n}\n```\n\n\n## security_rules:\nSet of IP addresses or ranges (IPV4 or IPV6) in CIDR notation to match against inbound traffic. There is a limit of 10 IP ranges per rule.\n\n### Format:\nEach rule is key value pair where key is a unique name of the rule and value is the action associated with it.\n\n```\n\"block_bad_actor_ip\" = {\n  action             = \"deny(502)\"\n  priority           = 11\n  description        = \"Deny Malicious IP address\"\n  src_ip_ranges      = [\"A..B.C.D\", \"W.X.Y.Z\",]\n  preview            = false\n  redirect_type      = null\n  redirect_target    = null\n  rate_limit_options = {}\n  header_action      = []\n}\n```\n\n### Sample:\n\n```\nsecurity_rules = {\n\n  \"deny_project_bad_actor\" = {\n    action             = \"deny(502)\"\n    priority           = 11\n    description        = \"Deny Malicious IP address from project bad_actor\"\n    src_ip_ranges      = [\"190.217.68.211/32\", \"45.116.227.68/32\", \"103.43.141.122\", \"123.11.215.36\", ]\n  }\n\n  \"throttle_project_droptwenty\" = {\n    action        = \"throttle\"\n    priority      = 15\n    description   = \"Throttle IP addresses from project droptwenty\"\n    src_ip_ranges = [\"190.217.68.214\", \"45.116.227.71\", ]\n\n    rate_limit_options = {\n      exceed_action                        = \"deny(502)\"\n      rate_limit_http_request_count        = 10\n      rate_limit_http_request_interval_sec = 60\n      enforce_on_key_configs = [\n        {\n          enforce_on_key_type = \"HTTP_PATH\"\n        },\n        {\n          enforce_on_key_type = \"HTTP_COOKIE\"\n          enforce_on_key_name = \"site_id\"\n        }\n      ]\n    }\n\n  }\n\n}\n```\n\n## custom_rules:\nAdd Custom Rules using [Common Expression Language (CEL)](https://cloud.google.com/armor/docs/rules-language-reference)\n\n### Format:\nEach rule is key value pair where key is a unique name of the rule and value is the action associated with it.\n\n```\nallow_specific_regions = {\n  action             = \"allow\"\n  priority           = 21\n  description        = \"Allow specific Regions\"\n  preview            = false\n  expression         = \u003c\u003c-EOT\n    '[US,AU,BE]'.contains(origin.region_code)\n  EOT\n  redirect_type      = null\n  redirect_target    = null\n  rate_limit_options = {}\n  header_action      = []\n}\n```\n\n### Sample:\n\n```\ncustom_rules = {\n\n  allow_specific_regions = {\n    action             = \"allow\"\n    priority           = 21\n    description        = \"Allow specific Regions\"\n    preview            = true\n    expression         = \u003c\u003c-EOT\n      '[US,AU,BE]'.contains(origin.region_code)\n    EOT\n  }\n\n  allow_path_token_header = {\n    action      = \"allow\"\n    priority    = 25\n    description = \"Allow path and token match with addition of header\"\n\n    expression = \u003c\u003c-EOT\n      request.path.matches('/login.html') \u0026\u0026 token.recaptcha_session.score \u003c 0.2\n    EOT\n\n    header_action = [\n      {\n        header_name  = \"reCAPTCHA-Warning\"\n        header_value = \"high\"\n      },\n      {\n        header_name  = \"X-Resource\"\n        header_value = \"test\"\n      }\n    ]\n\n  }\n\n}\n```\n\n## threat_intelligence_rules:\nAdd Rules based on [threat intelligence](https://cloud.google.com/armor/docs/threat-intelligence). [Managed protection plus](https://cloud.google.com/armor/docs/managed-protection-overview) subscription is needed to use this feature.\n\n### Format:\nEach rule is key value pair where key is a unique name of the rule and value is the action associated with it. NOTE: `exclude_ip` is a string with IP addresse(s) in single quotes and enclused within a sqare bracket (You can find detail [here](https://cloud.google.com/armor/docs/threat-intelligence#configure-nti)).\n\n```\nthreat_intelligence_rules = {\n  deny_crawlers_ip = {\n    action             = \"deny(502)\"\n    priority           = 31\n    description        = \"Deny IP addresses of search engine crawlers\"\n    preview            = false\n    feed               = \"iplist-search-engines-crawlers\"\n    exclude_ip         = null\n    rate_limit_options = {}\n    header_action      = []\n  }\n}\n```\n\n### Sample:\n\n```\nthreat_intelligence_rules = {\n\n  deny_malicious_ips = {\n    action      = \"deny(502)\"\n    priority    = 31\n    description = \"Deny IP addresses known to attack web applications\"\n    preview     = true\n    feed        = \"iplist-known-malicious-ips\"\n    exclude_ip  = \"['47.100.100.100', '47.189.12.139']\"\n  }\n\n  deny_tor_exit_ips = {\n    action      = \"deny(502)\"\n    priority    = 31\n    description = \"Deny Tor exit nodes IP addresses\"\n    preview     = true\n    feed        = \"iplist-tor-exit-nodes\"\n  }\n\n}\n```\n\n## adaptive_protection_auto_deploy:\nAdd a rule to [Automatically deploy Adaptive Protection suggested rules](https://cloud.google.com/armor/docs/adaptive-protection-auto-deploy). [Managed protection plus](https://cloud.google.com/armor/docs/managed-protection-overview) subscription is needed to use this feature. By default this feature is disabled. If `enable` is set to true you need to provide `priority` and `action` for this module to deploy auto deploy rule. Module will create a rule with expression `evaluateAdaptiveProtectionAutoDeploy()`.\n\n### Format:\nIt is an object with key value pair.\n\n```\nadaptive_protection_auto_deploy = {\n  enable                      = true\n  action                      = \"deny(502)\"\n  priority                    = 31\n  description                 = \"Automatically deploy Adaptive Protection suggested rules\"\n  preview                     = false\n\n  load_threshold              = 0.1    #This cannot be provided if `layer_7_ddos_defense_threshold_configs` is not null\n  confidence_threshold        = 0.5    #This cannot be provided if `layer_7_ddos_defense_threshold_configs` is not null\n  impacted_baseline_threshold = 0.01   #This cannot be provided if `layer_7_ddos_defense_threshold_configs` is not null\n  expiration_sec              = 7200   #This cannot be provided if `layer_7_ddos_defense_threshold_configs` is not null\n\n  redirect_type               = null\n  redirect_target             = null\n  rate_limit_options          = {}\n}\n```\n\n### Sample 1 (Deny):\n\n```\nadaptive_protection_auto_deploy = {\n  enable   = true\n  priority = 100000\n  action   = \"deny(403)\"\n}\n```\n\n### Sample 2 (redirect):\n\n```\nadaptive_protection_auto_deploy = {\n  enable         = true\n  priority       = 100000\n  action         = \"redirect\"\n  redirect_type  = \"GOOGLE_RECAPTCHA\"\n}\n```\n\n### Sample 3 (throttle):\n\n```\nadaptive_protection_auto_deploy = {\n  enable   = true\n  priority = 100000\n  action   = \"throttle\"\n\n  rate_limit_options = {\n    exceed_action                        = \"deny(502)\"\n    rate_limit_http_request_count        = 500\n    rate_limit_http_request_interval_sec = 120\n    enforce_on_key                       = \"IP\"\n  }\n}\n```\n\n## Requirements\n\nThese sections describe requirements for using this module.\n\n### Software\n\nThe following dependencies must be available:\n\n- [Terraform][terraform] v1.3+\n- [Terraform Provider for GCP][terraform-provider-gcp] plugin v6.14+\n\n### Service Account\n\nA service account with the following permission must be used to provision\nthe resources of this module:\n\n- compute.networkEdgeSecurityServices.create\n- compute.networkEdgeSecurityServices.update\n- compute.networkEdgeSecurityServices.get\n- compute.networkEdgeSecurityServices.delete\n- compute.networkEdgeSecurityServices.list\n- compute.securityPolicies.create\n- compute.securityPolicies.delete\n- compute.securityPolicies.get\n- compute.securityPolicies.list\n- compute.securityPolicies.use\n- compute.securityPolicies.update\n- recaptchaenterprise.keys.list\n- recaptchaenterprise.keys.get\n\nFollowing roles contain above mentioned permissions. You can either assing one of the following role or create custom roles with above permissions.\n\n- Compute Organization Security Policy Admin: `roles/compute.orgSecurityPolicyAdmin`\n- Compute Security Admin: `roles/compute.securityAdmin`\n- reCAPTCHA Enterprise Admin: `roles/recaptchaenterprise.admin`\n\n### Enable API's\nIn order to operate with the Service Account you must activate the following API on the project where the Service Account was created:\n\n- Compute Engine API - compute.googleapis.com\n\n## Contributing\n\nRefer to the [contribution guidelines](./CONTRIBUTING.md) for\ninformation on contributing to this module.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgooglecloudplatform%2Fterraform-google-cloud-armor","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fgooglecloudplatform%2Fterraform-google-cloud-armor","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgooglecloudplatform%2Fterraform-google-cloud-armor/lists"}