Self-directed · this site

How this site is built

A static Astro build served from a private S3 bucket through CloudFront, with URL rewriting and security headers at the edge and every resource declared in Terraform.

Discipline
Cloud · IaC
Origin
Private S3
Edge
Lambda@Edge
1
Edge functionTwo event associations
6
Security headersSet at the edge
0
Third-party originsFonts self-hosted

Sheet B

Specification

The shape of it

Static files in a private S3 bucket, served through CloudFront over HTTP/2 and HTTP/3 with an ACM certificate and TLS 1.2 as the minimum (see note 1). DNS is in Route 53. Every resource, including the edge function, the certificate and its validation records, is declared in Terraform.

URLs at the edge

S3 serves objects, not routes. A request for /projects/capstone has no matching object; the object is /projects/capstone/index.html.

A Lambda@Edge function on viewer-request rewrites directory-style and extensionless paths to their index documents. The same function, on viewer-response, sets HSTS, X-Content-Type-Options, X-Frame-Options, Referrer-Policy, Permissions-Policy and a strict Content-Security-Policy (see note 2).

Caching

Content-hashed assets are served with a one-year immutable cache and HTML with max-age=0, must-revalidate, so a deploy shows on the next page load and no unchanged asset is fetched twice.

Verifying what ships

The build fails on a CSP violation (see note 3). Fonts are self-hosted and subset to Latin and Latin Extended, so the policy allows no third-party origin at all.

Sheet C

Notes

3 items

Sheet D

Revisions

What I would change

  1. 01Move the Terraform state to S3 with locking. It is local today, which is fine for one operator and wrong for any number greater than one.

← All work