2026-08-07 15:09:54 -04:00
|
|
|
resource "aws_cloudfront_origin_access_control" "site" {
|
|
|
|
|
name = "seahaven-site-prod-oac"
|
|
|
|
|
description = "OAC for seahaven-site-prod origin bucket"
|
|
|
|
|
origin_access_control_origin_type = "s3"
|
|
|
|
|
signing_behavior = "always"
|
|
|
|
|
signing_protocol = "sigv4"
|
|
|
|
|
}
|
|
|
|
|
|
2026-08-15 01:26:23 -04:00
|
|
|
# Viewer-request rewrite so pretty URLs (/sustainability/) fetch S3 key
|
|
|
|
|
# sustainability/index.html. default_root_object only covers "/". PLAT-105.
|
|
|
|
|
resource "aws_cloudfront_function" "directory_index" {
|
|
|
|
|
name = "seahaven-site-prod-directory-index"
|
|
|
|
|
runtime = "cloudfront-js-2.0"
|
|
|
|
|
comment = "Rewrite directory and extensionless URIs to index.html"
|
|
|
|
|
publish = true
|
|
|
|
|
code = file("${path.module}/functions/directory-index.js")
|
|
|
|
|
}
|
|
|
|
|
|
2026-08-07 17:21:46 -04:00
|
|
|
# Shared CloudFront WAF (M-17) published by org-baseline stack seahaven-app-web-acl
|
|
|
|
|
# in this account (PLAT-92). aws_cloudfront_distribution.web_acl_id takes the
|
|
|
|
|
# WAFv2 ARN despite the attribute name.
|
|
|
|
|
data "aws_ssm_parameter" "app_web_acl_arn" {
|
|
|
|
|
name = "/seahaven/waf/app-web-acl-arn"
|
|
|
|
|
}
|
|
|
|
|
|
2026-08-07 15:09:54 -04:00
|
|
|
resource "aws_cloudfront_distribution" "site" {
|
|
|
|
|
enabled = true
|
|
|
|
|
is_ipv6_enabled = true
|
|
|
|
|
comment = "Sea Haven marketing site (seahaven-site-prod)"
|
|
|
|
|
default_root_object = "index.html"
|
|
|
|
|
price_class = "PriceClass_100"
|
|
|
|
|
http_version = "http2and3"
|
|
|
|
|
aliases = var.attach_apex_alias ? [var.domain_name] : []
|
2026-08-07 17:21:46 -04:00
|
|
|
web_acl_id = data.aws_ssm_parameter.app_web_acl_arn.value
|
2026-08-07 15:09:54 -04:00
|
|
|
|
|
|
|
|
origin {
|
|
|
|
|
domain_name = aws_s3_bucket.origin.bucket_regional_domain_name
|
|
|
|
|
origin_id = "s3-seahaven-site-prod"
|
|
|
|
|
origin_access_control_id = aws_cloudfront_origin_access_control.site.id
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
default_cache_behavior {
|
|
|
|
|
target_origin_id = "s3-seahaven-site-prod"
|
|
|
|
|
viewer_protocol_policy = "redirect-to-https"
|
|
|
|
|
allowed_methods = ["GET", "HEAD", "OPTIONS"]
|
|
|
|
|
cached_methods = ["GET", "HEAD"]
|
|
|
|
|
compress = true
|
|
|
|
|
|
|
|
|
|
# Origin Cache-Control from GHA sync is honored (assets max-age=86400; html no-cache).
|
|
|
|
|
cache_policy_id = "658327ea-f89d-4fab-a63d-7e88639e58f6" # CachingOptimized
|
2026-08-15 01:26:23 -04:00
|
|
|
|
|
|
|
|
function_association {
|
|
|
|
|
event_type = "viewer-request"
|
|
|
|
|
function_arn = aws_cloudfront_function.directory_index.arn
|
|
|
|
|
}
|
2026-08-07 15:09:54 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
custom_error_response {
|
|
|
|
|
error_code = 403
|
|
|
|
|
response_code = 404
|
|
|
|
|
response_page_path = "/404.html"
|
|
|
|
|
error_caching_min_ttl = 300
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
custom_error_response {
|
|
|
|
|
error_code = 404
|
|
|
|
|
response_code = 404
|
|
|
|
|
response_page_path = "/404.html"
|
|
|
|
|
error_caching_min_ttl = 300
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
restrictions {
|
|
|
|
|
geo_restriction {
|
|
|
|
|
restriction_type = "none"
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
dynamic "viewer_certificate" {
|
|
|
|
|
for_each = var.attach_apex_alias ? [1] : []
|
|
|
|
|
content {
|
|
|
|
|
acm_certificate_arn = aws_acm_certificate.site.arn
|
|
|
|
|
ssl_support_method = "sni-only"
|
|
|
|
|
minimum_protocol_version = "TLSv1.2_2021"
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
dynamic "viewer_certificate" {
|
|
|
|
|
for_each = var.attach_apex_alias ? [] : [1]
|
|
|
|
|
content {
|
|
|
|
|
cloudfront_default_certificate = true
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|