Automating Deployment with GitHub Actions and AWS
Context: These workflows power this Gatsby site (Netlify), Car-Match (GitHub Pages frontend + Render backend), CheeseMath (GitHub Pages), and AWS labs. No enterprise-scale systems—just my projects.
AI assist: ChatGPT helped me structure the write-up; the YAML snippets come straight from the repos.
Status: Everything described here runs today. Some AWS deploys still live in lab accounts, and I call that out below.
Reality snapshot
- Static apps: Gatsby/React/Vite sites build via Yarn/Bun, lint/test, then deploy to Netlify or GitHub Pages.
- APIs: Express apps build Docker images, push to GHCR/ECR, and deploy to Render or EKS labs.
- Serverless: SAM/Serverless Framework packages functions, assumes AWS roles via OIDC, and deploys to sandbox accounts.
- Observability: Slack webhooks for success/failure,
/healthzsmoke tests, version tags (vYYYY.MM.DD.N). No on-call, but I check logs daily.
Baseline workflow (static site example)
name: ci-staticon:push:branches: [main]pull_request:branches: [main]jobs:build-test-deploy:runs-on: ubuntu-latestpermissions:id-token: write # for OIDC when targeting AWScontents: readsteps:- uses: actions/checkout@v4- uses: actions/setup-node@v4with:node-version: 20cache: npm- run: npm ci- run: npm run lint- run: npm run test --if-present- run: npm run build- name: Deploy to Netlifyif: github.ref == 'refs/heads/main'uses: netlify/actions/cli@v4with:args: deploy --dir=public --prodenv:NETLIFY_AUTH_TOKEN: ${{ secrets.NETLIFY_AUTH_TOKEN }}NETLIFY_SITE_ID: ${{ secrets.NETLIFY_SITE_ID }}
- Why it works: Immutable installs (
npm ci), lint/tests enforced before builds, and deployments happen only on main. Pull requests stop after the build so reviewers see artifacts fast.
AWS deployments (labs + future hosting)
deploy-aws:needs: build-test-deployif: github.ref == 'refs/heads/main'runs-on: ubuntu-latestpermissions:id-token: writecontents: readsteps:- uses: actions/checkout@v4- uses: aws-actions/configure-aws-credentials@v4with:role-to-assume: arn:aws:iam::123456789012:role/github-actionsrole-session-name: github-actionsaws-region: us-east-1- run: sam build- run: sam deploy --no-confirm-changeset --stack-name media-pipeline --region us-east-1
- OIDC means I don’t store long-lived AWS keys in GitHub.
- Stacks deploy to AWS Academy / sandbox accounts; README files state that clearly so nobody assumes it’s production.
Containers & Render deploys
- Build + scan images (
docker build,docker scan, Trivy). - Push to GitHub Container Registry.
- Trigger Render via webhook (free tier for Car-Match backend). README warns about 5-minute cold starts.
Observability & rollback habits
- Smoke tests (
scripts/smoke.sh) hit/healthz+ a basic user flow post-deploy. Failures runscripts/rollback.shto redeploy the previous artifact. - Slack notifications (success/failure) include commit SHA, author, and deploy URL.
- Tags like
v2025.10.15.1map to Netlify deploy IDs and Render releases, making it easy to diff.
Governance & cost guardrails
- Branch protections: lint/test/build must pass before merging.
- Secrets live in GitHub environments (dev/stage/prod) with required reviewers.
- Nightly
npm audit+pip-auditworkflows log findings; high severity issues block merging until resolved. - Cost dashboards (Netlify, Render, Mongo Atlas, AWS Budgets) alert via email when spend crosses thresholds—even if it’s only a few dollars.
To-do list
- Add Playwright-based synthetic tests that run automatically after deploys.
- Publish my workflow templates so classmates can fork them instead of copying snippets.
- Experiment with Checkly/Upptime for external monitoring.
- Migrate more workloads to the AWS adapter (S3/CloudFront) once I clean up the sharp install process.