17.9 C
Monday, January 30, 2023

Deploy Static Website on AWS S3 using CodePipeline, CloudFront & Route 53

The goal of this article is to deploy a static website on AWS S3 Bucket which is one of the different methods to deploy a static website on AWS. We need to complete the followings objective to achieve the goal.

  1. Version controlling the website project on Local Machine using Git.
  2. Upload the code on GitHub Repository.
  3. Create an AWS S3 Bucket that has Public Access Policy.
  4. Create a CICD Pipeline using AWS CodePipeline that can trigger an automatic deployment when any code changes are pushed to GitHub Repository.
  5. Request a free SSL/TLS Certificate from the AWS Certificate Manager.
  6. Use AWS CloudFront service to create a Content Delivery Network (CDN) to improve page load speed.
  7. Use custom domain using AWS Route 53.

Set up GitHub Repository

First of all, we need to set up a GitHub Repository where the code of our project resides. Either we can continue from the existing static website project or we can download a sample project from the internet.

Download Free HTML/CSS Theme

There are a plethora of free HTML/CSS themes available on the internet. We will download a free HTML theme from the Free CSS website. Once you have the code downloaded, we are ready to upload it to GitHub Repository.

Screenshot from https://www.free-css.com/

Create GitHub Repository

  1. Go to GitHub and log in to your account.
  2. Click the New Repository button.
  3. Provide a Repository Name and set this repository as Public.
  4. Keep other configurations to default as shown in the screenshot below.
  5. Click the Create Repository button.

Associate SSH Keys to GitHub Account

In our project, there may be different team members who can collaborate to make changes or fix bugs in the project. Each team member will have his own local Git repository, where he/she will make changes and push them to GitHub Repository.

Every user of the local repository must have a secure connection to the remote repository when he pushes updates on the GitHub server. SSH key pairs authentication method that relies on a cryptographic algorithm is used to authenticate the local git user on the GitHub server.

Generate SSH Key Pairs

Open Ubuntu Terminal and run the following command to create SSH key pairs. Two keys will be created named id_ecdsa (Private Key) and id_ecdsa.pub (Public Key) on location ~/.ssh.

The following command will create key pairs of the algorithm type ECDSA, byte equals 512, and with no pass-phrase.

ssh-keygen -f ~/.ssh/id_ecdsa -t ecdsa -b 521 -q -N ""

Run the following command to see the key pairs generated.

ls -l ~/.ssh 

Copy the Content of the Public Key

Run the following command to copy the content of the Public Key.

cat ~/.ssh/id_ecdsa.pub

Add Public Key Content to GitHub

  1. Go to Settings > SSH and GPG keys and Click the New SSH Key button.
  2. Paste the content of Public Key in the text box titled Key.
  3. Click Add SSH Key button.

Set up Local Git Repository

Now, locate the website folder on the local machine and set up a local Git repository by running the following commands one by one.

1) Initialize the git repository.

2) Adds a change in the working directory to the staging area.

3) Save the snapshot of the working directory

4) Change the branch name from default “master” to “main”.

5) Set the remote repository URL to a local variable named origin. Note that the URL used is the SSH URL provided by the GitHub repository, not HTTPS.

6) Upload the local content of the repository to the remote repository.

git init
git add .
git commit -m "first commit"
git branch -M main
git remote add origin git@github.com:gulraeezgulshan/newsroom.git
git push -u origin main

After running the above commands successfully, you will notice that the content of your local Git repository has been pushed to the remote GitHub Repository.

Create and Configure AWS S3 Bucket

Not let us begin with the AWS part of this project. We need some sort of secure storage where the current version of our website code will get stored. S3 Bucket is an infinite storage service that can be used to store different types of data. For example, Analytics data, logs files, application data, videos and pictures, and backup and archival can be stored on S3. When it comes to hosting static websites, S3 is a great choice too.

Create the S3 Bucket

Login to AWS Management Console and launch S3 Bucket Service. Click Create Bucket button to proceed.

Bucket name and Region

Provide a globally unique bucket name; in our case, the name of the bucket is the same as the domain. Select the region where the S3 Bucket is intended to be created.

Public Access settings for Bucket

By default, public access to the S3 bucket is blocked but we need to grant public access to the bucket so that our website can be publically accessed.

Empty S3 Bucket

Keep the rest of the configurations to the default and click the Create Bucket button. You will end up with the Empty Bucket as shown below:

Enable Bucket to host Static Website

By default, the S3 bucket is not configured to host a website so we need to enable it.

Go to the Properties tab and click the Edit button under the Static website hosting section.

  1. Select Enable under Static website hosting.
  2. Choose a Hosting type to Host a static website.
  3. Provide the default index document as index.html.
  4. Click the Save Changes button to enable the S3 bucket to host the website.

Attach a Bucket Policy

A bucket policy is a resource-based policy that we can use to grant access permissions to the bucket and the objects in it. We need to create such a policy that makes the objects of the bucket readable so the website can be easily accessible publically by anonymous users.

Go to the Permission tab and click the Edit button under the Bucket Policy section.

To grant the public read access to your website, copy the following bucket policy, and paste it into the Bucket policy editor.

    "Version": "2012-10-17",
    "Statement": [
            "Sid": "PublicReadGetObject",
            "Effect": "Allow",
            "Principal": "*",
            "Action": [
            "Resource": [

Note that the bucket name written in red colour is that placeholder where you can update the name of your own bucket.

Click the Save Changes button and you will notice the S3 Bucket is now publically accessible.

Set up CICD Pipeline using AWS CodePipeline

The CICD pipeline will automate the process of deployment of our website for fast delivery; the CICD process is AWS orchestrated by CodePipeline Service. The team of developers working collaboratively on website code will keep updating the code, fixing bugs or adding a new feature. As soon a code change is pushed to the main branch of the GitHub repository, the CodePipeline will automatically trigger the deployment process.

Go to AWS CodePipeline and click Create Pipeline button, it will start of series of steps to create a CICD pipeline.

Step 1: Choose Pipeline Settings

  1. Provide a Pipeline name.
  2. choose the New service role and leave the Role name to the default value.
  3. Click the Next button.

Step 2: Add Source Stage

Our source code is uploaded on GitHub so we choose the Source provider as GitHub (Version 2).

We need to create a connection to GitHub so that we can load our repository to AWS CodePipeline. Click Connect to GitHub button, it will start a setup wizard to install AWS Connector App on GitHub.

Provide a Connection name and click Connect to GitHub button.

Click the Install a new app button.

Select your GitHub account to continue.

Select All repositories and click the Save button.

Now, you have a GitHub connection at your disposal. Select the connection and click Connect button to continue.

Once the connection wizard has been completed, you can see the connection string as shown below and your GitHub connection is ready to use.

Now you can choose the repository name where your website source code has been uploaded. Also, choose the main branch of the repository; whenever any code changes/commits are pushed to the main branch, it will trigger CodePipeline to automatically deploy updated code to S3 Bucket. Click the Next button to continue.

Step 3: Add build stage

We can skip the build stage as our website source code only included HTML/CSS. Click Skip build stage to continue.

Step 4: Add deploy stage

At this stage, you configure where your code is going to be stored. In our case, we have already created the S3 Bucket intended to store website files and folders.

Provide Deploy Provider as Amazon S3, Region where Bucket is created, and the Bucket Name. It is mandatory to choose the option to Extract file before deploy, so that deployed artifacts will be unzipped before deployment. Click the Next button to continue.

Step 5: Review

In the last step, you will be asked to review the settings that you have configured so far for all stages. If everything seems fine, click Create Pipeline button to continue.

Visualize CodePipeline Stages

We can see our newly created pipeline that has two stages, Source and Deploy. It is apparent in the Source stage that it succeeded to pull the source code of the latest commit from GitHub. In the Deploy stage, we can see that it succeeded to upload all the files from the latest commit to S3 Bucket. Click the Amazon S3 button to verify the file uploads.

Deploy to S3 from CodePipeline

We can notice that CodePiple has successfully deployed the source code of the latest commit from GitHub to S3 Bucket.

Go to Properties > Static website hosting and click the URL provided.

Your website is available at the URL provided by S3 Bucket.

Request SSL Certificate on AWS

We will use AWS Certificate Manager (ACM) service to provision a public SSL/TLS Certificate that will be deployed later with CloudFront distribution. AWS will manage and renew the certificate on its own. The subsequent steps are only eligible to work if you have a valid domain address.

Go to Certificate Manager and Click the Request a certificate button.

Choose Request a public certificate and click Next.

Provide the fully qualified domain name of the site that you want to secure with an SSL/TLS certificate (i.e, www.gulraeez.com).

Also, provide a domain with an asterisk (*) to request a wildcard certificate to protect several sites in the same domain. i.e, *.gulraeez.com protects www.gulraeez.com, site.gulraeez.com, and images.gulraeez.com.

Select validation method as DNS validation. Click the Request button to continue.

Your request for the certificate has been generated for the domain gulraeez.com and it is currently pending validation. The validation process can sometimes take up to several hours.

In the meanwhile, click on Certificate ID to open the certificate details page. There you find Create records in Route 53 button.

Click Create records button; it will create a CNAME record in Route 53 automatically.

When the Status changes from Pending Validation to Issued, your public certificate is ready to be used with CloudFront.

Use CloudFront to create CDN

What is CDN?

A content delivery network, or content distribution network (CDN), is a geographically distributed network of proxy servers and their data centres. AWS CloudFront service is used to create CDN.

Below are the key benefits of using CDN

  • Improve page load speed
  • Handle high traffic loads
  • Block spammers, scrapers and other bad bots
  • Localize coverage without the cost
  • Reduce bandwidth consumption
  • Load balance between multiple servers
  • Protect your website from DDoS attacks
  • Secure your application (TLS/HTTPS)

Get Started with CloudFront

Go to CloudFront service and click Create a CloudFront distribution button.

CloudFront Origin

CloudFront origin is the location where content is stored i.e S3 Bucket. Select the Amazon S3 bucket’s domain from the list.

The name of origin should be the same as the origin domain name above.

Origin Access Identity (OIA)

We have set up an Amazon S3 bucket as the origin for CloudFront distribution. Currently, permission is granted to everyone to read the files in our bucket. It means users can access the website both from CloudFront URL and the S3 Bucket URL. If you want to prevent users from accessing the website directly from S3 URL, you use OAI.

OAI does the following;

  1. It creates a special CloudFront user called an origin access identity (OAI) and associate it with your distribution.
  2. It configures S3 bucket permission so that the user can not directly access the files from S3 Bucket from the URL provided by S3 Bucket
  3. You can then only access Bucket files from the URL provided by CloudFront Distribution.

Redirect HTTP to HTTPS

We can redirect all HTTP traffic to HTTPS from the setting below.

Alternate domain name (CNAME)

An alternate domain name allows you to use your own domain name instead of the domain name provided by CloudFront.

Associate SSL Certificate to Distribution

We have already been issued SSL Certificate from AWS Certificate Manager that can be associated with CloudFront Distribution.

Default Root Object

CloudFront Distribution Domain Name

When you click Create Distribution button, it will take display a summary page or newly created distribution. CloudFront will assign a domain name to access your website stored on CloudFront origin i.e S3 Bucket.

The website is successfully available at the domain name provided by CloudFront.

Update Bucket Policy

OIA automatically updates the Bucket Policy to allow access to special as CloudFront user. You can see two statements in the policy, the first statement allows access to every user/prin (*) while the second statement allows access to only a special CloudFront user (cloudfront:user).

With the current state of Bucket Policy, it will allow access from both CloudFront and S3 Bucket URLs. To prevent accessing the Website from S3 Bucket, remove the first statement.

After removing the first statement, Bucket Policy will look like the below. Click the Save button to continue.

Now, you can verify the access denied from S3 URL.

Use Custom Domain with CloudFront

Go to Route 53 > Hosted zones and click on the registered domain address.

You will see the list of records added to your domain. Click Create record button.

Create an alias record of (Type A) to route traffic to CloudFront distribution when the requests are received on gulraeez.com.

Create another record (Type CNAME) to route traffic to gulraeez.com when requests are received on www.gulraeez.com.

Route 53 records should contain all records as shown below by the end of this project.

Finally, your website is accessible from your custom domain with SSL Certificate Installed.

Gulraeez Gulshan
Gulraeez Gulshan
I am an engineer, programmer, tech-savvy professional, and very passionate about the latest technologies for the modern web, mobile, cloud-native, machine learning, and network automation. I have a bachelor's degree in Electronics Engineering and a Master's degree in Computer Science and Information Technology from a renowned university in Pakistan. I have not limited myself to a certain set of skills in this era where technology is in a state of flux; I have experience working with an extensive range of technologies and learning daily to update my skills and adapt to the latest technologies

Related Articles


Please enter your comment!
Please enter your name here

Latest Articles