AWS WAF terraform

https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/wafv2_web_acl.html

https://dev.to/aws-builders/how-to-setup-aws-waf-v2-21f1

AWSのWAFとCloudFrontをTerraformで導入してみました 2022

マネージドルール

override_action と rule_action_override でカスタマイズする

sample

locals {
  name   = "test"
}

resource "aws_wafv2_web_acl" "this" {
  name  = local.name
  scope = "REGIONAL"

  default_action {
    allow {}
  }

  visibility_config {
    cloudwatch_metrics_enabled = true
    metric_name                = "${local.name}-waf"
    sampled_requests_enabled   = true
  }

  rule {
    name     = "AWSManagedRulesCommonRuleSet"
    priority = 10

    # マネージドルールのアクションを上書きしない → block
    override_action {
      none {}
    }

    statement {
      managed_rule_group_statement {
        name        = "AWSManagedRulesCommonRuleSet"
        vendor_name = "AWS"

        # NoUserAgent_HEADER は block → count に変更
        rule_action_override {
          action_to_use {
            count {}
          }
          name = "NoUserAgent_HEADER"
        }
    }

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

WAF ログ ロギング

https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/wafv2_web_acl_logging_configuration

AWSのWAFとCloudFrontをTerraformで導入してみました 2022

WAFログをCloudWatch Logsへ出力する際の例です。WAFログのロググループ名は"aws-waf-logs-*"とする必要があること、CloudFront向けWAFについてはus-east-1にすることを忘れがちなのでご注意ください。
TerraformでAWS WAFを構築するサンプルコードを書いてみた - Qiita 2022

WAFのログ有効化&ロギングフィルターで必要なログのみS3へ直接保存(Terraform) - Qiita 2022

retention_in_days - (Optional) Specifies the number of days you want to retain log events in the specified log group. Possible values are: 1, 3, 5, 7, 14, 30, 60, 90, 120, 150, 180, 365, 400, 545, 731, 1096, 1827, 2192, 2557, 2922, 3288, 3653, and 0. If you select 0, the events in the log group are always retained and never expire.

https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/cloudwatch_log_group

resource "aws_wafv2_web_acl" "this" {
...
}

resource "aws_wafv2_web_acl_association" "this" {
  resource_arn = aws_alb.this.arn
  web_acl_arn  = aws_wafv2_web_acl.this.arn
}

resource "aws_cloudwatch_log_group" "waf" {
  name              = "aws-waf-logs-${local.name}"
  retention_in_days = 30
}

resource "aws_wafv2_web_acl_logging_configuration" "this" {
  log_destination_configs = [aws_cloudwatch_log_group.waf.arn]
  resource_arn            = aws_wafv2_web_acl.this.arn

  logging_filter {
    default_behavior = "KEEP"

    filter {
      behavior = "DROP"
      condition {
        action_condition {
          action = "ALLOW"
        }
      }
      requirement = "MEETS_ANY"
    }
  }
}