AWS aws_wafv2_web_acl rule and_statement syntax in terraform

I am trying to write terraform code to create a WAF rule to block any POST request that does not have Content-Type: application/json.

Terraform documentation is not clear on the syntax. Below is my code:

  rule {
    name     = "my-block-post-requests-content-type-application-json"
    priority = 7

    action {
      block {}
    }

    statement {
      and_statement {
        statements = [
          {
            byte_match_statement = {
              field_to_match {
                method {}
              }
              positional_constraint = CONTAINS
              search_string         = POST
              text_transformation {
                priority = 0
                type     = NONE
              }
            }
          },
          {
            not_statement {
              statement {
                byte_match_statement {
                  search_string = "application/json"
                  field_to_match {
                    single_header {
                      name = "content-type"
                    }
                  }
                  positional_constraint = CONTAINS
                  search_string         = POST
                  text_transformation {
                    priority = 0
                    type     = NONE
                  }
                }
              }
            }
          }
        ]
      }
    }

    visibility_config {
      cloudwatch_metrics_enabled = true
      metric_name                = "${var.solution}-${var.environment}-block-post-requests-content-type-application-json"
      sampled_requests_enabled   = true
    }
  }

But it is giving this error:

Terraform can determine which modules and providers need to be installed.
╷
│ Error: Missing key/value separator
│ 
│ On waf.tf line 249: Expected an equals sign ("=") to mark the beginning of
│ the attribute value.
╵

Error: Process completed with exit code 1.

Line 249 is the actually line no 14 in the previous code block. It is also showing red squiggly(wavy) lines in Vscode editor. I would highly appreciate any hint on resolving this error.

Here is the snapshot of the rule(which I created manually) from AWS console:
I am trying to write terraform code to create a WAF rule to block any POST request that does not have Content-Type: application/json.

Terraform documentation is not clear on the syntax. Below is my code:

  rule {
    name     = "my-block-post-requests-content-type-application-json"
    priority = 7

    action {
      block {}
    }

    statement {
      and_statement {
        statements = [
          {
            byte_match_statement = {
              field_to_match {
                method {}
              }
              positional_constraint = CONTAINS
              search_string         = POST
              text_transformation {
                priority = 0
                type     = NONE
              }
            }
          },
          {
            not_statement {
              statement {
                byte_match_statement {
                  search_string = "application/json"
                  field_to_match {
                    single_header {
                      name = "content-type"
                    }
                  }
                  positional_constraint = CONTAINS
                  search_string         = POST
                  text_transformation {
                    priority = 0
                    type     = NONE
                  }
                }
              }
            }
          }
        ]
      }
    }

    visibility_config {
      cloudwatch_metrics_enabled = true
      metric_name                = "${var.solution}-${var.environment}-block-post-requests-content-type-application-json"
      sampled_requests_enabled   = true
    }
  }

But it is giving this error:

Terraform can determine which modules and providers need to be installed.
╷
│ Error: Missing key/value separator
│ 
│ On waf.tf line 249: Expected an equals sign ("=") to mark the beginning of
│ the attribute value.
╵

Error: Process completed with exit code 1.

Line 249 is the actually line no 14 in the previous code block. It is also showing red squiggly(wavy) lines in Vscode editor. I would highly appreciate any hint on resolving this error.

Here is the snapshot of the rule(which I created manually) from AWS console:

I am trying to write terraform code to create a WAF rule to block any POST request that does not have Content-Type: application/json.

Terraform documentation is not clear on the syntax. Below is my code:

  rule {
    name     = "my-block-post-requests-content-type-application-json"
    priority = 7

    action {
      block {}
    }

    statement {
      and_statement {
        statements = [
          {
            byte_match_statement = {
              field_to_match {
                method {}
              }
              positional_constraint = CONTAINS
              search_string         = POST
              text_transformation {
                priority = 0
                type     = NONE
              }
            }
          },
          {
            not_statement {
              statement {
                byte_match_statement {
                  search_string = "application/json"
                  field_to_match {
                    single_header {
                      name = "content-type"
                    }
                  }
                  positional_constraint = CONTAINS
                  search_string         = POST
                  text_transformation {
                    priority = 0
                    type     = NONE
                  }
                }
              }
            }
          }
        ]
      }
    }

    visibility_config {
      cloudwatch_metrics_enabled = true
      metric_name                = "${var.solution}-${var.environment}-block-post-requests-content-type-application-json"
      sampled_requests_enabled   = true
    }
  }

But it is giving this error:

Terraform can determine which modules and providers need to be installed.
╷
│ Error: Missing key/value separator
│ 
│ On waf.tf line 249: Expected an equals sign ("=") to mark the beginning of
│ the attribute value.
╵

Error: Process completed with exit code 1.

Line 249 is the actually line no 14 in the previous code block. It is also showing red squiggly(wavy) lines in Vscode editor. I would highly appreciate any hint on resolving this error.

The Json text from AWS console for this rule:

{
  "Name": "Block-post-Content-Type-Application-Json",
  "Priority": 8,
  "Statement": {
    "AndStatement": {
      "Statements": [
        {
          "ByteMatchStatement": {
            "SearchString": "POST",
            "FieldToMatch": {
              "Method": {}
            },
            "TextTransformations": [
              {
                "Priority": 0,
                "Type": "NONE"
              }
            ],
            "PositionalConstraint": "CONTAINS"
          }
        },
        {
          "NotStatement": {
            "Statement": {
              "ByteMatchStatement": {
                "SearchString": "application/json",
                "FieldToMatch": {
                  "SingleHeader": {
                    "Name": "content-type"
                  }
                },
                "TextTransformations": [
                  {
                    "Priority": 0,
                    "Type": "NONE"
                  }
                ],
                "PositionalConstraint": "CONTAINS"
              }
            }
          }
        }
      ]
    }
  },
  "Action": {
    "Block": {}
  },
  "VisibilityConfig": {
    "SampledRequestsEnabled": true,
    "CloudWatchMetricsEnabled": true,
    "MetricName": "Block-post-Content-Type-Application-Json"
  }
}

There are various syntax issues with your rule:

  1. There is no statements list argument inside and_statement. Instead you need to use statement blocks to define the statements.
  2. Various string argument values, such as CONTAINS,POST and NONE, need double quotes around them.
  3. There is an extraneous search_string in your byte_match_statement that’s inside the not_statement block.

Here is a working configuration that you can use as a reference:


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

  default_action {
    allow {}
  }

  rule {
    name     = "my-block-post-requests-content-type-application-json"
    priority = 7
    action {
      block {}
    }
    statement {
      and_statement {
        statement {
          byte_match_statement {
            field_to_match {
              method {}
            }
            positional_constraint = "CONTAINS"
            search_string         = "POST"
            text_transformation {
              priority = 0
              type     = "NONE"
            }
          }
        }
        statement {
          not_statement {
            statement {
              byte_match_statement {
                search_string = "application/json"
                field_to_match {
                  single_header {
                    name = "content-type"
                  }
                }
                positional_constraint = "CONTAINS"
                text_transformation {
                  priority = 0
                  type     = "NONE"
                }
              }
            }
          }
        }
      }
    }

    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
  }
}