AWS WAF v2
AWS WAF v2 (Web Application Firewall) protects web applications from common web exploits and malicious traffic patterns.
Modules
- Web ACLs – Define WAF rules with support for templates, AWS managed rule groups, and custom rules.
- Associations – Attach WAF Web ACLs to Application Load Balancers.
- Logging Configurations – Configure WAF logging to CloudWatch with filtering and field redaction.
Architecture
The WAF implementation follows a template-based approach:
- Templates define baseline security rule sets (e.g.,
sapphire_managed_ruleset_v1) - Web ACLs reference templates and override specific rules as needed
- Associations attach Web ACLs to load balancers
- Logging captures blocked/allowed requests with optional filtering
Quick Start
wafv2_web_acl = {
EpicManagedRulesWebACL = {
description = "WAF for Epic ingress traffic"
rule_set_template = "managed_ruleset_v1"
visibility_config = {
cloudwatch_metrics_enabled = true
metric_name = "EpicManagedRulesWebACL"
sampled_requests_enabled = true
}
}
}
# Attach to load balancer
wafv2_web_acl_association = {
default-waf = {
web_acl = "EpicManagedRulesWebACL"
lb = "default"
}
}
# Configure logging
wafv2_web_acl_logging_configuration = {
waf-logging = {
web_acl = "EpicManagedRulesWebACL"
log_destination = "WAFLogGroup"
}
}
Features
Template-Based Configuration
- Pre-configured rule sets with AWS managed rules
- Easy override mechanism for customization
- Consistent security baselines across environments
Flexible Rule Management
- Shallow merge: Override entire rules while keeping other template rules
- Remove rules: Set rule to
nullto exclude from template - Add custom rules: Define new rules not in template
Comprehensive Logging
- Filter logs by action (ALLOW, BLOCK, COUNT, etc.)
- Redact sensitive fields (headers, query strings, URI paths)
- Automatic resource replacement when clearing redacted fields
Merge Behavior
When using templates with rule overrides:
# Template defines:
rules = {
ip_reputation = { ... complete rule definition ... }
sqli = { ... }
xss = { ... }
}
# You override:
rules = {
ip_reputation = { ... complete override ... }
}
# Result: ip_reputation uses YOUR definition, sqli and xss use TEMPLATE definitions
Important: Overriding a rule requires providing the COMPLETE rule definition. Terraform's merge() performs shallow merging—nested objects are replaced entirely, not deep-merged.