This repository is a guideline to how to deploy a static web application using aws Below are the steps to follow to deploy an SPA to aws s3 bucket:
- Visit the Amazon Web Services (AWS) website.
- Click on "Create an AWS Account" and follow the prompts to set up your account.
- After logging in, navigate to the IAM (Identity and Access Management) dashboard.
- Select Users from the sidebar.
- Click on your username (this is your root account) and then go to the Security credentials tab.
- Under Multi-Factor Authentication (MFA), click Manage MFA and follow the instructions to enable MFA using an authenticator app.
- In the IAM dashboard, select Users and then Add user.
- Enter a username (e.g., admin-user), enable Programmatic access, and enable AWS Management Console access.
- Set a custom password or let AWS auto-generate one.
- Click Next: Permissions, then Attach existing policies directly.
- Select the AdministratorAccess policy.
- Click Next: Tags, then Next: Review, and finally Create user.
- Download the .csv file containing your access key and secret key for programmatic access.
- Log out from the root account.
- Log in using the new administrator account credentials.
- Go to the S3 Console.
- Click Create bucket.
- Enter a unique bucket name (e.g., my-spa-bucket).
- Choose a region close to your target audience.
- Click Create bucket.
- Select your bucket.
- Go to the Permissions tab.
- Scroll down to Block public access and click Edit.
- Uncheck the Block all public access option and confirm the change.
- Click Save.
- Still in the Permissions tab, scroll down to Bucket Policy and click Edit.
- Enter the following policy, replacing your-bucket-name with your actual bucket name:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": "*",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::your-bucket-name/*"
}
]
}
- Click Save changes.
- Go to the Properties tab.
- Scroll down to Static website hosting and click Edit.
- Choose Enable.
- Enter index.html for the Index document and error.html for the Error document.
- Click Save changes.
Go to the Objects tab. Click Upload and add your index.html, error.html, and any other necessary files (CSS, JS, images, etc.).
PS : If your html page doesn't apply the css files to the page try verifying the meta data property of the file and make sure it is text/css.
Now that our S3 bucket is set up and our static assets are ready,we need to complete the deployment pipeline with custom domain support, HTTPS, and CDN caching.
We purchased our domain from Namecheap,but want to manage DNS using AWS Route 53.So we need to do the following:
-
Create a Hosted Zone
- Go to the Route 53 console.
- Click Hosted zones > Create hosted zone.
- Enter our domain name ariellekamdem.me
- Select Public Hosted Zone and click Create hosted zone.
-
Update Domain Nameservers
- In Route 53, note the four NS (Name Server) records.
- Go to the Namecheap dashboard.
- Update the nameservers for our domain with the four provided by Route 53.
- This will delegate DNS management to AWS Route 53.
-
Create a Subdomain Record
- In our hosted zone,we will create a record.
- Name:
v1(forv1.ariellekamdem.me) - Type: A – IPv4 address
- Choose Alias: Yes
- Alias target: select your CloudFront distribution
- Click Create records
To enable HTTPS:
- Go to AWS Certificate Manager (ACM).
- Click Request a certificate > Public certificate.
- Enter our domain v1.ariellekamdem.me and request the certificate.
- Choose DNS validation, and ACM will give you a CNAME record.
- Go back to Route 53, and add the provided CNAME record to your hosted zone.
- Once validated, the certificate status will change to Issued.
- Go to CloudFront and click Create distribution.
- Origin:
- Origin domain: your S3 bucket
- Protocol: Redirect HTTP to HTTPS
- Settings:
- Viewer protocol policy: Redirect HTTP to HTTPS
- Alternate domain name (CNAME):
v1.ariellekamdem.me - SSL Certificate: choose the one issued by ACM
- Enable Caching, set a reasonable TTL
- Save and wait for distribution to deploy.
To automate deployment whenever we push changes to our repo we did the following:
-
In our GitHub repository, create a
.github/workflows/deploy.ymlfile. -
Sample GitHub Actions workflow:
name: Deploy Website
on:
push:
branches:
- main
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v1
- name: Configure AWS Credentials
uses: aws-actions/configure-aws-credentials@v1
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: Install modules
run: npm install --legacy-peer-deps
- name: Build application
run: npm run build
- name: Deploy to S3
run: aws s3 cp ./dist/ s3://${{ secrets.BUCKET_ID }} --recursive
- name: Create CloudFront invalidation
run: aws cloudfront create-invalidation --distribution-id ${{ secrets.DISTRIBUTION_ID }} --paths "/*"
-
Trigger: Runs on every push to the
mainbranch. -
Checkout Code: Uses
actions/checkoutto pull your latest code. -
Configure AWS Credentials: Authenticates with AWS using secrets stored in your GitHub repository.
-
Install Dependencies: Installs all project dependencies with
npm install --legacy-peer-deps. -
Build Application: Runs
npm run buildto generate static files (usually in thedist/folder). -
Deploy to S3: Uploads the contents of the
dist/directory to your S3 bucket. -
CloudFront Invalidation: Issues an invalidation request (
/*) to clear the CloudFront cache, so new content is
NB : What is a CloudFront Invalidation? When CloudFront serves content, it caches the files at edge locations to improve performance and reduce load time. However, when you update files (like index.html, bundle.js, or CSS), the cached version may still be served unless it's cleared.
A CloudFront invalidation is a request to remove cached objects from all edge locations. This forces CloudFront to fetch the updated content from the origin (your S3 bucket) the next time a user makes a request.
In this pipeline, we invalidate all files ("/*") after deployment to ensure users always receive the latest version of the application.
Here’s a clear and professional conclusion you can add at the end of your deployment steps:
Congratulations! 🎉 You've successfully deployed your Single Page Application (SPA) using AWS services. By leveraging S3 for hosting, Route 53 for DNS management, CloudFront for CDN caching, ACM for SSL certificates, and GitHub Actions for CI/CD automation.
This setup ensures:
- High availability and performance through AWS’s global infrastructure,
- Automatic HTTPS support for secure browsing,
- Fast delivery of content via CloudFront edge caching,
- Seamless updates through automated GitHub workflows.
Feel free to contact me if you need help or assistance.


