case study · serverless delivery · live

Cloud portfolio infrastructure

The infrastructure behind this portfolio: private static content through CloudFront, a serverless visitor API, and separate OIDC workflows for reviewing and applying Terraform changes.

problem

Make the portfolio itself verifiable infrastructure work

The site needed global HTTPS delivery, no public storage bucket, a small dynamic visitor counter and a deployment path that did not rely on console changes or permanent AWS credentials.

Astro is used only as a static build system. The deployed output is HTML, CSS and minimal JavaScript served from S3 through CloudFront.

architecture

Private origin with a serverless API path

Portfolio architecture: CloudFront serves private S3 content and routes visitor requests to Lambda and DynamoDB
CloudFront serves the private S3 origin through origin access control. A separate behavior routes the visitor endpoint to Lambda, which atomically updates DynamoDB.

Route 53 and ACM provide the custom domain and TLS certificate. CloudFront is the only public delivery layer; direct S3 object access remains blocked.

decisions and tradeoffs

Key design decisions

Static output instead of an application server
Pages are cheap to cache and have no runtime to patch. Dynamic behavior is limited to isolated serverless endpoints.
CloudFront origin access control
The bucket stays private and grants reads only to the distribution, adding policy setup in exchange for removing direct object exposure.
Separate plan and apply workflows
Pull requests can review Terraform changes without receiving apply permissions. Merge-time automation has the narrower deployment role.
OIDC instead of static AWS secrets
GitHub assumes short-lived roles subject to repository and branch conditions; no AWS access key is stored in Actions.

what broke

Preview paths exposed base-path assumptions

The same static build is served both at the production root and under a preview prefix. Root-relative links worked in production but escaped the preview path. Centralizing URL generation around Astro's configured base fixed navigation, resume and asset links.

The visitor script is generated with the deployed API URL by Terraform. A local Astro preview therefore cannot report a real count unless that deployment-generated script is injected; the interface intentionally shows a neutral placeholder rather than a fabricated value.

delivery

Infrastructure and content move together