πŸ’‘ Ask Tutor

AWS + GitHub Actions – Automate Deployments Like a Pro

Build Seamless CI/CD Pipelines from GitHub to AWS for EC2, S3, Lambda & More

In modern cloud development, automation is non-negotiable. GitHub Actions allows you to automate build, test, and deployment pipelinesβ€”and when combined with AWS, it enables powerful DevOps workflows.

This chapter shows you:

  • How GitHub Actions works
  • How to deploy to AWS EC2, S3, Lambda
  • How to store secrets securely
  • How to write YAML workflows
  • Real-world CI/CD examples

What is GitHub Actions?

GitHub Actions is a built-in automation feature in GitHub that allows you to define workflows using YAML files in your repo.

You can trigger actions:

  • On code push, pull request, merge
  • On manual trigger (workflow_dispatch)
  • On cron schedule

GitHub Workflow Structure

YAML
name: CI/CD to AWS

on:
  push:
    branches:
      - main

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

      - name: Run Deployment Script
        run: ./deploy.sh

Step 1: Store AWS Credentials in GitHub Secrets

Go to your GitHub repo β†’ Settings β†’ Secrets β†’ Actions
Add:

NameValue
AWS_ACCESS_KEY_IDYour IAM access key
AWS_SECRET_ACCESS_KEYYour IAM secret key
(Optional) AWS_REGIONe.g., us-east-1

⚠️ Use an IAM user with least privilege access to required services.

Step 2: Deploy to AWS EC2 Using GitHub Actions

Sample Workflow: Upload Code to EC2 via SSH

YAML
name: Deploy to EC2

on:
  push:
    branches:
      - main

jobs:
  deploy:
    runs-on: ubuntu-latest

    steps:
    - name: Checkout code
      uses: actions/checkout@v3

    - name: Copy files to EC2
      uses: appleboy/scp-action@v0.1.7
      with:
        host: ${{ secrets.EC2_HOST }}
        username: ec2-user
        key: ${{ secrets.EC2_SSH_KEY }}
        source: "."
        target: "/home/ec2-user/app"

    - name: Restart App
      uses: appleboy/ssh-action@master
      with:
        host: ${{ secrets.EC2_HOST }}
        username: ec2-user
        key: ${{ secrets.EC2_SSH_KEY }}
        script: |
          cd /home/ec2-user/app
          pm2 restart all

Make sure EC2_SSH_KEY is your PEM file contents (no line breaks issues).


Step 3: Deploy Static Site to S3 with CloudFront Cache Invalidation

YAML
name: Deploy Static Site

on:
  push:
    branches:
      - main

jobs:
  deploy:
    runs-on: ubuntu-latest

    steps:
      - name: Checkout code
        uses: actions/checkout@v3

      - name: Sync to S3
        uses: jakejarvis/s3-sync-action@master
        with:
          args: --acl public-read --delete
        env:
          AWS_S3_BUCKET: my-site-bucket
          AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
          AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
          AWS_REGION: "us-east-1"
          SOURCE_DIR: "."

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

Step 4: Deploy Lambda Function Using AWS CLI

Deploy zipped function to AWS Lambda

YAML
- name: Zip Function
  run: zip -r function.zip .

- name: Deploy Lambda
  run: |
    aws lambda update-function-code \
      --function-name MyLambdaFunction \
      --zip-file fileb://function.zip
  env:
    AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
    AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
    AWS_REGION: us-east-1

πŸ’‘ Pro Tips for Using GitHub Actions with AWS

TipReason
Use workflow_dispatch to testAllows manual triggering
Use matrix builds for multi-envDeploy to staging & prod in parallel
Add if: statements for env controlPrevent accidental prod deploy
Cache dependenciesImprove pipeline speed
Use separate dev & prod workflowsSafer deployment process

Useful GitHub Actions Marketplace Tools

ToolUse
appleboy/scp-actionUpload files via SCP
jakejarvis/s3-sync-actionSync static files to S3
aws-actions/configure-aws-credentialsAuthenticate AWS CLI
docker/setup-buildx-actionUse Docker with AWS ECR
actions/cacheCache node_modules or Python deps

Bonus: CI/CD for CloudFormation

YAML
- name: Deploy CloudFormation
  run: |
    aws cloudformation deploy \
      --template-file template.yaml \
      --stack-name my-app-stack \
      --capabilities CAPABILITY_IAM