Resource: aws_wafv2_web_acl

Creates a WAFv2 Web ACL resource.

Example Usage

This resource is based on aws_wafv2_rule_group, check the documentation of the aws_wafv2_rule_group resource to see examples of the various available statements.

Managed Rule

resource "aws_wafv2_web_acl" "example" {
  name        = "managed-rule-example"
  description = "Example of a managed rule."
  scope       = "REGIONAL"

  default_action {
    allow {}
  }

  rule {
    name     = "rule-1"
    priority = 1

    override_action {
      count {}
    }

    statement {
      managed_rule_group_statement {
        name        = "AWSManagedRulesCommonRuleSet"
        vendor_name = "AWS"

        rule_action_override {
          action_to_use {
            count {}
          }

          name = "SizeRestrictions_QUERYSTRING"
        }

        rule_action_override {
          action_to_use {
            count {}
          }

          name = "NoUserAgent_HEADER"
        }

        scope_down_statement {
          geo_match_statement {
            country_codes = ["US", "NL"]
          }
        }
      }
    }

    token_domains = ["mywebsite.com", "myotherwebsite.com"]

    visibility_config {
      cloudwatch_metrics_enabled = false
      metric_name                = "friendly-rule-metric-name"
      sampled_requests_enabled   = false
    }
  }

  tags = {
    Tag1 = "Value1"
    Tag2 = "Value2"
  }

  visibility_config {
    cloudwatch_metrics_enabled = false
    metric_name                = "friendly-metric-name"
    sampled_requests_enabled   = false
  }
}

Account Creation Fraud Prevention

resource "aws_wafv2_web_acl" "acfp-example" {
  name        = "managed-acfp-example"
  description = "Example of a managed ACFP rule."
  scope       = "CLOUDFRONT"

  default_action {
    allow {}
  }

  rule {
    name     = "acfp-rule-1"
    priority = 1

    override_action {
      count {}
    }

    statement {
      managed_rule_group_statement {
        name        = "AWSManagedRulesACFPRuleSet"
        vendor_name = "AWS"

        managed_rule_group_configs {
          aws_managed_rules_acfp_rule_set {
            creation_path          = "/signin"
            registration_page_path = "/register"

            request_inspection {
              email_field {
                identifier = "/email"
              }

              password_field {
                identifier = "/password"
              }

              payload_type = "JSON"

              username_field {
                identifier = "/username"
              }
            }

            response_inspection {
              status_code {
                failure_codes = ["403"]
                success_codes = ["200"]
              }
            }
          }
        }
      }
    }

    visibility_config {
      cloudwatch_metrics_enabled = false
      metric_name                = "friendly-rule-metric-name"
      sampled_requests_enabled   = false
    }
  }

  visibility_config {
    cloudwatch_metrics_enabled = false
    metric_name                = "friendly-metric-name"
    sampled_requests_enabled   = false
  }
}

Account Takeover Protection

resource "aws_wafv2_web_acl" "atp-example" {
  name        = "managed-atp-example"
  description = "Example of a managed ATP rule."
  scope       = "CLOUDFRONT"

  default_action {
    allow {}
  }

  rule {
    name     = "atp-rule-1"
    priority = 1

    override_action {
      count {}
    }

    statement {
      managed_rule_group_statement {
        name        = "AWSManagedRulesATPRuleSet"
        vendor_name = "AWS"

        managed_rule_group_configs {
          aws_managed_rules_atp_rule_set {
            login_path = "/api/1/signin"

            request_inspection {
              password_field {
                identifier = "/password"
              }

              payload_type = "JSON"

              username_field {
                identifier = "/email"
              }
            }

            response_inspection {
              status_code {
                failure_codes = ["403"]
                success_codes = ["200"]
              }
            }
          }
        }
      }
    }

    visibility_config {
      cloudwatch_metrics_enabled = false
      metric_name                = "friendly-rule-metric-name"
      sampled_requests_enabled   = false
    }
  }

  visibility_config {
    cloudwatch_metrics_enabled = false
    metric_name                = "friendly-metric-name"
    sampled_requests_enabled   = false
  }
}

Rate Based

Rate-limit US and NL-based clients to 10,000 requests for every 5 minutes.

resource "aws_wafv2_web_acl" "example" {
  name        = "rate-based-example"
  description = "Example of a Cloudfront rate based statement."
  scope       = "CLOUDFRONT"

  default_action {
    allow {}
  }

  rule {
    name     = "rule-1"
    priority = 1

    action {
      block {}
    }

    statement {
      rate_based_statement {
        limit              = 10000
        aggregate_key_type = "IP"

        scope_down_statement {
          geo_match_statement {
            country_codes = ["US", "NL"]
          }
        }
      }
    }

    visibility_config {
      cloudwatch_metrics_enabled = false
      metric_name                = "friendly-rule-metric-name"
      sampled_requests_enabled   = false
    }
  }

  tags = {
    Tag1 = "Value1"
    Tag2 = "Value2"
  }

  visibility_config {
    cloudwatch_metrics_enabled = false
    metric_name                = "friendly-metric-name"
    sampled_requests_enabled   = false
  }
}

Rule Group Reference

resource "aws_wafv2_rule_group" "example" {
  capacity = 10
  name     = "example-rule-group"
  scope    = "REGIONAL"

  rule {
    name     = "rule-1"
    priority = 1

    action {
      count {}
    }

    statement {
      geo_match_statement {
        country_codes = ["NL"]
      }
    }

    visibility_config {
      cloudwatch_metrics_enabled = false
      metric_name                = "friendly-rule-metric-name"
      sampled_requests_enabled   = false
    }
  }

  rule {
    name     = "rule-to-exclude-a"
    priority = 10

    action {
      allow {}
    }

    statement {
      geo_match_statement {
        country_codes = ["US"]
      }
    }

    visibility_config {
      cloudwatch_metrics_enabled = false
      metric_name                = "friendly-rule-metric-name"
      sampled_requests_enabled   = false
    }
  }

  rule {
    name     = "rule-to-exclude-b"
    priority = 15

    action {
      allow {}
    }

    statement {
      geo_match_statement {
        country_codes = ["GB"]
      }
    }

    visibility_config {
      cloudwatch_metrics_enabled = false
      metric_name                = "friendly-rule-metric-name"
      sampled_requests_enabled   = false
    }
  }

  visibility_config {
    cloudwatch_metrics_enabled = false
    metric_name                = "friendly-metric-name"
    sampled_requests_enabled   = false
  }
}

resource "aws_wafv2_web_acl" "test" {
  name  = "rule-group-example"
  scope = "REGIONAL"

  default_action {
    block {}
  }

  rule {
    name     = "rule-1"
    priority = 1

    override_action {
      count {}
    }

    statement {
      rule_group_reference_statement {
        arn = aws_wafv2_rule_group.example.arn

        rule_action_override {
          action_to_use {
            count {}
          }

          name = "rule-to-exclude-b"
        }

        rule_action_override {
          action_to_use {
            count {}
          }

          name = "rule-to-exclude-a"
        }
      }
    }

    visibility_config {
      cloudwatch_metrics_enabled = false
      metric_name                = "friendly-rule-metric-name"
      sampled_requests_enabled   = false
    }
  }

  tags = {
    Tag1 = "Value1"
    Tag2 = "Value2"
  }

  visibility_config {
    cloudwatch_metrics_enabled = false
    metric_name                = "friendly-metric-name"
    sampled_requests_enabled   = false
  }
}

Argument Reference

This resource supports the following arguments:

association_config Block

The association_config block supports the following arguments:

custom_response_body Block

Each custom_response_body block supports the following arguments:

default_action Block

The default_action block supports the following arguments:

rule Block

Each rule supports the following arguments:

action Block

The action block supports the following arguments:

override_action Block

The override_action block supports the following arguments:

allow Block

The allow block supports the following arguments:

block Block

The block block supports the following arguments:

captcha Block

The captcha block supports the following arguments:

challenge Block

The challenge block supports the following arguments:

count Block

The count block supports the following arguments:

custom_request_handling Block

The custom_request_handling block supports the following arguments:

insert_header Block

Each insert_header block supports the following arguments. Duplicate header names are not allowed:

custom_response Block

The custom_response block supports the following arguments:

response_header Block

Each response_header block supports the following arguments. Duplicate header names are not allowed:

rule_label Block

Each block supports the following arguments:

statement Block

The processing guidance for a Rule, used by AWS WAF to determine whether a web request matches the rule. See the documentation for more information.

The statement block supports the following arguments:

and_statement Block

A logical rule statement used to combine other rule statements with AND logic. You provide more than one statement within the and_statement.

The and_statement block supports the following arguments:

byte_match_statement Block

The byte match statement provides the bytes to search for, the location in requests that you want AWS WAF to search, and other settings. The bytes to search for are typically a string that corresponds with ASCII characters.

The byte_match_statement block supports the following arguments:

geo_match_statement Block

The geo_match_statement block supports the following arguments:

ip_set_reference_statement Block

A rule statement used to detect web requests coming from particular IP addresses or address ranges. To use this, create an aws_wafv2_ip_set that specifies the addresses you want to detect, then use the ARN of that set in this statement.

The ip_set_reference_statement block supports the following arguments:

label_match_statement Block

The label_match_statement block supports the following arguments:

managed_rule_group_statement Block

A rule statement used to run the rules that are defined in a managed rule group.

You can't nest a managed_rule_group_statement, for example for use inside a not_statement or or_statement. It can only be referenced as a top-level statement within a rule.

The managed_rule_group_statement block supports the following arguments:

not_statement Block

A logical rule statement used to negate the results of another rule statement. You provide one statement within the not_statement.

The not_statement block supports the following arguments:

or_statement Block

A logical rule statement used to combine other rule statements with OR logic. You provide more than one statement within the or_statement.

The or_statement block supports the following arguments:

rate_based_statement Block

A rate-based rule tracks the rate of requests for each originating IP address, and triggers the rule action when the rate exceeds a limit that you specify on the number of requests in any 5-minute time span. You can use this to put a temporary block on requests from an IP address that is sending excessive requests. See the documentation for more information.

You can't nest a rate_based_statement, for example for use inside a not_statement or or_statement. It can only be referenced as a top-level statement within a rule.

The rate_based_statement block supports the following arguments:

regex_match_statement Block

A rule statement used to search web request components for a match against a single regular expression.

The regex_match_statement block supports the following arguments:

regex_pattern_set_reference_statement Block

A rule statement used to search web request components for matches with regular expressions. To use this, create a aws_wafv2_regex_pattern_set that specifies the expressions that you want to detect, then use the ARN of that set in this statement. A web request matches the pattern set rule statement if the request component matches any of the patterns in the set.

The regex_pattern_set_reference_statement block supports the following arguments:

rule_group_reference_statement Block

A rule statement used to run the rules that are defined in an WAFv2 Rule Group or aws_wafv2_rule_group resource.

You can't nest a rule_group_reference_statement, for example for use inside a not_statement or or_statement. It can only be referenced as a top-level statement within a rule.

The rule_group_reference_statement block supports the following arguments:

size_constraint_statement Block

A rule statement that uses a comparison operator to compare a number of bytes against the size of a request component. AWS WAFv2 inspects up to the first 8192 bytes (8 KB) of a request body, and when inspecting the request URI Path, the slash / in the URI counts as one character.

The size_constraint_statement block supports the following arguments:

sqli_match_statement Block

An SQL injection match condition identifies the part of web requests, such as the URI or the query string, that you want AWS WAF to inspect. Later in the process, when you create a web ACL, you specify whether to allow or block requests that appear to contain malicious SQL code.

The sqli_match_statement block supports the following arguments:

xss_match_statement Block

The XSS match statement provides the location in requests that you want AWS WAF to search and text transformations to use on the search area before AWS WAF searches for character sequences that are likely to be malicious strings.

The xss_match_statement block supports the following arguments:

rule_action_override Block

The rule_action_override block supports the following arguments:

managed_rule_group_configs Block

The managed_rule_group_configs block support the following arguments:

aws_managed_rules_bot_control_rule_set Block

aws_managed_rules_acfp_rule_set Block

aws_managed_rules_atp_rule_set Block

request_inspection Block

address_fields Block

email_field Block

password_field Block

phone_number_fields Block

username_field Block

response_inspection Block

body_contains Block

header Block

json Block

status_code Block

field_to_match Block

The part of a web request that you want AWS WAF to inspect. Include the single field_to_match type that you want to inspect, with additional specifications as needed, according to the type. You specify a single request component in field_to_match for each rule statement that requires it. To inspect more than one component of a web request, create a separate rule statement for each component. See the documentation for more details.

The field_to_match block supports the following arguments:

forwarded_ip_config Block

The configuration for inspecting IP addresses in an HTTP header that you specify, instead of using the IP address that's reported by the web request origin. Commonly, this is the X-Forwarded-For (XFF) header, but you can specify any header name. If the specified header isn't present in the request, AWS WAFv2 doesn't apply the rule to the web request at all. AWS WAFv2 only evaluates the first IP address found in the specified HTTP header.

The forwarded_ip_config block supports the following arguments:

ip_set_forwarded_ip_config Block

The configuration for inspecting IP addresses in an HTTP header that you specify, instead of using the IP address that's reported by the web request origin. Commonly, this is the X-Forwarded-For (XFF) header, but you can specify any header name.

The ip_set_forwarded_ip_config block supports the following arguments:

header_order Block

Inspect a string containing the list of the request's header names, ordered as they appear in the web request that AWS WAF receives for inspection. AWS WAF generates the string and then uses that as the field to match component in its inspection. AWS WAF separates the header names in the string using colons and no added spaces, for example host:user-agent:accept:authorization:referer.

The header_order block supports the following arguments:

headers Block

Inspect the request headers.

The headers block supports the following arguments:

ja3_fingerprint Block

The ja3_fingerprint block supports the following arguments:

json_body Block

The json_body block supports the following arguments:

single_header Block

Inspect a single header. Provide the name of the header to inspect, for example, User-Agent or Referer (provided as lowercase strings).

The single_header block supports the following arguments:

single_query_argument Block

Inspect a single query argument. Provide the name of the query argument to inspect, such as UserName or SalesRegion (provided as lowercase strings).

The single_query_argument block supports the following arguments:

body Block

The body block supports the following arguments:

cookies Block

Inspect the cookies in the web request. You can specify the parts of the cookies to inspect and you can narrow the set of cookies to inspect by including or excluding specific keys. This is used to indicate the web request component to inspect, in the FieldToMatch specification.

The cookies block supports the following arguments:

text_transformation Block

The text_transformation block supports the following arguments:

visibility_config Block

The visibility_config block supports the following arguments:

captcha_config Block

The captcha_config block supports the following arguments:

challenge_config Block

The challenge_config block supports the following arguments:

immunity_time_property Block

The immunity_time_property block supports the following arguments:

request_body Block

The request_body block supports the following arguments:

cloudfront Block

The cloudfront block supports the following arguments:

custom_key Block

Aggregate the request counts using one or more web request components as the aggregate keys. With this option, you must specify the aggregate keys in the custom_keys block. To aggregate on only the IP address or only the forwarded IP address, don't use custom keys. Instead, set the aggregate_key_type to IP or FORWARDED_IP.

The custom_key block supports the following arguments:

Use the value of a cookie in the request as an aggregate key. Each distinct value in the cookie contributes to the aggregation instance. If you use a single cookie as your custom key, then each value fully defines an aggregation instance.

The cookie block supports the following arguments:

RateLimit forwarded_ip Block

Use the first IP address in an HTTP header as an aggregate key. Each distinct forwarded IP address contributes to the aggregation instance. When you specify an IP or forwarded IP in the custom key settings, you must also specify at least one other key to use. You can aggregate on only the forwarded IP address by specifying FORWARDED_IP in your rate-based statement's aggregate_key_type. With this option, you must specify the header to use in the rate-based rule's forwarded_ip_config block.

The forwarded_ip block is configured as an empty block {}.

RateLimit http_method Block

Use the request's HTTP method as an aggregate key. Each distinct HTTP method contributes to the aggregation instance. If you use just the HTTP method as your custom key, then each method fully defines an aggregation instance.

The http_method block is configured as an empty block {}.

RateLimit header Block

Use the value of a header in the request as an aggregate key. Each distinct value in the header contributes to the aggregation instance. If you use a single header as your custom key, then each value fully defines an aggregation instance.

The header block supports the following arguments:

RateLimit ip Block

Use the request's originating IP address as an aggregate key. Each distinct IP address contributes to the aggregation instance. When you specify an IP or forwarded IP in the custom key settings, you must also specify at least one other key to use. You can aggregate on only the IP address by specifying IP in your rate-based statement's aggregate_key_type.

The ip block is configured as an empty block {}.

RateLimit label_namespace Block

Use the specified label namespace as an aggregate key. Each distinct fully qualified label name that has the specified label namespace contributes to the aggregation instance. If you use just one label namespace as your custom key, then each label name fully defines an aggregation instance. This uses only labels that have been added to the request by rules that are evaluated before this rate-based rule in the web ACL. For information about label namespaces and names, see Label syntax and naming requirements (https://docs.aws.amazon.com/waf/latest/developerguide/waf-rule-label-requirements.html) in the WAF Developer Guide.

The label_namespace block supports the following arguments:

RateLimit query_argument Block

Use the specified query argument as an aggregate key. Each distinct value for the named query argument contributes to the aggregation instance. If you use a single query argument as your custom key, then each value fully defines an aggregation instance.

The query_argument block supports the following arguments:

RateLimit query_string Block

Use the request's query string as an aggregate key. Each distinct string contributes to the aggregation instance. If you use just the query string as your custom key, then each string fully defines an aggregation instance.

The query_string block supports the following arguments:

RateLimit uri_path Block

Use the request's URI path as an aggregate key. Each distinct URI path contributes to the aggregation instance. If you use just the URI path as your custom key, then each URI path fully defines an aggregation instance.

The uri_path block supports the following arguments:

Attribute Reference

This resource exports the following attributes in addition to the arguments above:

Import

In Terraform v1.5.0 and later, use an import block to import WAFv2 Web ACLs using ID/Name/Scope. For example:

import {
  to = aws_wafv2_web_acl.example
  id = "a1b2c3d4-d5f6-7777-8888-9999aaaabbbbcccc/example/REGIONAL"
}

Using terraform import, import WAFv2 Web ACLs using ID/Name/Scope. For example:

% terraform import aws_wafv2_web_acl.example a1b2c3d4-d5f6-7777-8888-9999aaaabbbbcccc/example/REGIONAL