β οΈ Important Notice: This is sample code for demonstration purposes. Do not use in production environments without proper testing, security review, and customization for your specific requirements.
This Terraform-based solution automatically deploys a comprehensive set of AWS WAF (Web Application Firewall) rules that protect your web applications from common attacks including:
- π SQL Injection attacks
- π·οΈ Cross-Site Scripting (XSS) attempts
- π€ Bad bot traffic and scrapers
- π HTTP flood attacks (DDoS protection)
- π― Scanner and probe activities
- π Reputation-based IP blocking
β
One-Click Deployment - Deploy enterprise-grade WAF protection in minutes
β
Cost-Effective - Automated rules reduce manual security management overhead
β
Scalable - Works with both CloudFront and Application Load Balancers
β
Intelligent - Uses machine learning and threat intelligence for dynamic protection
β
Observable - Built-in CloudWatch dashboards and logging
The solution creates a multi-layered security architecture that includes:
- AWS WAF with intelligent rule sets
- Lambda functions for log analysis and IP management
- Amazon Athena for advanced log querying
- S3 buckets for secure log storage
- CloudWatch dashboards for monitoring
- SNS notifications for security alerts
- DevOps Engineers setting up web application security
- Security Teams implementing automated threat protection
- Cloud Architects designing secure web infrastructures
- Developers protecting applications from common web attacks
Before you begin, ensure you have:
- β AWS Account with appropriate permissions
- β AWS CLI installed and configured (Setup Guide)
- β Terraform >= 1.0.7 installed (Installation Guide)
-
Clone the repository
git clone <repository-url> cd security-automations-for-aws-waf-using-terraform
-
Navigate to the basic example
cd examples/basic
-
Deploy with Terraform
terraform init terraform plan terraform apply
That's it! Your WAF protection is now active. π
The solution supports two deployment targets:
Target | Description | Use Case |
---|---|---|
CloudFront | Global CDN protection | Static websites, global applications |
Application Load Balancer | Regional protection | Dynamic applications, APIs |
Protection Type | Description | Default Status |
---|---|---|
SQL Injection | Blocks malicious SQL queries | β Enabled |
Cross-Site Scripting | Prevents XSS attacks | β Enabled |
HTTP Flood Protection | Rate-based DDoS protection | β Enabled |
Bad Bot Protection | Blocks malicious crawlers | β Enabled |
Scanner Protection | Detects reconnaissance attempts | β Enabled |
Reputation Lists | IP-based threat intelligence | β Enabled |
- π Automatic IP Management - Dynamic blocking and allowlisting
- π Real-time Analytics - CloudWatch dashboards and metrics
- π¨ Alert System - SNS notifications for security events
- ποΈ Log Analysis - Automated parsing with Lambda and Athena
- β° Configurable Retention - Customizable IP blocking periods
Parameter | Description | Default | Options |
---|---|---|---|
end_point |
Deployment target | cloudfront |
cloudfront , ALB |
activate_http_flood_protection_param |
DDoS protection method | yes - AWS WAF rate based rule |
See HTTP Flood Options |
sns_email_param |
Email for security alerts | "" |
Your email address |
yes β AWS Lambda log parser
- Advanced analysis with custom logicyes β Amazon Athena log parser
- SQL-based log analysisyes β AWS WAF rate-based rule
- Built-in rate limiting (recommended)
After deployment, you'll have access to:
- π CloudWatch Dashboard - Real-time security metrics
- π§ Email Alerts - Immediate notification of threats
- ποΈ Centralized Logging - All WAF logs in S3
- π Athena Queries - Advanced log analysis capabilities
Issue: WAFOptimisticLockException
during terraform destroy
Solution:
# Manually delete IPSets in AWS Console, then retry
terraform destroy
Reference: Terraform AWS Provider Issue #21136
For CloudFormation deployment, see the official AWS solution: Security Automations for AWS WAF
Create your own configuration by referencing the modules:
module "waf_security" {
source = "path/to/this/module"
# Your custom configuration
end_point = "ALB"
activate_http_flood_protection_param = "yes - AWS Lambda log parser"
sns_email_param = "[email protected]"
}
This solution incurs costs for:
- AWS WAF requests and rules
- Lambda function executions
- S3 storage for logs
- CloudWatch logs and metrics
- Athena query processing
Use the AWS Pricing Calculator to estimate costs for your specific usage patterns.
- π Least Privilege: Use IAM roles with minimal required permissions
- π Regular Updates: Keep Terraform and AWS provider versions current
- π Monitoring: Set up CloudWatch alarms for unusual activity
- π§ͺ Testing: Test WAF rules in a staging environment first
- π Documentation: Document any custom rule modifications
We welcome contributions! Please see CONTRIBUTING.md for:
- How to report issues
- Development guidelines
- Security vulnerability reporting
This project is licensed under the MIT-0 License - see the LICENSE file for details.
Name | Version |
---|---|
terraform | >= 1.0.7 |
aws | >= 4.0.0, < 5.0.0 |
awscc | >= 0.24.0 |
Name | Version |
---|---|
aws | >= 4.0.0, < 5.0.0 |
random | n/a |
Name | Source | Version |
---|---|---|
dashboard | ./modules/cloudwatch | n/a |
firehouse_athena_source | ./modules/firehose_athena_source | n/a |
ip_retention_resource | ./modules/ip_retention_resource | n/a |
ip_sets | ./modules/waf | n/a |
s3_access_logging_bucket | ./modules/s3 | n/a |
s3_app_log_bucket | ./modules/s3 | n/a |
s3_app_log_bucket_notification | ./modules/s3_notification | n/a |
s3_app_log_bucket_notification_1 | ./modules/s3_notification | n/a |
s3_iam_role | ./modules/iam | n/a |
s3_waf_log_bucket | ./modules/s3 | n/a |
s3_waf_log_bucket_notification | ./modules/s3_notification | n/a |
waf_key | ./modules/kms | n/a |
waf_resource | ./modules/waf_resource | n/a |
Name | Type |
---|---|
aws_cloudformation_stack.trigger_codebuild_stack | resource |
random_id.server | resource |
random_uuid.test | resource |
aws_region.current | data source |
Name | Description | Type | Default | Required |
---|---|---|---|---|
aws_managed_ap_activated | Enable AWS Managed Rules for Anonymous Proxy | bool |
n/a | yes |
aws_managed_api_activated | Enable AWS Managed Rules for API Gateway | bool |
n/a | yes |
aws_managed_crs_activated | Enable AWS Managed Core Rule Set | bool |
n/a | yes |
aws_managed_ipr_activated | Enable AWS Managed IP Reputation Rules | bool |
n/a | yes |
aws_managed_kbi_activated | Enable AWS Managed Known Bad Inputs Rules | bool |
n/a | yes |
aws_managed_linux_activated | Enable AWS Managed Linux Operating System Rules | bool |
n/a | yes |
aws_managed_php_activated | Enable AWS Managed PHP Application Rules | bool |
n/a | yes |
aws_managed_posix_activated | Enable AWS Managed POSIX Operating System Rules | bool |
n/a | yes |
aws_managed_sql_activated | Enable AWS Managed SQL Database Rules | bool |
n/a | yes |
aws_managed_windows_activated | Enable AWS Managed Windows Operating System Rules | bool |
n/a | yes |
aws_managed_wp_activated | Enable AWS Managed WordPress Application Rules | bool |
n/a | yes |
cross_site_scripting_protection_activated | Enable Cross-Site Scripting (XSS) protection | bool |
n/a | yes |
sql_injection_protection_activated | Enable SQL Injection protection | bool |
n/a | yes |
access_logging_bucket_name | Name of existing S3 bucket for access logging | string |
null |
no |
activate_aws_managed_rules_param | Activate AWS Managed Rules | string |
"no" |
no |
activate_bad_bot_protection_param | Activate bad bot protection | string |
"yes" |
no |
activate_cross_site_scripting_protection_param | Activate Cross-Site Scripting protection | string |
"yes" |
no |
activate_http_flood_protection_param | HTTP flood protection method | string |
"yes - AWS WAF rate based rule" |
no |
activate_reputation_lists_protection_param | Activate reputation lists protection | string |
"yes" |
no |
activate_scanners_probes_protection_param | Activate scanners and probes protection | string |
"" |
no |
activate_sql_injection_protection_param | Activate SQL injection protection | string |
"yes" |
no |
api_stage | API Gateway stage name | string |
"ProdStage" |
no |
app_access_log_bucket_logging_enabled | Enable application access log bucket logging | string |
"no" |
no |
athena_query_run_time_schedule_param | Athena query runtime schedule in hours | number |
4 |
no |
bad_bot_protection_activated | Enable bad bot protection | string |
"yes" |
no |
create_access_logging_bucket | Create new access logging bucket | string |
"no" |
no |
end_point | Deployment target: CloudFront or Application Load Balancer | string |
"cloudfront" |
no |
error_threshold | Error threshold for log monitoring | number |
50 |
no |
http_flood_athena_query_group_by_param | HTTP flood Athena query group by parameter | string |
"None" |
no |
ip_retention_period | Enable IP retention period management | string |
"yes" |
no |
ip_retention_period_allowed_param | IP retention period for allowed IPs (minutes, -1 for permanent) | number |
-1 |
no |
ip_retention_period_denied_param | IP retention period for denied IPs (minutes, -1 for permanent) | number |
-1 |
no |
keep_original_data | Keep original data in S3 | string |
"No" |
no |
key_prefix | S3 key prefix for Lambda source code | string |
"security-automations-for-aws-waf" |
no |
reputation_lists_protection_activated | Enable reputation lists protection | string |
"yes" |
no |
request_threshold | Request threshold for log monitoring | number |
100 |
no |
request_threshold_by_country_param | Enable request threshold by country | string |
"no" |
no |
resolve_count | Enable resolve count functionality | string |
"yes" |
no |
retention_in_days | Log retention period in days | number |
365 |
no |
scanners_probes_protection_activated | Enable scanners and probes protection | string |
"yes" |
no |
send_anonymous_usage_data | Send anonymous usage data to AWS | string |
"yes" |
no |
sns_email_param | Email address for SNS notifications | string |
"" |
no |
source_version | Source code version | string |
"v4.0.2" |
no |
sse_algorithm | S3 server-side encryption algorithm | string |
"aws:kms" |
no |
user_agent_extra | Additional user agent string | string |
"AwsSolution/SO0006-tf" |
no |
user_defined_app_access_log_bucket_prefix | Custom prefix for application access logs | string |
"AWSLogs" |
no |
waf_block_period | WAF block period in minutes | number |
240 |
no |
Name | Description |
---|---|
app_access_log_bucket | Name of Application Access Log S3 Bucket |
bad_bot_honey_end_point | URL of bad bot honey pot endpoint |
badbot_honeyendpoint | URL of bad bot honey pot endpoint |
badbot_ipv4_name | Name of bad bot IPv4 IP set |
waf_acl_arn | ARN of the WAF Web ACL |
waf_log_bucket | Name of WAF Log S3 Bucket |
waf_web_acl | Name of the WAF Web ACL |