Skip to content

Commit

Permalink
Merge pull request #13961 from terraform-providers/b-wafv2-web-acl-re…
Browse files Browse the repository at this point in the history
…cursion

resource/wafv2_web_acl: add additional nested statement level
  • Loading branch information
anGie44 authored Jun 29, 2020
2 parents 04baa55 + 41fc7fa commit 081bf57
Show file tree
Hide file tree
Showing 2 changed files with 261 additions and 7 deletions.
14 changes: 7 additions & 7 deletions aws/resource_aws_wafv2_web_acl.go
Original file line number Diff line number Diff line change
Expand Up @@ -338,14 +338,14 @@ func wafv2WebACLRootStatementSchema(level int) *schema.Schema {
MaxItems: 1,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"and_statement": wafv2StatementSchema(level - 1),
"and_statement": wafv2StatementSchema(level),
"byte_match_statement": wafv2ByteMatchStatementSchema(),
"geo_match_statement": wafv2GeoMatchStatementSchema(),
"ip_set_reference_statement": wafv2IpSetReferenceStatementSchema(),
"managed_rule_group_statement": wafv2ManagedRuleGroupStatementSchema(),
"not_statement": wafv2StatementSchema(level - 1),
"or_statement": wafv2StatementSchema(level - 1),
"rate_based_statement": wafv2RateBasedStatementSchema(level - 1),
"not_statement": wafv2StatementSchema(level),
"or_statement": wafv2StatementSchema(level),
"rate_based_statement": wafv2RateBasedStatementSchema(level),
"regex_pattern_set_reference_statement": wafv2RegexPatternSetReferenceStatementSchema(),
"rule_group_reference_statement": wafv2RuleGroupReferenceStatementSchema(),
"size_constraint_statement": wafv2SizeConstraintSchema(),
Expand Down Expand Up @@ -429,12 +429,12 @@ func wafv2ScopeDownStatementSchema(level int) *schema.Schema {
MaxItems: 1,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"and_statement": wafv2StatementSchema(level - 1),
"and_statement": wafv2StatementSchema(level),
"byte_match_statement": wafv2ByteMatchStatementSchema(),
"geo_match_statement": wafv2GeoMatchStatementSchema(),
"ip_set_reference_statement": wafv2IpSetReferenceStatementSchema(),
"not_statement": wafv2StatementSchema(level - 1),
"or_statement": wafv2StatementSchema(level - 1),
"not_statement": wafv2StatementSchema(level),
"or_statement": wafv2StatementSchema(level),
"regex_pattern_set_reference_statement": wafv2RegexPatternSetReferenceStatementSchema(),
"size_constraint_statement": wafv2SizeConstraintSchema(),
"sqli_match_statement": wafv2SqliMatchStatementSchema(),
Expand Down
254 changes: 254 additions & 0 deletions aws/resource_aws_wafv2_web_acl_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package aws

import (
"fmt"
"github.com/terraform-providers/terraform-provider-aws/aws/internal/tfawsresource"
"regexp"
"testing"

Expand Down Expand Up @@ -436,6 +437,91 @@ func TestAccAwsWafv2WebACL_Tags(t *testing.T) {
})
}

// Reference: https://github.com/terraform-providers/terraform-provider-aws/issues/13862
func TestAccAwsWafv2WebACL_MaxNestedRateBasedStatements(t *testing.T) {
var v wafv2.WebACL
webACLName := acctest.RandomWithPrefix("tf-acc-test")
resourceName := "aws_wafv2_web_acl.test"

resource.ParallelTest(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: testAccCheckAwsWafv2WebACLDestroy,
Steps: []resource.TestStep{
{
Config: testAccAwsWafv2WebACLConfig_multipleNestedRateBasedStatements(webACLName),
Check: resource.ComposeTestCheckFunc(
testAccCheckAwsWafv2WebACLExists(resourceName, &v),
testAccMatchResourceAttrRegionalARN(resourceName, "arn", "wafv2", regexp.MustCompile(`regional/webacl/.+$`)),
resource.TestCheckResourceAttr(resourceName, "name", webACLName),
resource.TestCheckResourceAttr(resourceName, "rule.#", "1"),
tfawsresource.TestCheckTypeSetElemNestedAttrs(resourceName, "rule.*", map[string]string{
"statement.#": "1",
"statement.0.rate_based_statement.#": "1",
"statement.0.rate_based_statement.0.limit": "300",
"statement.0.rate_based_statement.0.aggregate_key_type": "IP",
"statement.0.rate_based_statement.0.scope_down_statement.#": "1",
"statement.0.rate_based_statement.0.scope_down_statement.0.not_statement.#": "1",
"statement.0.rate_based_statement.0.scope_down_statement.0.not_statement.0.statement.#": "1",
"statement.0.rate_based_statement.0.scope_down_statement.0.not_statement.0.statement.0.or_statement.#": "1",
"statement.0.rate_based_statement.0.scope_down_statement.0.not_statement.0.statement.0.or_statement.0.statement.#": "2",
"statement.0.rate_based_statement.0.scope_down_statement.0.not_statement.0.statement.0.or_statement.0.statement.0.regex_pattern_set_reference_statement.#": "1",
"statement.0.rate_based_statement.0.scope_down_statement.0.not_statement.0.statement.0.or_statement.0.statement.1.ip_set_reference_statement.#": "1",
}),
),
},
{
ResourceName: resourceName,
ImportState: true,
ImportStateVerify: true,
ImportStateIdFunc: testAccAwsWafv2WebACLImportStateIdFunc(resourceName),
},
},
})
}

func TestAccAwsWafv2WebACL_MaxNestedOperatorStatements(t *testing.T) {
var v wafv2.WebACL
webACLName := acctest.RandomWithPrefix("tf-acc-test")
resourceName := "aws_wafv2_web_acl.test"

resource.ParallelTest(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: testAccCheckAwsWafv2WebACLDestroy,
Steps: []resource.TestStep{
{
Config: testAccAwsWafv2WebACLConfig_multipleNestedOperatorStatements(webACLName),
Check: resource.ComposeTestCheckFunc(
testAccCheckAwsWafv2WebACLExists(resourceName, &v),
testAccMatchResourceAttrRegionalARN(resourceName, "arn", "wafv2", regexp.MustCompile(`regional/webacl/.+$`)),
resource.TestCheckResourceAttr(resourceName, "name", webACLName),
resource.TestCheckResourceAttr(resourceName, "rule.#", "1"),
tfawsresource.TestCheckTypeSetElemNestedAttrs(resourceName, "rule.*", map[string]string{
"statement.#": "1",
"statement.0.and_statement.#": "1",
"statement.0.and_statement.0.statement.#": "2",
"statement.0.and_statement.0.statement.0.not_statement.#": "1",
"statement.0.and_statement.0.statement.0.not_statement.0.statement.#": "1",
"statement.0.and_statement.0.statement.0.not_statement.0.statement.0.or_statement.#": "1",
"statement.0.and_statement.0.statement.0.not_statement.0.statement.0.or_statement.0.statement.#": "2",
"statement.0.and_statement.0.statement.0.not_statement.0.statement.0.or_statement.0.statement.0.regex_pattern_set_reference_statement.#": "1",
"statement.0.and_statement.0.statement.0.not_statement.0.statement.0.or_statement.0.statement.1.ip_set_reference_statement.#": "1",
"statement.0.and_statement.0.statement.1.geo_match_statement.#": "1",
"statement.0.and_statement.0.statement.1.geo_match_statement.0.country_codes.0": "NL",
}),
),
},
{
ResourceName: resourceName,
ImportState: true,
ImportStateVerify: true,
ImportStateIdFunc: testAccAwsWafv2WebACLImportStateIdFunc(resourceName),
},
},
})
}

// Calculates the index which isn't static because ARN is generated as part of the test
func computeWafv2RuleGroupRefStatementIndex(r *wafv2.WebACL, idx *int, e []interface{}) resource.TestCheckFunc {
return func(s *terraform.State) error {
Expand Down Expand Up @@ -1108,6 +1194,174 @@ resource "aws_wafv2_web_acl" "test" {
`, name, tag1Key, tag1Value, tag2Key, tag2Value)
}

func testAccAwsWafv2WebACLConfig_multipleNestedRateBasedStatements(name string) string {
return fmt.Sprintf(`
resource "aws_wafv2_regex_pattern_set" "test" {
name = "%[1]s"
scope = "REGIONAL"
regular_expression {
regex_string = "one"
}
}
resource "aws_wafv2_ip_set" "test" {
name = "%[1]s"
scope = "REGIONAL"
ip_address_version = "IPV4"
addresses = ["1.2.3.4/32", "5.6.7.8/32"]
}
resource "aws_wafv2_web_acl" "test" {
name = "%[1]s"
description = "%[1]s"
scope = "REGIONAL"
default_action {
allow {}
}
rule {
name = "rule"
priority = 0
action {
block {}
}
statement {
rate_based_statement {
limit = 300
aggregate_key_type = "IP"
scope_down_statement {
not_statement {
statement {
or_statement {
statement {
regex_pattern_set_reference_statement {
arn = aws_wafv2_regex_pattern_set.test.arn
field_to_match {
uri_path {}
}
text_transformation {
type = "LOWERCASE"
priority = 1
}
}
}
statement {
ip_set_reference_statement {
arn = aws_wafv2_ip_set.test.arn
}
}
}
}
}
}
}
}
visibility_config {
cloudwatch_metrics_enabled = false
metric_name = "rule"
sampled_requests_enabled = false
}
}
visibility_config {
cloudwatch_metrics_enabled = false
metric_name = "waf"
sampled_requests_enabled = false
}
}
`, name)
}

func testAccAwsWafv2WebACLConfig_multipleNestedOperatorStatements(name string) string {
return fmt.Sprintf(`
resource "aws_wafv2_regex_pattern_set" "test" {
name = "%[1]s"
scope = "REGIONAL"
regular_expression {
regex_string = "one"
}
}
resource "aws_wafv2_ip_set" "test" {
name = "%[1]s"
scope = "REGIONAL"
ip_address_version = "IPV4"
addresses = ["1.2.3.4/32", "5.6.7.8/32"]
}
resource "aws_wafv2_web_acl" "test" {
name = "%[1]s"
description = "%[1]s"
scope = "REGIONAL"
default_action {
allow {}
}
rule {
name = "rule"
priority = 0
action {
block {}
}
statement {
and_statement {
statement {
not_statement {
statement {
or_statement {
statement {
regex_pattern_set_reference_statement {
arn = aws_wafv2_regex_pattern_set.test.arn
field_to_match {
uri_path {}
}
text_transformation {
type = "LOWERCASE"
priority = 1
}
}
}
statement {
ip_set_reference_statement {
arn = aws_wafv2_ip_set.test.arn
}
}
}
}
}
}
statement {
geo_match_statement {
country_codes = ["NL"]
}
}
}
}
visibility_config {
cloudwatch_metrics_enabled = false
metric_name = "rule"
sampled_requests_enabled = false
}
}
visibility_config {
cloudwatch_metrics_enabled = false
metric_name = "waf"
sampled_requests_enabled = false
}
}
`, name)
}

func testAccAwsWafv2WebACLImportStateIdFunc(resourceName string) resource.ImportStateIdFunc {
return func(s *terraform.State) (string, error) {
rs, ok := s.RootModule().Resources[resourceName]
Expand Down

0 comments on commit 081bf57

Please sign in to comment.