Hosting a Static Website with Amazon S3
Tags: aws, devops, cloud, tutorial
Published: 2021-06-26 21:30:43

In this article, I’d like to demonstrate how you can deploy a static website with AWS by uploading your website content into S3 bucket, configuring your bucket for website hosting and speeding up content delivery using AWS CloudFront.

First of all, let me explain some of the terminologies.

##What is Amazon S3?
Amazon S3 (Simple Storage Service) is a service offered by AWS for object storage through a web service interface. It can be used to store or retrieve any amount of data such as documents, images, videos, etc.
**S3 bucket** is a resource in Amazon S3. It is a container where files and folders can be uploaded.

##What is Amazon CloudFront?
Amazon CloudFront is a content delivery network (CDN) service offered by AWS. It is used to speed up content delivery and can be integrated with Amazon S3.

##Benefits of using AWS S3 bucket
* Each object can contain up to 5TB of data.
* A resource can only be accessed by the owner until permission is granted to others which makes it more secure.
* It is cheap.
* You can enable Multi-Factor Authentication (MFA) delete on an S3 bucket to prevent accidental deletions and unintentional data loss.

##Prerequisites
If you’d like to follow this tutorial, please make sure the following requirements are met.
* AWS account. You can sign up [here](https://aws.amazon.com/) and follow this [tutorial](https://aws.amazon.com/premiumsupport/knowledge-center/create-and-activate-aws-account/) in setting it up.
* A static website. If you don’t have one, you can clone this [demo project](https://github.com/mariehposa/aws-s3-demo).

##Table of Contents
1. [Create an S3 bucket](#create)
2. [Upload web files to S3 bucket](#upload)
3. [Secure S3 bucket through IAM policies](#secure)
4. [Configure S3 bucket](#configure)
5. [Serve content from S3 bucket with CloudFront](#serve)

Now, let’s get into it!

##Step 1 — Create an S3 bucket <a name="create"></a>
You will need to create an S3 bucket to put your website’s files and folders.

To do this, login into your AWS management console and click on **Services** on the top navbar. From the **Services** drop-down, select **S3** from the **Storage** section. This should display the **S3** dashboard.

![image](https://user-images.githubusercontent.com/33374159/119153245-fc67ba00-ba48-11eb-81dc-63968f5dcfd9.png)

From the S3 dashboard, click on **Create bucket**. Give the bucket a unique name, the name you choose must be globally unique (for best practice, attach your AWS account ID to the name). 

Next, choose your preferred **AWS Region** from the drop-down. 

![image](https://user-images.githubusercontent.com/33374159/119145517-9f1c3a80-ba41-11eb-9c6b-f4a17a052e82.png)

Under **Block Public Access settings for this bucket** section, uncheck the **Block all public access** checkbox and accept the acknowledgement. This is done to make the bucket accessible to the public because you are going to host a website in it. 

![image](https://user-images.githubusercontent.com/33374159/119145647-c115bd00-ba41-11eb-8c50-b27cfa04fbbb.png)

Click on **disable** for Bucket Versioning.

You can also **Add tag** to the bucket for easy identification. 

Under **Default encryption** section, click on **disable** for Server-side encryption. 

![image](https://user-images.githubusercontent.com/33374159/119145920-076b1c00-ba42-11eb-8cfb-9bd28d352e10.png)

Then click on **Create bucket**.

![image](https://user-images.githubusercontent.com/33374159/119146169-47ca9a00-ba42-11eb-9917-5c2fb5bb7802.png)

##Step 2 — Upload web files to S3 bucket <a name="upload"></a>
After creating the bucket, you need to upload your website’s files and folders into it.

From the **S3** dashboard, click on the **name** of the bucket you just created.

On the **Objects** tab, you can see that the bucket is currently empty, click on the **Upload** button.

![image](https://user-images.githubusercontent.com/33374159/119146402-806a7380-ba42-11eb-903e-c24995bae41c.png)

This should take you to the **Upload** page. Click **Add files** to add the website files and use **Add folder** to add the website folders.

**Note**: The whole website folder shouldn’t be added at once. Instead, add its content one after the other. For example, with the demo project linked up top, I uploaded my **signup.html** as a file, **signup.js** as a file, **css** as a folder and **img** as a folder.

![image](https://user-images.githubusercontent.com/33374159/119146885-fcfd5200-ba42-11eb-835a-465703daa78b.png)

After the necessary files and folders have been added, scroll down and click on **Upload**.

The uploading should be done in a few minutes depending on your network and content size. Also, please do not close the tab while the upload process is going on.

##Step 3 — Secure S3 bucket through IAM policies <a name="secure"></a>
Now you need to add some policies to secure your bucket.

From the **S3** dashboard, click on the **name** of the bucket, then click on **Permissions** tab. Scroll down to the **Bucket policy** section and click on its **Edit** button.

![image](https://user-images.githubusercontent.com/33374159/119147505-93ca0e80-ba43-11eb-8af4-25792cedf124.png)

Add the following bucket policy to it and make sure to replace `bucket-name` with the name of your bucket.

```
{
"Version":"2012-10-17",
"Statement":[
 {
   "Sid":"AddPerm",
   "Effect":"Allow",
   "Principal": "*",
   "Action":["s3:GetObject"],
   "Resource":["arn:aws:s3:::bucket-name/*"]
 }
]
}
```

Then scroll down and click on **Save changes**.

This should change the bucket **access** to public, as shown below.

![image](https://user-images.githubusercontent.com/33374159/119148274-3da99b00-ba44-11eb-90b7-0997dc76b81a.png)

##Step 4 — Configure S3 bucket <a name="configure"></a>
You need to specify the default page and error page for your website.

From the **S3** dashboard, click on the **name** of the bucket, then click on the **Properties** tab.

Scroll down to the **Static website hosting** section and click on its **Edit** button.

Select **Enable** for Static website hosting.

Also, select **Host a static website** for the Hosting type.

Enter the file for your **Index document** and **Error document**. The **Error document** is optional. I used **signup.html** for both **Index document** and **Error document**.

Scroll down and click on **Save Changes**.

![image](https://user-images.githubusercontent.com/33374159/119148824-cb858600-ba44-11eb-9556-73525506d83a.png)

After saving, If you click on the bucket website endpoint, it would display your website.

![image](https://user-images.githubusercontent.com/33374159/119149050-0982aa00-ba45-11eb-8e45-145fc9427508.png)

##Step 5 — Serve content from S3 bucket with CloudFront <a name="serve"></a>
From the **Services** drop-down, scroll down to **Networking & Content Delivery** section and click on **CloudFront**. This should take you to the CloudFront dashboard.

Click on **Create Distribution**. On **Select a delivery method for your content** page, click on **Get Started** under the **Web** section.

![image](https://user-images.githubusercontent.com/33374159/119149298-4babeb80-ba45-11eb-8550-b06a6642dd35.png)

Under the **Origin Settings** section, click on the **Origin Domain Name** field and select the S3 bucket you created earlier. In the **Origin Path** field, enter **/** to indicate root level.

For **Restrict Bucket Access**, select **Yes**.

For **Origin Access Identity**, select **Create a New Identity**.

For **Grant Read Permissions on Bucket**, select **Yes, Update Bucket Policy**.

![image](https://user-images.githubusercontent.com/33374159/119150705-9aa65080-ba46-11eb-8a75-dc2b14a53807.png)

Scroll down to the **Default Cache Behavior Settings** section. For **Viewer Protocol Policy**, select **Redirect HTTP to HTTPS**.

![image](https://user-images.githubusercontent.com/33374159/119151046-e8bb5400-ba46-11eb-91e4-5883998b75d9.png)

Next, scroll down to the **Distribution Settings** section. Inside the **Default Root Object** field, enter the filename at the root level, which should be your landing page. I used **signup.html** as my **Default Root Object**.

Leave the rest of the options as default and click on **Create Distribution**.

![image](https://user-images.githubusercontent.com/33374159/119151334-320ba380-ba47-11eb-9694-175a62505d7b.png)

Now, you can see the distribution you created from the CloudFront dashboard. It might take a few minutes for it to be deployed.


![image](https://user-images.githubusercontent.com/33374159/119151828-a9413780-ba47-11eb-8363-f689ad363a21.png)

After the CloudFront distribution has been deployed, copy the URL from the Domain Name column and paste it into your browser. Yay!🎉 That’s it!


![image](https://user-images.githubusercontent.com/33374159/119156002-afd1ae00-ba4b-11eb-9133-c652785ebcfc.png)

Now, you can access your website with:
1. CloudFront domain name e.g d3450i4qtm1w2p.cloudfront.net
2. Website endpoint e.g http://demo-95581515414.s3-website-us-east-1.amazonaws.com
3. S3 object URL e.g https://demo-95581515414.s3.us-east-1.amazonaws.com/signup.html

You should now know how to host a static website with Amazon S3 and speed up the content delivery using AWS CloudFront. Even though you had to go through a few steps, you did it and you're awesome!

If you’ve found this article helpful, please leave a heart or a comment. If you have any questions or constructive feedback, please let me know in the comment section.

Also, don’t forget to follow me for more articles. Thank you!