Owner / Builder

zachull.com Static Cloud Migration

Replacing a Lightsail WordPress site with a static Astro portfolio served from S3, CloudFront, Route 53, and ACM.

Overview

This project migrated zachull.com from a Lightsail-hosted WordPress site to a static Astro portfolio served through S3, CloudFront, Route 53, and ACM. The project turned my personal site into a practical cloud engineering exercise: private object storage, edge delivery, DNS cutover, TLS, and automated deployment through GitHub Actions.

Problem This Project Solves

My existing WordPress site had become stale, carried more maintenance overhead than I needed, and exposed features I no longer wanted to support. The comment system in particular had attracted suspicious activity, which pushed me to reduce the attack surface immediately and rethink the site more deliberately.

Goals

In the short term, I wanted to reduce unnecessary exposure on the existing WordPress site while preparing a better replacement. Disabling comments addressed the immediate concern, but it did not solve the larger problem: the site was outdated, harder to maintain than it needed to be, and lacked a clean path for ongoing improvement.

The long-term goal is to turn zachull.com into an automated portfolio platform that can display ongoing and completed projects, what I am currently learning, and up-to-date professional contact information.

Current Architecture

The target architecture for zachull.com is a low-cost static hosting path built around managed AWS edge services:

  • Astro builds the static website from version-controlled project files.
  • GitHub remains the source of truth for site code and public-safe content.
  • Amazon S3 stores the compiled static build output.
  • CloudFront serves the site at the edge and becomes the public delivery layer.
  • Route 53 manages DNS for the domain and directs public traffic to CloudFront.
  • AWS Certificate Manager provides TLS coverage for the custom domain.
  • GitHub Actions with AWS OpenID Connect handles the production deployment workflow without long-lived AWS credentials.
  • Terraform-managed infrastructure is the next implementation phase, planned after the automated deployment path is fully documented.

Design Decisions

The previous WordPress deployment gave me a functional public site, but it also introduced maintenance overhead I did not need for a portfolio that is primarily static content. A static architecture reduces the amount of running application infrastructure I have to patch, monitor, and pay for while still giving me room to learn meaningful cloud engineering concepts.

This migration is intentionally designed around a few priorities:

  • Lower recurring cloud cost than an always-on WordPress host
  • Less operational burden for a mostly static website
  • Cleaner version control through GitHub
  • A stronger deployment story than manual website edits
  • A public project that connects front-end code, cloud infrastructure, DNS, TLS, and automation

This keeps the site aligned with the kind of infrastructure work I want to become better at: clear boundaries, lower overhead, repeatable deployment, and well-documented tradeoffs.

Implementation Path

The project is being developed in stages so that each part of the system is understandable before I automate it.

  1. Build the portfolio site locally in Astro.
  2. Track the project in GitHub and establish clean commit history.
  3. Create the AWS hosting path using S3, CloudFront, Route 53, and ACM.
  4. Test the new site through a preview or temporary endpoint before changing public DNS.
  5. Cut over zachull.com from the existing WordPress host to the new static architecture.
  6. Add GitHub Actions deployment automation using AWS OIDC rather than long-lived AWS credentials.
  7. Convert the proven hosting design into Terraform-managed infrastructure.

What I’m Learning

This project is giving me a practical path through several cloud and operations concepts that are easier to understand when they are tied to a real deliverable:

  • How static site builds differ from server-rendered or CMS-backed websites
  • How S3, CloudFront, Route 53, and ACM fit together in a public hosting path
  • How to think about DNS migration and cutover planning without creating avoidable disruption
  • Why deployment automation should use scoped, temporary credentials instead of long-lived secrets
  • How content structure, code structure, and infrastructure decisions affect long-term maintainability
  • When to prove an architecture manually before codifying it in Terraform

Current Status

The Astro portfolio site is currently live and the main project is documented in my GitHub homelab repo. GitHub Actions deployment automation is live and a part of the production pipeline with all tests passing. The next implementation phase is Terraform-managed infrastructure is planned after the automated architecture is documented.

Deployment Automation Update

After the manual S3 and CloudFront deployment path was validated, deployment was automated with GitHub Actions and AWS OIDC.

The workflow now builds the Astro site on pushes to main, assumes a scoped AWS IAM role through GitHub’s OIDC provider, syncs the generated dist/ output to the private S3 origin bucket, and creates a CloudFront invalidation.

A small troubleshooting issue came up during implementation: GitHub repository variables were initially entered as KEY=value strings instead of value-only entries. This caused malformed S3 and CloudFront commands in the workflow. Once the variables were corrected to store only their values, the deployment completed successfully.

Decommission Update

After the CloudFront-backed static site and GitHub Actions deployment pipeline were validated, the legacy Lightsail WordPress instance was stopped as the first stage of decommissioning. The instance was retained temporarily as rollback while the new Route 53, CloudFront, and S3 path was monitored. After validation, remaining Lightsail resources were removed to eliminate unnecessary cost and operational overhead.

Planned Improvements

Future documentation is planned to cover smaller parts of the project, including:

  • DNS cutover troubleshooting
  • AWS CLI setup
  • Static site deployment runbook
  • GitHub Actions with OIDC runbook

Other improvements:

  • Add diagrams showing the request path from Route 53 through CloudFront to S3.
  • Convert the proven AWS hosting resources into Terraform-managed infrastructure.