# 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 }