Skip to content
← All projects

This Site, and Its Infrastructure

Angular prerendered to static HTML, on AWS I provisioned and deploy myself.

Period
2026
Stack
Angular · Terraform · AWS · CloudFront · Lambda · GitHub Actions

Problem

For most of my career a DevOps team owned deployment. I could describe what happened after a merge, but I had never built it. That is a real gap, and reading about IAM is not the same as being denied by it.

Approach

Angular prerenders every route to its own HTML file, so the site is genuinely static and crawlable rather than an empty shell that fills in later. It is served from a private S3 bucket through CloudFront, with the contact form's API Gateway attached to the same distribution under /api/* — same origin, so there is no CORS to configure. Terraform provisions all of it in two stages, since the bucket holding Terraform's own state has to be created before Terraform can use it. GitHub Actions deploys on push using OIDC, so no AWS credentials are stored anywhere.

Outcome

Live, deploying in under a minute on push, with no long-lived credentials. The most instructive part was the failure: GitHub's OIDC token identifies a repository by numeric ID rather than by name, so a trust policy that looked correct in every console view rejected every deploy. Finding it meant reading the actual denied request in CloudTrail.