6
votes

I created the following AWS WAF ACL and I want to associate it with my ALB using terraform. is there any way I can do it using terraform? I want to block all requests except the ones that have secret key using amazon web service web application firewalls, aws waf. For that purpose, I created byte_set, aws rule and access control lists, ACL

    resource "aws_alb" "app" {
    ............
  }


#waf
resource "aws_waf_byte_match_set" "byte_set" {
  name = "tf_waf_byte_match_set"

  byte_match_tuples {
    text_transformation   = "NONE"
    target_string         = "${var.secret_key}"
    positional_constraint = "EXACTLY"

    field_to_match {
      type = "HEADER"
      data = "referer"
    }
  }
}

resource "aws_waf_rule" "wafrule" {
  depends_on  = ["aws_waf_byte_match_set.byte_set"]
  name        = "tfWAFRule"
  metric_name = "tfWAFRule"

  predicates {
    data_id = "${aws_waf_byte_match_set.byte_set.id}"
    negated = false
    type    = "ByteMatch"
  }
}

resource "aws_waf_web_acl" "waf_acl" {
  depends_on  = ["aws_waf_byte_match_set.byte_set", "aws_waf_rule.wafrule"]
  name        = "tfWebACL"
  metric_name = "tfWebACL"

  default_action {
    type = "BLOCK"
  }

  rules {
    action {
      type = "ALLOW"
    }

    priority = 1
    rule_id  = "${aws_waf_rule.wafrule.id}"
  }
}
3

3 Answers

4
votes

You can associate a WAF with ALB (Application Load Balancer) and with CloudFront, you cannot associate with an ELB (Classic Elastic Load Balancer).

To associate with ALB this is the piece of code

resource "aws_wafregional_web_acl_association" "foo" {
  resource_arn = "${aws_alb.foo.arn}"
  web_acl_id = "${aws_wafregional_web_acl.foo.id}"
}

taken from the official documentation

3
votes

Sure, here is an example of the resource for the WAFv2 (I recommend to use this one) with a rate limit example rule and the association with an ALB:

########### This is the creation of an WAFv2 (Web ACL) and a example rate limit rule

resource "aws_wafv2_web_acl" "my_web_acl" {
  name  = "my-web-acl"
  scope = "REGIONAL"

  default_action {
    allow {}
  }

  rule {
    name     = "RateLimit"
    priority = 1

    action {
      block {}
    }

    statement {

      rate_based_statement {
        aggregate_key_type = "IP"
        limit              = 500
      }
    }

    visibility_config {
      cloudwatch_metrics_enabled = true
      metric_name                = "RateLimit"
      sampled_requests_enabled   = true
    }
  }

  visibility_config {
    cloudwatch_metrics_enabled = false
    metric_name                = "my-web-acl"
    sampled_requests_enabled   = false
  }
}

########### This is the association code

resource "aws_wafv2_web_acl_association" "web_acl_association_my_lb" {
  resource_arn = aws_lb.my_lb.arn
  web_acl_arn  = aws_wafv2_web_acl.my_web_acl.arn
}