Files
Filamenteka/terraform/cloudfront-frontend.tf
DaX c0ca1e4bb3 Fix CloudFront domain configuration and add missing color definitions
- Configure CloudFront to accept filamenteka.rs with ACM SSL certificate
- Add Cloudflare Transform Rule for Host header rewriting
- Fix Matte Grass Green hex code (#7CB342 -> #61C680)
- Add PLA Wood colors: Ochre Yellow, White Oak, Clay Brown
- Add script for managing color definitions in database
2025-10-31 02:40:03 +01:00

185 lines
5.3 KiB
HCL

# S3 bucket for static website hosting
resource "aws_s3_bucket" "frontend" {
bucket = "${var.app_name}-frontend"
tags = {
Name = "${var.app_name}-frontend"
Environment = var.environment
}
}
# S3 bucket website configuration
resource "aws_s3_bucket_website_configuration" "frontend" {
bucket = aws_s3_bucket.frontend.id
index_document {
suffix = "index.html"
}
error_document {
key = "404.html"
}
}
# S3 bucket public access block (we'll use CloudFront OAC instead)
resource "aws_s3_bucket_public_access_block" "frontend" {
bucket = aws_s3_bucket.frontend.id
block_public_acls = true
block_public_policy = true
ignore_public_acls = true
restrict_public_buckets = true
}
# CloudFront Origin Access Control
resource "aws_cloudfront_origin_access_control" "frontend" {
name = "${var.app_name}-frontend-oac"
description = "OAC for ${var.app_name} frontend"
origin_access_control_origin_type = "s3"
signing_behavior = "always"
signing_protocol = "sigv4"
}
# CloudFront distribution
resource "aws_cloudfront_distribution" "frontend" {
enabled = true
is_ipv6_enabled = true
comment = "${var.app_name} frontend"
default_root_object = "index.html"
price_class = "PriceClass_100" # US, Canada, Europe only (cheapest)
# No aliases - Cloudflare will proxy to CloudFront's default domain
# aliases = var.domain_name != "" ? [var.domain_name, "www.${var.domain_name}"] : []
origin {
domain_name = aws_s3_bucket.frontend.bucket_regional_domain_name
origin_id = "S3-${aws_s3_bucket.frontend.id}"
origin_access_control_id = aws_cloudfront_origin_access_control.frontend.id
}
default_cache_behavior {
allowed_methods = ["GET", "HEAD", "OPTIONS"]
cached_methods = ["GET", "HEAD"]
target_origin_id = "S3-${aws_s3_bucket.frontend.id}"
forwarded_values {
query_string = false
cookies {
forward = "none"
}
}
viewer_protocol_policy = "redirect-to-https"
min_ttl = 0
default_ttl = 3600 # 1 hour
max_ttl = 86400 # 24 hours
compress = true
}
# Custom error responses for SPA routing
custom_error_response {
error_code = 404
response_code = 200
response_page_path = "/index.html"
error_caching_min_ttl = 300
}
custom_error_response {
error_code = 403
response_code = 200
response_page_path = "/index.html"
error_caching_min_ttl = 300
}
restrictions {
geo_restriction {
restriction_type = "none"
}
}
# Use default CloudFront certificate (we'll handle SSL via Cloudflare)
viewer_certificate {
cloudfront_default_certificate = true
# If you want CloudFront SSL, add ACM certificate here
# acm_certificate_arn = aws_acm_certificate.cert.arn
# ssl_support_method = "sni-only"
# minimum_protocol_version = "TLSv1.2_2021"
}
tags = {
Name = "${var.app_name}-frontend"
Environment = var.environment
}
}
# S3 bucket policy to allow CloudFront OAC access
resource "aws_s3_bucket_policy" "frontend" {
bucket = aws_s3_bucket.frontend.id
policy = jsonencode({
Version = "2012-10-17"
Statement = [
{
Sid = "AllowCloudFrontServicePrincipal"
Effect = "Allow"
Principal = {
Service = "cloudfront.amazonaws.com"
}
Action = "s3:GetObject"
Resource = "${aws_s3_bucket.frontend.arn}/*"
Condition = {
StringEquals = {
"AWS:SourceArn" = aws_cloudfront_distribution.frontend.arn
}
}
}
]
})
}
# Cloudflare DNS records for frontend
resource "cloudflare_record" "frontend_root" {
count = var.domain_name != "" && var.cloudflare_api_token != "" ? 1 : 0
zone_id = data.cloudflare_zone.domain[0].id
name = "@"
type = "CNAME"
value = aws_cloudfront_distribution.frontend.domain_name
ttl = 1
proxied = true # Enable Cloudflare proxy for SSL and caching
comment = "CloudFront distribution for frontend"
}
resource "cloudflare_record" "frontend_www" {
count = var.domain_name != "" && var.cloudflare_api_token != "" ? 1 : 0
zone_id = data.cloudflare_zone.domain[0].id
name = "www"
type = "CNAME"
value = aws_cloudfront_distribution.frontend.domain_name
ttl = 1
proxied = true # Enable Cloudflare proxy for SSL and caching
comment = "CloudFront distribution for frontend (www)"
}
# Cloudflare Transform Rule to rewrite Host header for CloudFront
resource "cloudflare_ruleset" "frontend_host_header_rewrite" {
count = var.domain_name != "" && var.cloudflare_api_token != "" ? 1 : 0
zone_id = data.cloudflare_zone.domain[0].id
name = "Rewrite Host header for CloudFront"
kind = "zone"
phase = "http_request_late_transform"
rules {
action = "rewrite"
expression = "(http.host eq \"${var.domain_name}\" or http.host eq \"www.${var.domain_name}\")"
description = "Rewrite Host header to CloudFront domain"
action_parameters {
headers {
name = "Host"
operation = "set"
value = aws_cloudfront_distribution.frontend.domain_name
}
}
}
}