Skip to content

Commit

Permalink
feat: Added AWSManagedRules rule sets to WAFv2
Browse files Browse the repository at this point in the history
   + AWSManagedRulesATPRuleSet
   + AWSManagedRulesACFPRuleSet
   + AWSManagedRulesBotControlRuleSet
   + captchaConfig
   + challengeConfig
  • Loading branch information
uyggnodoow committed Jan 30, 2025
1 parent ba70458 commit 146f78e
Show file tree
Hide file tree
Showing 3 changed files with 135 additions and 2 deletions.
8 changes: 7 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,10 @@ A Terraform module that creates Web Application Firewall (WAFV2).
- GeoMatchStatement
- IPSetReferenceStatement
- LabelMatchStatement
- ManagedRuleGroupStatement
- ManagedRuleGroupStatemen
- AWSManagedRulesACFPRuleSet
- AWSManagedRulesATPRuleSet
- AWSManagedRulesBotControlRuleSet
- NotStatement
- OrStatement
- RateBasedStatement
Expand Down Expand Up @@ -58,6 +61,8 @@ No modules.

| Name | Description | Type | Default | Required |
|------|-------------|------|---------|:--------:|
| <a name="input_captcha_config"></a> [captcha\_config](#input\_captcha\_config) | (Optional) The amount of time, in seconds, that a CAPTCHA or challenge timestamp is considered valid by AWS WAF. The default setting is 300. | `number` | `300` | no |
| <a name="input_challenge_config"></a> [challenge\_config](#input\_challenge\_config) | (Optional) The amount of time, in seconds, that a CAPTCHA or challenge timestamp is considered valid by AWS WAF. The default setting is 300. | `number` | `300` | no |
| <a name="input_custom_response_body"></a> [custom\_response\_body](#input\_custom\_response\_body) | (Optional) Defines custom response bodies that can be referenced by custom\_response actions. | `map(any)` | `{}` | no |
| <a name="input_default_action"></a> [default\_action](#input\_default\_action) | (Required) Action to perform if none of the rules contained in the WebACL match. | `string` | n/a | yes |
| <a name="input_description"></a> [description](#input\_description) | (Optional) Friendly description of the WebACL. | `string` | `null` | no |
Expand All @@ -71,6 +76,7 @@ No modules.
| <a name="input_rule"></a> [rule](#input\_rule) | (Optional) Rule blocks used to identify the web requests that you want to allow, block, or count. | `any` | n/a | yes |
| <a name="input_scope"></a> [scope](#input\_scope) | (Required) Specifies whether this is for an AWS CloudFront distribution or for a regional application | `string` | n/a | yes |
| <a name="input_tags"></a> [tags](#input\_tags) | (Optional) Map of key-value pairs to associate with the resource. | `map(string)` | `null` | no |
| <a name="input_token_domains"></a> [token\_domains](#input\_token\_domains) | (Optional) Specifies the domains that AWS WAF should accept in a web request token. This enables the use of tokens across multiple protected websites. When AWS WAF provides a token, it uses the domain of the AWS resource that the web ACL is protecting. If you don't specify a list of token domains, AWS WAF accepts tokens only for the domain of the protected resource. With a token domain list, AWS WAF accepts the resource's host domain plus all domains in the token domain list, including their prefixed subdomains. | `list(string)` | `[]` | no |
| <a name="input_visibility_config"></a> [visibility\_config](#input\_visibility\_config) | (Required) Defines and enables Amazon CloudWatch metrics and web request sample collection. | `map(string)` | n/a | yes |

## Outputs
Expand Down
111 changes: 110 additions & 1 deletion main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,96 @@ resource "aws_wafv2_web_acl" "this" {
vendor_name = lookup(managed_rule_group_statement.value, "vendor_name", "AWS")
version = lookup(managed_rule_group_statement.value, "version", null)

dynamic "managed_rule_group_configs" {
for_each = lookup(managed_rule_group_statement.value, "managed_rule_group_configs", null) == null ? [] : lookup(managed_rule_group_statement.value, "managed_rule_group_configs")
content {
dynamic "aws_managed_rules_acfp_rule_set" {
for_each = lookup(managed_rule_group_configs.value, "aws_managed_rules_acfp_rule_set", null) == null ? [] : [lookup(managed_rule_group_configs.value, "aws_managed_rules_acfp_rule_set")]
content {
creation_path = lookup(aws_managed_rules_acfp_rule_set.value, "creation_path")
enable_regex_in_path = lookup(aws_managed_rules_acfp_rule_set.value, "enable_regex_in_path", false)
registration_page_path = lookup(aws_managed_rules_acfp_rule_set.value, "registration_page_path")

dynamic "request_inspection" {
for_each = lookup(aws_managed_rules_acfp_rule_set.value, "request_inspection") == null ? [] : [lookup(aws_managed_rules_acfp_rule_set.value, "request_inspection")]
content {
payload_type = lookup(request_inspection.value, "payload_type", "JSON")

dynamic "address_fields" {
for_each = lookup(request_inspection.value, "address_fields", null) == null ? [] : [lookup(request_inspection.value, "address_fields")]

content {
identifiers = lookup(address_fields.value, "identifiers")
}
}
dynamic "email_field" {
for_each = lookup(request_inspection.value, "email_field", null) == null ? [] : [lookup(request_inspection.value, "email_field")]
content {
identifier = lookup(email_field.value, "identifier")
}
}
dynamic "password_field" {
for_each = lookup(request_inspection.value, "password_field", null) == null ? [] : [lookup(request_inspection.value, "password_field")]
content {
identifier = lookup(password_field.value, "identifier")
}
}
dynamic "phone_number_fields" {
for_each = lookup(request_inspection.value, "phone_number_fields", null) == null ? [] : [lookup(request_inspection.value, "phone_number_fields")]

content {
identifiers = lookup(phone_number_fields.value, "identifiers")
}
}
dynamic "username_field" {
for_each = lookup(request_inspection.value, "username_field", null) == null ? [] : [lookup(request_inspection.value, "username_field")]
content {
identifier = lookup(username_field.value, "identifier")
}
}
}
}
}
}

dynamic "aws_managed_rules_atp_rule_set" {
for_each = lookup(managed_rule_group_configs.value, "aws_managed_rules_atp_rule_set", null) == null ? [] : [lookup(managed_rule_group_configs.value, "aws_managed_rules_atp_rule_set")]
content {
enable_regex_in_path = lookup(aws_managed_rules_atp_rule_set.value, "enable_regex_in_path", false)
login_path = lookup(aws_managed_rules_atp_rule_set.value, "login_path")

dynamic "request_inspection" {
for_each = lookup(aws_managed_rules_atp_rule_set.value, "request_inspection") == null ? [] : [lookup(aws_managed_rules_atp_rule_set.value, "request_inspection")]
content {
payload_type = lookup(request_inspection.value, "payload_type", "JSON")

dynamic "password_field" {
for_each = lookup(request_inspection.value, "password_field", null) == null ? [] : [lookup(request_inspection.value, "password_field")]
content {
identifier = lookup(password_field.value, "identifier")
}
}
dynamic "username_field" {
for_each = lookup(request_inspection.value, "username_field", null) == null ? [] : [lookup(request_inspection.value, "username_field")]
content {
identifier = lookup(username_field.value, "identifier")
}
}
}
}
}
}

dynamic "aws_managed_rules_bot_control_rule_set" {
for_each = lookup(managed_rule_group_configs.value, "aws_managed_rules_bot_control_rule_set", null) == null ? [] : [lookup(managed_rule_group_configs.value, "aws_managed_rules_bot_control_rule_set")]
content {
enable_machine_learning = lookup(aws_managed_rules_bot_control_rule_set.value, "enable_machine_learning", true)
inspection_level = upper(lookup(aws_managed_rules_bot_control_rule_set.value, "inspection_level", "COMMON"))
}
}
}
}

dynamic "rule_action_override" {
for_each = lookup(managed_rule_group_statement.value, "rule_action_override", null) == null ? [] : lookup(managed_rule_group_statement.value, "rule_action_override")
content {
Expand Down Expand Up @@ -113,6 +203,7 @@ resource "aws_wafv2_web_acl" "this" {
}
}
}

dynamic "scope_down_statement" {
for_each = lookup(managed_rule_group_statement.value, "scope_down_statement", null) == null ? [] : [lookup(managed_rule_group_statement.value, "scope_down_statement")]
content {
Expand Down Expand Up @@ -12107,6 +12198,20 @@ resource "aws_wafv2_web_acl" "this" {
}
}

captcha_config {
immunity_time_property {
immunity_time = var.captcha_config
}
}

challenge_config {
immunity_time_property {
immunity_time = var.challenge_config
}
}

token_domains = var.token_domains

visibility_config {
cloudwatch_metrics_enabled = var.visibility_config.cloudwatch_metrics_enabled
metric_name = var.visibility_config.metric_name
Expand Down Expand Up @@ -12158,30 +12263,34 @@ resource "aws_wafv2_web_acl_logging_configuration" "this" {

dynamic "logging_filter" {
for_each = var.logging_filter == null ? [] : [var.logging_filter]

content {
default_behavior = lookup(logging_filter.value, "default_behavior")

dynamic "filter" {
for_each = lookup(logging_filter.value, "filter")
iterator = filter

content {
behavior = lookup(filter.value, "behavior")
requirement = lookup(filter.value, "requirement")

dynamic "condition" {
for_each = lookup(filter.value, "condition")

content {
dynamic "action_condition" {
for_each = lookup(condition.value, "action_condition", null) == null ? {} : lookup(condition.value, "action_condition")
iterator = action_condition

content {
action = action_condition.value
}
}

dynamic "label_name_condition" {
for_each = lookup(condition.value, "label_name_condition", null) == null ? {} : lookup(condition.value, "label_name_condition")
iterator = label_name_condition

content {
label_name = label_name_condition.value
}
Expand Down
18 changes: 18 additions & 0 deletions variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,24 @@ variable "custom_response_body" {
default = {}
}

variable "captcha_config" {
description = "(Optional) The amount of time, in seconds, that a CAPTCHA or challenge timestamp is considered valid by AWS WAF. The default setting is 300."
type = number
default = 300
}

variable "challenge_config" {
description = "(Optional) The amount of time, in seconds, that a CAPTCHA or challenge timestamp is considered valid by AWS WAF. The default setting is 300."
type = number
default = 300
}

variable "token_domains" {
description = "(Optional) Specifies the domains that AWS WAF should accept in a web request token. This enables the use of tokens across multiple protected websites. When AWS WAF provides a token, it uses the domain of the AWS resource that the web ACL is protecting. If you don't specify a list of token domains, AWS WAF accepts tokens only for the domain of the protected resource. With a token domain list, AWS WAF accepts the resource's host domain plus all domains in the token domain list, including their prefixed subdomains."
type = list(string)
default = []
}

variable "rule" {
description = "(Optional) Rule blocks used to identify the web requests that you want to allow, block, or count."
type = any
Expand Down

0 comments on commit 146f78e

Please sign in to comment.