"What if every time you push to GitHub, your website updated itself within minutes?"
Welcome to the world of automated deployments! In this post, we’ll build a CI/CD pipeline that deploys a React app to Amazon S3 and serves it globally via CloudFront, all powered by GitHub Actions.
Perfect for developers who want to move fast, stay lean, and look like pros. 😎
🎯 What We’ll Cover
- Build and host a React app on S3
- Connect CloudFront for global delivery
- Use GitHub Actions to auto-deploy on every push
- Add cache invalidation so users always get the latest version
Think of this like a pizza shop that bakes, boxes, and delivers your app every time you update the ingredients (code)!
🧰 Prerequisites
- AWS account with access to S3, CloudFront, and IAM
- React project (Create with
npx create-react-app my-app
) - GitHub repo with your React app
- Basic familiarity with GitHub Actions and AWS CLI
🏗️ Step 1: Create an S3 Bucket for Static Hosting
- Go to the AWS S3 Console
- Create a new bucket:
my-react-app-bucket
- Uncheck "Block all public access" (for static hosting)
- Enable Static Website Hosting
- Note the bucket URL (you’ll need it later)
Bucket policy example:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": "*",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::my-react-app-bucket/*"
}
]
}
🌍 Step 2: Set Up CloudFront
- Go to the CloudFront Console
- Create a new distribution:
- Origin: Your S3 bucket website endpoint
- Viewer Protocol Policy: Redirect HTTP to HTTPS
- Cache Behavior: Set TTLs, enable compression
- Optional: Add a custom domain with ACM SSL
📌 Save the CloudFront domain (e.g. d1234xyz.cloudfront.net
)
🤖 Step 3: Create IAM User for GitHub Actions
- Go to IAM → Create user
github-deploy-user
- Attach permissions:
AmazonS3FullAccess
-
CloudFrontFullAccess
- Download Access Key ID & Secret
Store these as GitHub Secrets:
AWS_ACCESS_KEY_ID
AWS_SECRET_ACCESS_KEY
-
DISTRIBUTION_ID
(CloudFront ID) -
S3_BUCKET_NAME
(your bucket)
⚙️ Step 4: Add GitHub Actions Workflow
Create .github/workflows/deploy.yml
in your repo:
name: Deploy React App to S3 + CloudFront
on:
push:
branches:
- main
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v3
- name: Setup Node.js
uses: actions/setup-node@v3
with:
node-version: '18'
- name: Install dependencies
run: npm install
- name: Build app
run: npm run build
- name: Sync to S3
run: |
aws s3 sync build/ s3://$S3_BUCKET_NAME --delete
env:
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
AWS_REGION: us-east-1
- name: Invalidate CloudFront cache
run: |
aws cloudfront create-invalidation --distribution-id $DISTRIBUTION_ID --paths "/*"
env:
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
AWS_REGION: us-east-1
📦 Bonus: Speed Tips
- Add a custom domain with Route 53
- Use S3 lifecycle rules to manage stale assets
- Enable gzip + Brotli in CloudFront for performance
✅ Done! Push & Deploy
Now, every time you git push
, your app:
- Builds
- Uploads to S3
- Invalidates the CloudFront cache
- Goes live globally 🌎
Zero manual steps. Just speed and satisfaction. 😌
💬 What Will You Build Next?
Will you use this pipeline for:
- Your portfolio site?
- A React landing page for your startup?
- A client dashboard?
👇 Share your use case, tips, or questions below!
If you loved this, smash that ❤️ and share with someone building React apps.
Let’s deploy smart, fast, and like pros. 💪
Great guide, Automating deployment with GitHub Actions, S3, and CloudFront streamlines the process significantly.
One suggestion: consider adding cache invalidation to your CloudFront distribution to ensure users always receive the latest version of your app after each deployment.