Initial commit: AWS CloudFront with OpenTofu infrastructure

- Complete CloudFront distribution setup with origin.servidor.it.com
- WAF v2 integration for security protection
- S3 backend for Terraform state management
- CloudFront logging to S3
- HTTP-only origin protocol configuration (resolves 504 Gateway Timeout)
- Comprehensive documentation with deployment guide

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
kappa
2025-09-09 09:08:17 +09:00
commit 210c454359
12 changed files with 1386 additions and 0 deletions

181
security.tf Normal file
View File

@@ -0,0 +1,181 @@
# 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"
}
}
# 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 {}
}
# Rate limiting rule
rule {
name = "RateLimitRule"
priority = 1
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 = 2
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 = 3
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
}