Skip to content

Commit 9bd0c70

Browse files
authored
feat(tf): Add support for custom WAF rule groups in CloudFront module (#3)
1 parent 3fa7ed6 commit 9bd0c70

3 files changed

Lines changed: 71 additions & 3 deletions

File tree

deployments/terraform/modules/aws/cloudfront/validation.tf

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -131,12 +131,16 @@ resource "terraform_data" "route53_domain_alias_validation" {
131131
# =============================================================================
132132

133133
resource "terraform_data" "waf_rule_priority_validation" {
134-
count = var.waf_enabled && length(var.waf_managed_rules) > 0 ? 1 : 0
134+
count = var.waf_enabled && length(var.waf_managed_rules) + length(var.waf_custom_rule_groups) > 0 ? 1 : 0
135135

136136
lifecycle {
137137
precondition {
138-
condition = length(var.waf_managed_rules) == length(distinct([for r in var.waf_managed_rules : r.priority]))
139-
error_message = "All WAF managed rules must have unique priorities."
138+
condition = length(
139+
concat([for r in var.waf_managed_rules : r.priority], [for r in var.waf_custom_rule_groups : r.priority])
140+
) == length(distinct(
141+
concat([for r in var.waf_managed_rules : r.priority], [for r in var.waf_custom_rule_groups : r.priority])
142+
))
143+
error_message = "All WAF rule priorities must be unique across managed rules and custom rule groups."
140144
}
141145
}
142146
}

deployments/terraform/modules/aws/cloudfront/variables.tf

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -700,6 +700,39 @@ variable "waf_sampled_requests_enabled" {
700700
default = true
701701
}
702702

703+
variable "waf_custom_rule_groups" {
704+
description = <<-EOT
705+
Custom WAF rule group ARNs to include in the Web ACL.
706+
707+
Each entry references a pre-existing aws_wafv2_rule_group. The rule group's
708+
rules are evaluated inline within the Web ACL at the specified priority.
709+
710+
name: stable identifier used in the WAF rule name and CloudWatch metric name.
711+
override_action: "none" to use rule actions as-is, "count" to only count matches.
712+
EOT
713+
type = list(object({
714+
name = string
715+
arn = string
716+
priority = number
717+
override_action = optional(string, "none")
718+
}))
719+
default = []
720+
721+
validation {
722+
condition = alltrue([
723+
for rg in var.waf_custom_rule_groups : rg.priority >= 0 && rg.priority <= 2147483647
724+
])
725+
error_message = "All custom rule group priorities must be between 0 and 2147483647."
726+
}
727+
728+
validation {
729+
condition = alltrue([
730+
for rg in var.waf_custom_rule_groups : contains(["none", "count"], coalesce(rg.override_action, "none"))
731+
])
732+
error_message = "Custom rule group override_action must be 'none' or 'count'."
733+
}
734+
}
735+
703736
# ========================================
704737
# Route53 DNS
705738
# ========================================

deployments/terraform/modules/aws/cloudfront/waf.tf

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -193,6 +193,37 @@ resource "aws_wafv2_web_acl" "main" {
193193
}
194194
}
195195

196+
dynamic "rule" {
197+
for_each = var.waf_custom_rule_groups
198+
content {
199+
name = "custom-${rule.value.name}"
200+
priority = rule.value.priority
201+
202+
override_action {
203+
dynamic "none" {
204+
for_each = coalesce(rule.value.override_action, "none") == "none" ? [1] : []
205+
content {}
206+
}
207+
dynamic "count" {
208+
for_each = coalesce(rule.value.override_action, "none") == "count" ? [1] : []
209+
content {}
210+
}
211+
}
212+
213+
statement {
214+
rule_group_reference_statement {
215+
arn = rule.value.arn
216+
}
217+
}
218+
219+
visibility_config {
220+
cloudwatch_metrics_enabled = var.waf_cloudwatch_metrics_enabled
221+
metric_name = "${local.resource_prefix}-custom-${rule.value.name}"
222+
sampled_requests_enabled = var.waf_sampled_requests_enabled
223+
}
224+
}
225+
}
226+
196227
visibility_config {
197228
cloudwatch_metrics_enabled = var.waf_cloudwatch_metrics_enabled
198229
metric_name = "${local.resource_prefix}-waf"

0 commit comments

Comments
 (0)