1. Home
  2. Articles
  3. Case study

Case study

How devopsplant.com.au is built and deployed

Our own website runs on the same patterns we build for clients: a private S3 bucket behind CloudFront, deployments with no stored AWS keys, a staging environment first, and a rollback that takes one change.

  • By Anwar Alawad
  • Updated 1 October 2026
  • Stack AWS · Terraform · GitHub Actions
01 · Requirements

The requirements

  • Secure: no public bucket, no long-lived AWS keys anywhere, and strict security headers.
  • Safe to change: every change is seen on staging first, and a bad release can be undone quickly.
  • Fast: static files served from a CDN, cached as long as possible without serving stale pages.
  • Readable by search engines and AI systems: real HTML on every page, not an empty app shell.
02 · Architecture

Architecture

  • The site is a Vue application built with Vite.
  • Files live in a private S3 bucket. CloudFront reads it through Origin Access Control, signing every request with SigV4, so the bucket is never public.
  • A CloudFront response headers policy adds a Content Security Policy, HSTS, X-Content-Type-Options, a referrer policy and frame protection to every response.
  • The infrastructure is Terraform, run in Terraform Cloud, with a separate workspace for staging and production.
03 · Deploying

How a change reaches production

  1. A push to the staging branch deploys to staging. A push to main deploys to production, after it has been checked on staging.
  2. GitHub Actions signs in to AWS with OIDC: it exchanges a short-lived token for temporary credentials on an IAM role. The workflows use no stored AWS keys. See how to set that up.
  3. Each build is uploaded to its own folder in the bucket, named after the commit.
  4. Terraform then points CloudFront at the new folder, and the cache is invalidated. The switch only happens after the upload has finished, so visitors never see a half-uploaded release.

Rollback is one change

The last two builds are kept in the bucket. Rolling back means pointing CloudFront at the previous commit’s folder again. Nothing needs to be rebuilt or re-uploaded.

04 · Caching

Caching without stale pages

  • JavaScript, CSS and images have a content hash in their file names, so they are cached for a year and marked immutable.
  • HTML pages, robots.txt, the sitemap and llms.txt keep the same names between releases, so browsers revalidate them on every visit.

A returning visitor always gets the current page, and the page’s assets usually come straight from their cache.

05 · Crawlability

Real HTML for crawlers

A single-page app normally serves the same empty shell at every URL, and many crawlers, including those behind AI assistants, don’t run JavaScript. So after each build, every public page is opened in headless Chrome and saved as finished HTML. Each page has its own title, description, canonical link and structured data, and the site publishes a sitemap and an llms.txt.

06 · Takeaways

What carries over to client work

  • Keyless deployments with OIDC work for any pipeline that deploys to AWS.
  • Deploying each build to its own location, then switching traffic, makes rollback fast for static sites and containers alike.
  • Staging-first, with the same infrastructure code for both environments, means production is never the first place a change runs.

See Faster deployments for how we apply this to application releases.

Next step

Want the same for your site or app?

On a 30-minute call we’ll look at how you deploy today and what it would take to make it keyless and reversible.