Infrastructure improvements: - Update CloudFront distribution with ACM certificate support - Enable custom domain aliases when certificate is available - Add comprehensive WAF outputs for CrowdSec integration - Update variables with current configuration defaults New files: - Add CrowdSec WAF integration documentation - Add sync script for CrowdSec to WAF automation - Add MCP configuration for development tools Configuration updates: - Align Terraform configuration with deployed state - Enable ACM certificate and Route53 DNS by default - Maintain HTTP-only origin protocol for compatibility 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
221 lines
5.2 KiB
HCL
221 lines
5.2 KiB
HCL
# Security Group for ALB/ELB (if needed for origin server)
|
|
resource "aws_security_group" "alb" {
|
|
count = var.create_alb_security_group ? 1 : 0
|
|
name = "${var.project_name}-${var.environment}-alb-sg"
|
|
description = "Security group for ALB"
|
|
vpc_id = var.enable_cloudformation_stack ? data.aws_cloudformation_stack.network[0].outputs["VPCId"] : null
|
|
|
|
# HTTP access from anywhere
|
|
ingress {
|
|
description = "HTTP"
|
|
from_port = 80
|
|
to_port = 80
|
|
protocol = "tcp"
|
|
cidr_blocks = ["0.0.0.0/0"]
|
|
}
|
|
|
|
# HTTPS access from anywhere
|
|
ingress {
|
|
description = "HTTPS"
|
|
from_port = 443
|
|
to_port = 443
|
|
protocol = "tcp"
|
|
cidr_blocks = ["0.0.0.0/0"]
|
|
}
|
|
|
|
# All outbound traffic
|
|
egress {
|
|
from_port = 0
|
|
to_port = 0
|
|
protocol = "-1"
|
|
cidr_blocks = ["0.0.0.0/0"]
|
|
}
|
|
|
|
tags = {
|
|
Name = "${var.project_name}-${var.environment}-alb-sg"
|
|
}
|
|
}
|
|
|
|
# Security Group for EC2 instances (if needed)
|
|
resource "aws_security_group" "web" {
|
|
count = var.create_web_security_group ? 1 : 0
|
|
name = "${var.project_name}-${var.environment}-web-sg"
|
|
description = "Security group for web servers"
|
|
vpc_id = var.enable_cloudformation_stack ? data.aws_cloudformation_stack.network[0].outputs["VPCId"] : null
|
|
|
|
# HTTP access from ALB security group
|
|
ingress {
|
|
description = "HTTP from ALB"
|
|
from_port = 80
|
|
to_port = 80
|
|
protocol = "tcp"
|
|
security_groups = var.create_alb_security_group ? [aws_security_group.alb[0].id] : []
|
|
}
|
|
|
|
# HTTPS access from ALB security group
|
|
ingress {
|
|
description = "HTTPS from ALB"
|
|
from_port = 443
|
|
to_port = 443
|
|
protocol = "tcp"
|
|
security_groups = var.create_alb_security_group ? [aws_security_group.alb[0].id] : []
|
|
}
|
|
|
|
# SSH access (restrict as needed)
|
|
ingress {
|
|
description = "SSH"
|
|
from_port = 22
|
|
to_port = 22
|
|
protocol = "tcp"
|
|
cidr_blocks = var.ssh_allowed_cidrs
|
|
}
|
|
|
|
# All outbound traffic
|
|
egress {
|
|
from_port = 0
|
|
to_port = 0
|
|
protocol = "-1"
|
|
cidr_blocks = ["0.0.0.0/0"]
|
|
}
|
|
|
|
tags = {
|
|
Name = "${var.project_name}-${var.environment}-web-sg"
|
|
}
|
|
}
|
|
|
|
# IP Set for blocked IPs
|
|
resource "aws_wafv2_ip_set" "blocked_ips" {
|
|
provider = aws.us_east_1 # CloudFront WAF must be in us-east-1
|
|
count = var.enable_waf ? 1 : 0
|
|
name = "${var.project_name}-${var.environment}-blocked-ips"
|
|
description = "IP addresses to be blocked"
|
|
scope = "CLOUDFRONT"
|
|
ip_address_version = "IPV4"
|
|
|
|
# Start with empty set - IPs can be added via AWS CLI or Console
|
|
addresses = []
|
|
|
|
tags = {
|
|
Name = "${var.project_name}-${var.environment}-blocked-ips"
|
|
}
|
|
}
|
|
|
|
|
|
# WAF Web ACL for CloudFront (optional)
|
|
resource "aws_wafv2_web_acl" "cloudfront" {
|
|
provider = aws.us_east_1 # CloudFront WAF must be in us-east-1
|
|
count = var.enable_waf ? 1 : 0
|
|
name = "${var.project_name}-${var.environment}-waf"
|
|
scope = "CLOUDFRONT"
|
|
|
|
default_action {
|
|
allow {}
|
|
}
|
|
|
|
# Block IPs in blocked list
|
|
rule {
|
|
name = "BlockedIPsRule"
|
|
priority = 1
|
|
|
|
action {
|
|
block {}
|
|
}
|
|
|
|
statement {
|
|
ip_set_reference_statement {
|
|
arn = aws_wafv2_ip_set.blocked_ips[0].arn
|
|
}
|
|
}
|
|
|
|
visibility_config {
|
|
cloudwatch_metrics_enabled = true
|
|
metric_name = "BlockedIPsRule"
|
|
sampled_requests_enabled = true
|
|
}
|
|
}
|
|
|
|
# Rate limiting rule (original setting restored)
|
|
rule {
|
|
name = "RateLimitRule"
|
|
priority = 2
|
|
|
|
action {
|
|
block {}
|
|
}
|
|
|
|
statement {
|
|
rate_based_statement {
|
|
limit = 10000
|
|
aggregate_key_type = "IP"
|
|
}
|
|
}
|
|
|
|
visibility_config {
|
|
cloudwatch_metrics_enabled = true
|
|
metric_name = "RateLimitRule"
|
|
sampled_requests_enabled = true
|
|
}
|
|
}
|
|
|
|
# AWS Managed Rules - Core Rule Set
|
|
rule {
|
|
name = "AWSManagedRulesCommonRuleSet"
|
|
priority = 3
|
|
|
|
override_action {
|
|
none {}
|
|
}
|
|
|
|
statement {
|
|
managed_rule_group_statement {
|
|
name = "AWSManagedRulesCommonRuleSet"
|
|
vendor_name = "AWS"
|
|
}
|
|
}
|
|
|
|
visibility_config {
|
|
cloudwatch_metrics_enabled = true
|
|
metric_name = "CommonRuleSetMetric"
|
|
sampled_requests_enabled = true
|
|
}
|
|
}
|
|
|
|
# AWS Managed Rules - Known Bad Inputs
|
|
rule {
|
|
name = "AWSManagedRulesKnownBadInputsRuleSet"
|
|
priority = 4
|
|
|
|
override_action {
|
|
none {}
|
|
}
|
|
|
|
statement {
|
|
managed_rule_group_statement {
|
|
name = "AWSManagedRulesKnownBadInputsRuleSet"
|
|
vendor_name = "AWS"
|
|
}
|
|
}
|
|
|
|
visibility_config {
|
|
cloudwatch_metrics_enabled = true
|
|
metric_name = "KnownBadInputsRuleSetMetric"
|
|
sampled_requests_enabled = true
|
|
}
|
|
}
|
|
|
|
tags = {
|
|
Name = "${var.project_name}-${var.environment}-waf"
|
|
}
|
|
|
|
visibility_config {
|
|
cloudwatch_metrics_enabled = true
|
|
metric_name = "${var.project_name}-${var.environment}-waf"
|
|
sampled_requests_enabled = true
|
|
}
|
|
}
|
|
|
|
# Data source to get CloudFormation stack outputs (conditional)
|
|
data "aws_cloudformation_stack" "network" {
|
|
count = var.enable_cloudformation_stack ? 1 : 0
|
|
name = aws_cloudformation_stack.network[0].name
|
|
} |