简体   繁体   中英

Dynamically create multiple WAF rules with Terraform

I've got a piece of Terraform code that creates a Web ACL with a set of rules in AWS.

provider "aws" {
  region = "eu-west-2"
}

resource "aws_wafv2_web_acl" "foo" {
    name        = "foo"
    description = "foo"
    scope       = "REGIONAL"
    default_action {
        block {}
    }
    rule {
      name = "AWS-AWSManagedRulesLinuxRuleSet"
      priority = 0
      override_action {
        count {}
      }
      statement {
        managed_rule_group_statement {
          name = "AWS-AWSManagedRulesLinuxRuleSet"
          vendor_name = "AWS"
        }
      }
      visibility_config {
        cloudwatch_metrics_enabled = false 
        metric_name                 = "foo_name"
        sampled_requests_enabled   = false
      }
    }
    rule {
      name = "AWS-AWSManagedRulesSQLiRuleSet"
      priority = 1
      override_action {
        count {}
      }
      statement {
        managed_rule_group_statement {
          name = "AWS-AWSManagedRulesSQLiRuleSet"
          vendor_name = "AWS"
        }
      }
      visibility_config {
        cloudwatch_metrics_enabled = false
        metric_name                = "foo_name"
        sampled_requests_enabled   = false
      }
    }
    tags = {
      Tag1 = "Value1"
    }
    visibility_config {
      metric_name = "foo"
      sampled_requests_enabled = false
      cloudwatch_metrics_enabled = false
    }   
}

This works fine, but adding more rules means that my code starts to turn into somewhat of a monolith.

Is there a way to create multiple rules in Terraform using dynamic_blocks or for_each or something else, in a way that looks cleaner and dry?

You use dynamic in combination with for_each like this:

Define a variable:

variable "rules" {
  type    = list
  default = [
    {
      name = "AWS-AWSManagedRulesLinuxRuleSet"
      priority = 0
      managed_rule_group_statement_name = "AWS-AWSManagedRulesLinuxRuleSet"
      managed_rule_group_statement_vendor_name = "AWS"
      metric_name = "foo_name"
    },
    {
      name = "AWS-AWSManagedRulesSQLiRuleSet"
      priority = 1
      managed_rule_group_statement_name = "AWS-AWSManagedRulesSQLiRuleSet"
      managed_rule_group_statement_vendor_name = "AWS"
      metric_name = "foo_name"
    }
  ]
}

Then use it in the resource:

dynamic "rule" {
  for_each = toset(var.rules)

  content {
    name = rule.value.name
    priority = rule.value.priority
    override_action {
      count {}
    }
    statement {
      managed_rule_group_statement {
        name = rule.value.managed_rule_group_statement_name
        vendor_name = rule.value.managed_rule_group_statement_vendor_name
      }
    }
    visibility_config {
      cloudwatch_metrics_enabled = false
      metric_name                = rule.value.metric_name
      sampled_requests_enabled   = false
    }
  }
}

(Note: Obviously this replaces your previous rule blocks. See also the documentation about Dynamic Blocks for more information.)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM