Hey there, fellow developer! 👋 Let’s talk about a nightmare we’ve all had:

You’re deploying code to AWS, fingers crossed, praying it doesn’t take down your entire app. The loading spinner mocks you. Your Slack DMs blow up: “Is the site down??”

But what if you could deploy updates with zero downtime while sipping coffee? Enter GitHub Actions + AWS—the dynamic duo that’ll turn you into the calmest dev in the room.


Why GitHub Actions + AWS?

  • No More “It Works on My Machine”: Deploy from a clean, consistent environment every time.
  • Zero Downtime: Blue/green deployments, Lambda aliases, and S3 magic keep your site alive.
  • Free (Mostly): GitHub Actions gives you 2000 free minutes/month.

Let’s automate your AWS deploys like a pro.


1. Deploy a Static Site to S3 (And Invalidate CloudFront)

Use Case: Your React/Vue/Angular app needs to go live.

Step 1: Create an S3 Bucket & CloudFront Distribution

  • Enable static hosting on S3.
  • Set up CloudFront for CDN caching (optional but highly recommended).

Step 2: Add This GitHub Action

name: Deploy to S3  

on:  
  push:  
    branches: [main]  

jobs:  
  deploy:  
    runs-on: ubuntu-latest  
    steps:  
      - name: Checkout Code  
        uses: actions/checkout@v4  

      - name: Install Dependencies  
        run: npm install && npm run build  

      - name: Deploy to S3  
        uses: aws-actions/configure-aws-credentials@v4  
        with:  
          aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}  
          aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}  
          aws-region: us-east-1  

      - name: Sync Files  
        run: aws s3 sync ./dist s3://your-bucket-name --delete  

      - name: Invalidate CloudFront Cache  
        run: aws cloudfront create-invalidation --distribution-id ${{ secrets.CLOUDFRONT_ID }} --paths "/*"

Boom. Your static site updates instantly. No downtime.


2. Deploy a Node.js App to EC2 (Zero Downtime)

Use Case: Your backend API running on an EC2 instance.

Step 1: Set Up an EC2 Instance

  • Install Node.js, PM2 (process manager), and NGINX (reverse proxy).

Step 2: GitHub Action Workflow

name: Deploy to EC2  

on:  
  push:  
    branches: [main]  

jobs:  
  deploy:  
    runs-on: ubuntu-latest  
    steps:  
      - name: Checkout Code  
        uses: actions/checkout@v4  

      - name: Install Dependencies  
        run: npm install  

      - name: Zip Artifacts  
        run: zip -r deploy.zip .  

      - name: Copy to EC2 via SSH  
        uses: appleboy/scp-action@v1  
        with:  
          host: ${{ secrets.EC2_IP }}  
          username: ubuntu  
          key: ${{ secrets.EC2_SSH_KEY }}  
          source: "deploy.zip"  
          target: "/home/ubuntu"  

      - name: Deploy & Restart  
        uses: appleboy/ssh-action@v1  
        with:  
          host: ${{ secrets.EC2_IP }}  
          username: ubuntu  
          key: ${{ secrets.EC2_SSH_KEY }}  
          script: |  
            unzip -o deploy.zip  
            npm install --production  
            pm2 restart api

Why This Works:

  • PM2 keeps your app running during restarts.
  • NGINX proxies traffic seamlessly while the app reloads.

3. Deploy a Serverless Function to AWS Lambda

Use Case: A serverless API using Lambda + API Gateway.

Step 1: Use the AWS Lambda Action

name: Deploy to Lambda  

on:  
  push:  
    branches: [main]  

jobs:  
  deploy:  
    runs-on: ubuntu-latest  
    steps:  
      - name: Checkout Code  
        uses: actions/checkout@v4  

      - name: Configure AWS Creds  
        uses: aws-actions/configure-aws-credentials@v4  
        with:  
          aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}  
          aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}  
          aws-region: us-east-1  

      - name: Deploy Lambda Function  
        run: |  
          zip -r function.zip .  
          aws lambda update-function-code \  
            --function-name your-lambda-name \  
            --zip-file fileb://function.zip  

      - name: Update Alias (Zero Downtime)  
        run: |  
          aws lambda publish-version --function-name your-lambda-name  
          aws lambda update-alias \  
            --function-name your-lambda-name \  
            --name prod \  
            --function-version LATEST

Pro Tip: Use Lambda aliases (e.g., prod) to route traffic gradually.


“But What If Something Breaks?” (Rollbacks Made Easy)

  • S3: Enable versioning and revert to a previous version.
  • Lambda: Point the alias back to the last stable version.
  • EC2: Keep a backup AMI or use pm2 revert.

Your GitHub Actions + AWS Cheat Sheet

Service Zero-Downtine Trick
S3 CloudFront cache invalidation
EC2 PM2 graceful reloads
Lambda Version aliases

Final Thought: Automate First, Panic Never

Deploying to AWS doesn’t have to feel like defusing a bomb. With GitHub Actions, you can:

  • 🚀 Deploy confidently.
  • ☕ Enjoy your coffee mid-deployment.
  • 😎 Become the DevOps hero your team deserves.

Next Steps:

  • Add these workflows to your repos.
  • Share this guide with that one teammate who still deploys via FTP.

Now go automate all the things! 🛠️

Stuck? Drop a comment—we’ve all been there. Let’s debug together! 🚀