hashicorp / terraform-provider-aws

The AWS Provider enables Terraform to manage AWS resources.
https://registry.terraform.io/providers/hashicorp/aws
Mozilla Public License 2.0
9.66k stars 9.03k forks source link

[Bug]: Attempting to attach AWS-AWSManagedRulesATPRuleSet to an existing WAF result in panic error. #31739

Open mahela-aws opened 1 year ago

mahela-aws commented 1 year ago

Terraform Core Version

v1.3.7

AWS Provider Version

v4.67.0

Affected Resource(s)

aws_wafv2_web_acl

Expected Behavior

we should be able apply this configuration successfully.

Actual Behavior

it's throwing below error when applying

Relevant Error/Panic Output Snippet

"method":cty.List(cty.EmptyObject), "query_string":cty.List(cty.EmptyObject), "single_header":cty.List(cty.Object(map[string]cty.Type{"name":cty.String})),
│ "single_query_argument":cty.List(cty.Object(map[string]cty.Type{"name":cty.String})), "uri_path":cty.List(cty.EmptyObject)})),
│ "text_transformation":cty.Set(cty.Object(map[string]cty.Type{"priority":cty.Number, "type":cty.String}))})),
│ "rule_group_reference_statement":cty.ListValEmpty(cty.Object(map[string]cty.Type{"arn":cty.String, "excluded_rule":cty.List(cty.Object(map[string]cty.Type{"name":cty.String}))})),
│ "size_constraint_statement":cty.ListValEmpty(cty.Object(map[string]cty.Type{"comparison_operator":cty.String,
│ "field_to_match":cty.List(cty.Object(map[string]cty.Type{"all_query_arguments":cty.List(cty.EmptyObject), "body":cty.List(cty.Object(map[string]cty.Type{"oversize_handling":cty.String})),
│ "cookies":cty.List(cty.Object(map[string]cty.Type{"match_pattern":cty.List(cty.Object(map[string]cty.Type{"all":cty.List(cty.EmptyObject), "excluded_cookies":cty.List(cty.String),
│ "included_cookies":cty.List(cty.String)})), "match_scope":cty.String, "oversize_handling":cty.String})),
│ "headers":cty.List(cty.Object(map[string]cty.Type{"match_pattern":cty.List(cty.Object(map[string]cty.Type{"all":cty.List(cty.EmptyObject), "excluded_headers":cty.List(cty.String),
│ "included_headers":cty.List(cty.String)})), "match_scope":cty.String, "oversize_handling":cty.String})), "json_body":cty.List(cty.Object(map[string]cty.Type{"invalid_fallback_behavior":cty.String,
│ "match_pattern":cty.List(cty.Object(map[string]cty.Type{"all":cty.List(cty.EmptyObject), "included_paths":cty.List(cty.String)})), "match_scope":cty.String, "oversize_handling":cty.String})),
│ "method":cty.List(cty.EmptyObject), "query_string":cty.List(cty.EmptyObject), "single_header":cty.List(cty.Object(map[string]cty.Type{"name":cty.String})),
│ "single_query_argument":cty.List(cty.Object(map[string]cty.Type{"name":cty.String})), "uri_path":cty.List(cty.EmptyObject)})), "size":cty.Number,
│ "text_transformation":cty.Set(cty.Object(map[string]cty.Type{"priority":cty.Number, "type":cty.String}))})),
│ "sqli_match_statement":cty.ListValEmpty(cty.Object(map[string]cty.Type{"field_to_match":cty.List(cty.Object(map[string]cty.Type{"all_query_arguments":cty.List(cty.EmptyObject),
│ "body":cty.List(cty.Object(map[string]cty.Type{"oversize_handling":cty.String})),
│ "cookies":cty.List(cty.Object(map[string]cty.Type{"match_pattern":cty.List(cty.Object(map[string]cty.Type{"all":cty.List(cty.EmptyObject), "excluded_cookies":cty.List(cty.String),
│ "included_cookies":cty.List(cty.String)})), "match_scope":cty.String, "oversize_handling":cty.String})),
│ "headers":cty.List(cty.Object(map[string]cty.Type{"match_pattern":cty.List(cty.Object(map[string]cty.Type{"all":cty.List(cty.EmptyObject), "excluded_headers":cty.List(cty.String),
│ "included_headers":cty.List(cty.String)})), "match_scope":cty.String, "oversize_handling":cty.String})), "json_body":cty.List(cty.Object(map[string]cty.Type{"invalid_fallback_behavior":cty.String,
│ "match_pattern":cty.List(cty.Object(map[string]cty.Type{"all":cty.List(cty.EmptyObject), "included_paths":cty.List(cty.String)})), "match_scope":cty.String, "oversize_handling":cty.String})),
│ "method":cty.List(cty.EmptyObject), "query_string":cty.List(cty.EmptyObject), "single_header":cty.List(cty.Object(map[string]cty.Type{"name":cty.String})),
│ "single_query_argument":cty.List(cty.Object(map[string]cty.Type{"name":cty.String})), "uri_path":cty.List(cty.EmptyObject)})),
│ "text_transformation":cty.Set(cty.Object(map[string]cty.Type{"priority":cty.Number, "type":cty.String}))})),
│ "xss_match_statement":cty.ListValEmpty(cty.Object(map[string]cty.Type{"field_to_match":cty.List(cty.Object(map[string]cty.Type{"all_query_arguments":cty.List(cty.EmptyObject),
│ "body":cty.List(cty.Object(map[string]cty.Type{"oversize_handling":cty.String})),
│ "cookies":cty.List(cty.Object(map[string]cty.Type{"match_pattern":cty.List(cty.Object(map[string]cty.Type{"all":cty.List(cty.EmptyObject), "excluded_cookies":cty.List(cty.String),
│ "included_cookies":cty.List(cty.String)})), "match_scope":cty.String, "oversize_handling":cty.String})),
│ "headers":cty.List(cty.Object(map[string]cty.Type{"match_pattern":cty.List(cty.Object(map[string]cty.Type{"all":cty.List(cty.EmptyObject), "excluded_headers":cty.List(cty.String),
│ "included_headers":cty.List(cty.String)})), "match_scope":cty.String, "oversize_handling":cty.String})), "json_body":cty.List(cty.Object(map[string]cty.Type{"invalid_fallback_behavior":cty.String,
│ "match_pattern":cty.List(cty.Object(map[string]cty.Type{"all":cty.List(cty.EmptyObject), "included_paths":cty.List(cty.String)})), "match_scope":cty.String, "oversize_handling":cty.String})),
│ "method":cty.List(cty.EmptyObject), "query_string":cty.List(cty.EmptyObject), "single_header":cty.List(cty.Object(map[string]cty.Type{"name":cty.String})),
│ "single_query_argument":cty.List(cty.Object(map[string]cty.Type{"name":cty.String})), "uri_path":cty.List(cty.EmptyObject)})),
│ "text_transformation":cty.Set(cty.Object(map[string]cty.Type{"priority":cty.Number, "type":cty.String}))}))})}),
│ "visibility_config":cty.ListVal([]cty.Value{cty.ObjectVal(map[string]cty.Value{"cloudwatch_metrics_enabled":cty.False, "metric_name":cty.StringVal("buynomicsdevelopmentCommonRuleSet"),
│ "sampled_requests_enabled":cty.True})})}) does not correlate with any element in actual.
│ 
│ This is a bug in the provider, which should be reported in the provider's own issue tracker.

Terraform Configuration Files

resource "aws_wafv2_web_acl" "main" {
  name        = "${lower(var.name)}-webaclv2"
  description = "WAFv2 AWSManagedRules for BNsuite"
  scope       = "REGIONAL"

  default_action {
    allow {}
  }

rule {
    name     = "KeycloakAuthRestrictions"
    priority = 1

    override_action {
      none {}
    }

    statement {
      rule_group_reference_statement {
        arn = aws_wafv2_rule_group.keycloak_auth_restrictions.arn
      }
    }

    visibility_config {
      cloudwatch_metrics_enabled = false
      metric_name                = "${lower(var.custom_metric_name)}KeycloakAuthRestrictions"
      sampled_requests_enabled   = true
    }
  }

rule {
    name     = "AccountTakeOverPrevention"
    priority = 2

    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 = var.bn_context == "review" ? "/admin-${var.bn_context}" : "/admin"

            request_inspection {
              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                = "${lower(var.custom_metric_name)}AccountTakeOverPrevention"
      sampled_requests_enabled   = true
    }
  }

  tags = {
    Terraform = "True"
    Name      = "${lower(var.name)}-webaclv2"
  }

  visibility_config {
    cloudwatch_metrics_enabled = false
    metric_name                = "${lower(var.custom_metric_name)}Default"
    sampled_requests_enabled   = true
  }
}

Steps to Reproduce

try to apply this code, it should throw the given error

Debug Output

No response

Panic Output

 "method":cty.List(cty.EmptyObject), "query_string":cty.List(cty.EmptyObject), "single_header":cty.List(cty.Object(map[string]cty.Type{"name":cty.String})),
│ "single_query_argument":cty.List(cty.Object(map[string]cty.Type{"name":cty.String})), "uri_path":cty.List(cty.EmptyObject)})),
│ "text_transformation":cty.Set(cty.Object(map[string]cty.Type{"priority":cty.Number, "type":cty.String}))})),
│ "rule_group_reference_statement":cty.ListValEmpty(cty.Object(map[string]cty.Type{"arn":cty.String, "excluded_rule":cty.List(cty.Object(map[string]cty.Type{"name":cty.String}))})),
│ "size_constraint_statement":cty.ListValEmpty(cty.Object(map[string]cty.Type{"comparison_operator":cty.String,
│ "field_to_match":cty.List(cty.Object(map[string]cty.Type{"all_query_arguments":cty.List(cty.EmptyObject), "body":cty.List(cty.Object(map[string]cty.Type{"oversize_handling":cty.String})),
│ "cookies":cty.List(cty.Object(map[string]cty.Type{"match_pattern":cty.List(cty.Object(map[string]cty.Type{"all":cty.List(cty.EmptyObject), "excluded_cookies":cty.List(cty.String),
│ "included_cookies":cty.List(cty.String)})), "match_scope":cty.String, "oversize_handling":cty.String})),
│ "headers":cty.List(cty.Object(map[string]cty.Type{"match_pattern":cty.List(cty.Object(map[string]cty.Type{"all":cty.List(cty.EmptyObject), "excluded_headers":cty.List(cty.String),
│ "included_headers":cty.List(cty.String)})), "match_scope":cty.String, "oversize_handling":cty.String})), "json_body":cty.List(cty.Object(map[string]cty.Type{"invalid_fallback_behavior":cty.String,
│ "match_pattern":cty.List(cty.Object(map[string]cty.Type{"all":cty.List(cty.EmptyObject), "included_paths":cty.List(cty.String)})), "match_scope":cty.String, "oversize_handling":cty.String})),
│ "method":cty.List(cty.EmptyObject), "query_string":cty.List(cty.EmptyObject), "single_header":cty.List(cty.Object(map[string]cty.Type{"name":cty.String})),
│ "single_query_argument":cty.List(cty.Object(map[string]cty.Type{"name":cty.String})), "uri_path":cty.List(cty.EmptyObject)})), "size":cty.Number,
│ "text_transformation":cty.Set(cty.Object(map[string]cty.Type{"priority":cty.Number, "type":cty.String}))})),
│ "sqli_match_statement":cty.ListValEmpty(cty.Object(map[string]cty.Type{"field_to_match":cty.List(cty.Object(map[string]cty.Type{"all_query_arguments":cty.List(cty.EmptyObject),
│ "body":cty.List(cty.Object(map[string]cty.Type{"oversize_handling":cty.String})),
│ "cookies":cty.List(cty.Object(map[string]cty.Type{"match_pattern":cty.List(cty.Object(map[string]cty.Type{"all":cty.List(cty.EmptyObject), "excluded_cookies":cty.List(cty.String),
│ "included_cookies":cty.List(cty.String)})), "match_scope":cty.String, "oversize_handling":cty.String})),
│ "headers":cty.List(cty.Object(map[string]cty.Type{"match_pattern":cty.List(cty.Object(map[string]cty.Type{"all":cty.List(cty.EmptyObject), "excluded_headers":cty.List(cty.String),
│ "included_headers":cty.List(cty.String)})), "match_scope":cty.String, "oversize_handling":cty.String})), "json_body":cty.List(cty.Object(map[string]cty.Type{"invalid_fallback_behavior":cty.String,
│ "match_pattern":cty.List(cty.Object(map[string]cty.Type{"all":cty.List(cty.EmptyObject), "included_paths":cty.List(cty.String)})), "match_scope":cty.String, "oversize_handling":cty.String})),
│ "method":cty.List(cty.EmptyObject), "query_string":cty.List(cty.EmptyObject), "single_header":cty.List(cty.Object(map[string]cty.Type{"name":cty.String})),
│ "single_query_argument":cty.List(cty.Object(map[string]cty.Type{"name":cty.String})), "uri_path":cty.List(cty.EmptyObject)})),
│ "text_transformation":cty.Set(cty.Object(map[string]cty.Type{"priority":cty.Number, "type":cty.String}))})),
│ "xss_match_statement":cty.ListValEmpty(cty.Object(map[string]cty.Type{"field_to_match":cty.List(cty.Object(map[string]cty.Type{"all_query_arguments":cty.List(cty.EmptyObject),
│ "body":cty.List(cty.Object(map[string]cty.Type{"oversize_handling":cty.String})),
│ "cookies":cty.List(cty.Object(map[string]cty.Type{"match_pattern":cty.List(cty.Object(map[string]cty.Type{"all":cty.List(cty.EmptyObject), "excluded_cookies":cty.List(cty.String),
│ "included_cookies":cty.List(cty.String)})), "match_scope":cty.String, "oversize_handling":cty.String})),
│ "headers":cty.List(cty.Object(map[string]cty.Type{"match_pattern":cty.List(cty.Object(map[string]cty.Type{"all":cty.List(cty.EmptyObject), "excluded_headers":cty.List(cty.String),
│ "included_headers":cty.List(cty.String)})), "match_scope":cty.String, "oversize_handling":cty.String})), "json_body":cty.List(cty.Object(map[string]cty.Type{"invalid_fallback_behavior":cty.String,
│ "match_pattern":cty.List(cty.Object(map[string]cty.Type{"all":cty.List(cty.EmptyObject), "included_paths":cty.List(cty.String)})), "match_scope":cty.String, "oversize_handling":cty.String})),
│ "method":cty.List(cty.EmptyObject), "query_string":cty.List(cty.EmptyObject), "single_header":cty.List(cty.Object(map[string]cty.Type{"name":cty.String})),
│ "single_query_argument":cty.List(cty.Object(map[string]cty.Type{"name":cty.String})), "uri_path":cty.List(cty.EmptyObject)})),
│ "text_transformation":cty.Set(cty.Object(map[string]cty.Type{"priority":cty.Number, "type":cty.String}))}))})}),
│ "visibility_config":cty.ListVal([]cty.Value{cty.ObjectVal(map[string]cty.Value{"cloudwatch_metrics_enabled":cty.False, "metric_name":cty.StringVal("buynomicsdevelopmentCommonRuleSet"),
│ "sampled_requests_enabled":cty.True})})}) does not correlate with any element in actual.
│ 
│ This is a bug in the provider, which should be reported in the provider's own issue tracker.

Important Factoids

No response

References

No response

Would you like to implement a fix?

None

github-actions[bot] commented 1 year ago

Community Note

Voting for Prioritization

Volunteering to Work on This Issue

Dogers commented 1 year ago

Just leaving a note to say I've hit something similar with 1.3.x and the 5.0 provider, that per #30080 was resolved (or at least worked around) by using TF 1.4.6

mahela-aws commented 1 year ago

@Dogers I have tried to upgrade the terraform version to see if that works, but no luck

Plan: 1 to add, 0 to change, 0 to destroy.
aws_wafv2_web_acl.main: Creating...
╷
│ Error: creating WAFv2 WebACL (buynomics-dev2-webaclv2): WAFInvalidOperationException: Your request contains fields that belong to a feature you are not allowed to use.
│ 
│   with aws_wafv2_web_acl.main,
│   on main.tf line 21, in resource "aws_wafv2_web_acl" "main":
│   21: resource "aws_wafv2_web_acl" "main" {
│ 
╵

╭─ ~/buynomics-code/base-infrastructure/test feat/DOM-165-waf-atp !1 ?1 ···························································································· 11s AWS development 05:23:22 pm ─╮
╰─❯ terraform --version                                                                                                                                                                              ─╯
Terraform v1.4.6
on darwin_arm64
+ provider registry.terraform.io/hashicorp/aws v5.1.0
Dogers commented 1 year ago

Sounds like you're using third party rules? Might be worth checking they're correctly signed up in the account?

mahela-aws commented 1 year ago

@Dogers what do you mean by a third party rule ? all the existing rules were working just fine, only thing causing the error is when I'm trying to add the below rule

rule {
    name     = "AccountTakeOverPrevention"
    priority = 2

    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 = var.bn_context == "review" ? "/admin-${var.bn_context}" : "/admin"

            request_inspection {
              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                = "${lower(var.custom_metric_name)}AccountTakeOverPrevention"
      sampled_requests_enabled   = true
    }
  }
samlatunji commented 7 months ago

Running terraform for this rule aws_managed_rules_acfp_rule_set in a rule group throws up error of invalid code block and feature not support. Invalid operation. Any help on this please?

WAFInvalidOperationException: Your request contains fields that belong to a feature you are not allowed to use. │ │ with aws_wafv2_web_acl.waf_acl, │ on main.tf line 1, in resource "aws_wafv2_web_acl" "waf_acl": │ 1: resource "aws_wafv2_web_acl" "waf_acl" {