fix(infra): serve pretty URLs via CloudFront directory index (PLAT-105) (#42)
Some checks failed
Deploy / deploy (push) Has been cancelled

S3 OAC has no directory index, so /sustainability/ 404s while
/sustainability/index.html is live. Rewrite directory URIs on viewer-request.
This commit is contained in:
Adam Moussa 2026-08-15 01:26:23 -04:00 • committed by GitHub
parent edc4f3f6b9
commit 7480aee3c8
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 30 additions and 0 deletions

View file

@ -6,6 +6,16 @@ resource "aws_cloudfront_origin_access_control" "site" {
signing_protocol = "sigv4"
}
# 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")
}
# 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.
@ -38,6 +48,11 @@ resource "aws_cloudfront_distribution" "site" {
# Origin Cache-Control from GHA sync is honored (assets max-age=86400; html no-cache).
cache_policy_id = "658327ea-f89d-4fab-a63d-7e88639e58f6" # CachingOptimized
function_association {
event_type = "viewer-request"
function_arn = aws_cloudfront_function.directory_index.arn
}
}
custom_error_response {

View file

@ -0,0 +1,15 @@
function handler(event) {
var request = event.request;
var uri = request.uri;
var last = uri.substring(uri.lastIndexOf("/") + 1);
// S3 OAC has no directory index. default_root_object only covers "/".
// Keep the browser URL; rewrite the origin key to …/index.html.
if (uri.endsWith("/")) {
request.uri = uri + "index.html";
} else if (last.length > 0 && last.indexOf(".") === -1) {
request.uri = uri + "/index.html";
}
return request;
}