Overview

A written series on deploying an Astro site to Amazon S3 behind CloudFront from GitHub Actions, without long-lived AWS access keys: OIDC, IAM, a private bucket, clean URLs and the failures you will hit.

I wanted to build a personal engineering blog where I could document projects, experiments, embedded-systems development, FPGA work, Linux troubleshooting, software projects, and everything else I learn along the way.

But I didn’t want publishing an article to involve manually building the website, uploading files to a server, or logging into AWS every time.

I wanted the deployment process to be completely automated.

The goal was:

From writing an article to a published site Write article git commit git push GitHub Actions Build Astro website Deploy generated files to Amazon S3 CloudFront Website
Every step after the push is automatic; nothing is deployed by hand.

The final architecture uses:

  • Astro
  • GitHub
  • GitHub Actions
  • GitHub OpenID Connect (OIDC)
  • AWS IAM
  • Amazon S3
  • Amazon CloudFront
  • CloudFront Functions
  • A custom domain

The most important security decision was that I did not store a permanent AWS access key and secret key in GitHub.

Instead, GitHub Actions authenticates to AWS using OIDC and assumes a restricted IAM role.

The goal

The requirements were straightforward:

  1. Build the blog with Astro.
  2. Keep all source code in GitHub.
  3. Automatically deploy after pushing to main.
  4. Build the Astro project inside GitHub Actions.
  5. Upload only the generated dist/ directory to S3.
  6. Serve the website through CloudFront.
  7. Keep the S3 bucket private.
  8. Use a custom domain.
  9. Support clean URLs such as:
https://example.com/projects

instead of:

https://example.com/projects/index.html
  1. Avoid storing permanent AWS credentials in GitHub.

The final architecture looks like this:

The final architecture of the deployment Developer edits Astro content GitHub source code git push Astro build npm ci · npm run build GitHub Actions Amazon S3 static web files dist/ CloudFront CDN over HTTPS Custom domain engineerexperiences.link Users
One push is the only manual step; everything below GitHub is automated and repeatable.

What this series covers

Each part is a self-contained write-up, so read them in order or jump straight to the one you need.