Automating Static Website Deployment to S3 and CloudFront Using GitHub Actions (CI/CD)
Automate static website deployments on AWS using GitHub Actions, Amazon S3, and CloudFront
I build and deploy cloud-native applications using AWS and DevOps practices. I share practical tutorials on CI/CD pipelines, serverless architectures, and real project learnings, and I’m exploring MLOps.
Introduction
After setting up static website hosting using Amazon S3 and CloudFront, the next logical step is automation.
Manually uploading files to S3 every time you make a change is not scalable and does not reflect real-world DevOps practices. In production environments, deployments are automated using CI/CD pipelines to ensure speed, consistency, and reliability.
In this blog, we will build a CI/CD pipeline using GitHub Actions to automatically deploy a static website to Amazon S3 and invalidate the CloudFront cache whenever code is pushed to the repository.
Note: CloudFront invalidation removes cached objects from CloudFront edge locations so users receive the latest version of the content immediately after deployment.
This blog continues from:
Blog-1: CI/CD Basics with GitHub Actions
Blog-2: Hosting a Static Website Using Private S3 + CloudFront
What You Will Learn
In this blog, you will learn:
Why CI/CD is important even for static websites
How GitHub Actions works for automated deployments
How to deploy static files to Amazon S3 automatically
How to invalidate CloudFront cache after deployment
A real-world CI/CD architecture used in production
Why CI/CD for Static Websites?
Even though static websites are simple, deployment should never be manual in production.
Problems with Manual Deployment
Time-consuming uploads
High chance of human error
No consistency between deployments
Not suitable for production environments
Benefits of CI/CD
Automatic deployments on every code change
Faster and more reliable releases
Repeatable and consistent process
Aligns with real DevOps and SRE workflows
CI/CD Architecture Overview

Flow Explanation
Developer pushes code to GitHub
GitHub Actions workflow is triggered
Static files are synced to the S3 bucket
CloudFront cache is invalidated
Updated content is served globally
This ensures every deployment is automated and instantly available worldwide.
Prerequisites
Before starting, ensure you have:
A GitHub repository with static website files (HTML, CSS, JavaScript)
A private Amazon S3 bucket for static website hosting
An Amazon CloudFront distribution connected to the S3 bucket
An IAM user with programmatic access
AWS credentials (Access Key ID and Secret Access Key)
The S3 bucket and CloudFront distribution are assumed to be already configured as explained in Blog-2. and IAM User & Policy Setup Guide GitHub link https://github.com/nlokeshbabu1/AWS-S3.git
Step 1: Store AWS Credentials in GitHub Secrets
Never hardcode AWS credentials in your repository.
Steps
Go to your GitHub repository
Click Settings → Secrets and variables → Actions

Click New repository secret
Add the following secrets:
AWS_ACCESS_KEY_ID
AWS_SECRET_ACCESS_KEY
AWS_REGION
S3_BUCKET_NAME
CLOUDFRONT_DISTRIBUTION_ID
These secrets are securely encrypted and used by GitHub Actions during runtime.
Step 2: Create GitHub Actions Workflow
Create the following file in your repository:
.github/workflows/deploy.yml
GitHub Actions Workflow
name: Deploy Static Website to S3 and CloudFront
on:
push:
branches:
- main
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- name: Checkout Repository
uses: actions/checkout@v3
- name: Configure AWS Credentials
uses: aws-actions/configure-aws-credentials@v2
with:
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
aws-region: ${{ secrets.AWS_REGION }}
- name: Sync Files to S3
run: |
aws s3 sync . s3://${{ secrets.S3_BUCKET_NAME }} \
--delete \
--exclude ".git/*" \
--exclude ".github/*" \
--exclude "README.md" \
--exclude "LICENSE"
- name: Invalidate CloudFront Cache
run: |
aws cloudfront create-invalidation \
--distribution-id ${{ secrets.CLOUDFRONT_DISTRIBUTION_ID }} \
--paths "/*"
Workflow Explanation
Trigger
- Runs automatically when code is pushed to the
mainbranch
Checkout
- Downloads repository code into the GitHub Actions runner
AWS Credentials
- Authenticates securely using GitHub Secrets
S3 Sync
Uploads updated files to S3
Deletes removed files to maintain consistency
CloudFront Invalidation
Clears cached content
Ensures users see the latest version immediately
Deployment Result
Once the workflow completes successfully:
- Static files are updated in S3

CloudFront serves the latest content
Website updates are live globally 🌍
No manual deployment steps are required.
Production Best Practices
Keep the S3 bucket private
Use CloudFront with Origin Access Control (OAC)
Store secrets securely in GitHub Secrets
Automate every deployment using CI/CD
Invalidate CloudFront cache only when required
This setup reflects how static websites are deployed in real-world production environments.
Conclusion
By combining Amazon S3, CloudFront, and GitHub Actions, we create a fully automated, secure, and scalable deployment pipeline for static websites.
This CI/CD setup:
Eliminates manual deployments
Improves reliability and speed
Follows DevOps and SRE best practices
This architecture is widely used across startups and enterprises for frontend and static website deployments.