How To: Host static website on AWS S3 + CloudFront
Published: 2023-10-01 10:54:21


Hi. In this article, we will host a simple website on AWS S3.
Also, we will use AWS Cloudfront for https and CDN.

P.S. Hope it will not be a very long article, but if it does - sorry...

## Situation: 

There is a project called [The Cloud Resume Challenge]("https://cloudresumechallenge.dev/") 

The purpose of it is to create a "cloud resume" using public clouds like AWS, Azure, and GCP and to help you bridge the gap from cloud certification to cloud job. It incorporates many of the skills that real cloud and DevOps engineers use in their daily work.

So, related to this challenge, one of the starting points is to create a static HTML page on an AWS S3 bucket and publish it to the Internet as a static website.

## Task:

- Create a simple HTML page with basic CSS styles
- Put into s3 bucket
- Create CloudFront distribution for serving **https** request and **CDN**
- Registry new domain name for website on Namecheap (not covered in this article)
- Create a DNS record on Cloudflare and point it to the CloudFront distribution (not covered in this article)

## Action
So, Let's get started 

### Create a single HTML page with basic CSS styles

- We need to create file **index.html** for our site

  I don't want to describe much more here, just add several useful links for this step.

  - [HTML Tutorial](https://www.w3schools.com/html/default.asp)
  - [CSS Tutorial](https://www.w3schools.com/css/default.asp)
  - [Example html+css templates](https://www.w3schools.com/w3css/w3css_templates.asp) - you can find here Resume/CV template as well
  - [One more HTML Resume example](https://codepen.io/emzarts/pen/OXzmym)

  Also, we can ask ChatGPT to create a simple HTML page.
  
  As a result, we receive some code that we put in our **index.html** file.
  
### Put our index html page into the S3 bucket.

Create an S3 bucket for our site:
- Go to the AWS management console, find S3 in the search bar, and push the **Create bucket** button

![Create bucket](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/c1q91t4iyau1g89nxuyx.png)

- Fulfill the Bucket name and AWS Region field:
  * **Bucket name** - The bucket name must be unique within the global namespace and follow the bucket naming rules. [See rules for bucket naming](https://docs.aws.amazon.com/AmazonS3/latest/userguide/bucketnamingrules.html?icmpid=docs_amazons3_console). We can use the domain name of our future site for simplify as well as any random name.
  * **AWS Region** - General recommendations from AWS are "You can choose any AWS region that is geographically close to you to optimize latency, minimize costs, or address regulatory requirements. For example, if you reside in Europe, you might find it advantageous to create buckets in the EU (Ireland) or EU (Frankfurt) regions. 
  
-  Keep other settings by default and click on **Create bucket** button. 
   If everything goes fine you will see your new bucket in the Buckets list.

![Create bucket button](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/baxnn4r8vk8ohudz95kw.png)

### Upload our file **index.html**:

 - In the Buckets list click on the name of our bucket.
 
 - Click on the **Upload** button then on the **Add files** button.

![Upload](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/zhrp6al85z0x30glk2db.png)
 
![Upload2](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ievvi8z8owfjf7lkerun.png)

 - Choose our file from the browser window and click **Ok**.
 - Click on the **Upload** button.

![Upload3](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/auto0bl7daakncyk4gb1.png)

 - We will see a confirmation message and our file in the bucket.

![confirmation message](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2jriizrf81pmjh9jnf4j.png)


- Click on the **Close** button.


### Create CloudFront distribution

We need to create a CloudFront distribution to serve HTTP requests to our site (S3 bucket). 

Go to the **CloudFront - Distributions.**
![Cloufront distribution](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/cwvkj6hyprgst2oocyhs.png)


 - Click on the **Create Distribution** button. Here we need to choose from the list the origin which is our bucket arn name.
 
![Create Cloufront distribution](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/n671rcxy8eyntf3yjtx8.png)

-  Create origin control Settings. 
In the original access block click on **Create control settings** and click on **Create** (live all the settings by default).  
  
![Create origin control Settings](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/gnnbv2mvugqoru4t179i.png)

![Create origin control Settings2](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/az0aawx6cx0ajei6n3z9.png)

- We need to not forget to update S3 Bucket policy. We can do it after creation distribution or during the creation. It does not matter.

![update S3 Bucket policy](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/gwj0vols4p5up5uqu3vt.png)

- At the **WAF** section settings we choose **Do not enable security protection** at this point in time. 

![WAF](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/mv10exhcdygg6fuzxhq7.png)

- We can use our own domain as an **Alternate domain name (CNAME)** - it is optional and could be skipped.

![CNAME](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ndirf1r2gktossjk1npj.png)

-  In the field **Default root object** set **index.html** for serving all "/" requests to our index.html file.

![Default root object](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/m7qw19ais9h6jy50g8l9.png)

 - Click on **Create distribution** button.

![Create distribution*](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/mzstb101zf546qj111ov.png)

- We will see the successful creation notification and reminder about adding the S3 bucket policy.

![Successful creation notification](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/0va2ogwcu8kncsyrzfoi.png)

- So click on the **Copy policy** button and go to the S3 bucket - click on our bucket and go to the tab **Permission**.

![Permission](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ejootge6hqt31uqky5oa.png)

- Click on **Edit bucket policy** and paste from the clipboard the previously copied policy. Then save it.
![Edit bucket policy 1](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5rvgd9ddgwynx2vqgqau.png)

![Edit bucket policy 2](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/c8j7rqnyp8mzwrxf1p7h.png)

![Edit bucket policy 3](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/lxmhm4keo1kgb30j0dxe.png)

- Go back to the Distributions and copy our **Distribution domain name** like sldkf3ddds.clodfront.net

![Distributions domain name](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xqa8vjgpk1yg5fdgm8lf.png)

- Paste it in the new tab and you will see the content of the index.html page. 

### Invalidations.

There is another thing that we need to remember - when we edit or add files in our S3 bucket we need also to create cache invalidations in the **CloudFront distribution** to make our change available for everyone...
We can do it by going to the **Invalidations** tab in the CloudFront distribution settings.

![Invalidations](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ujjqzxsihs6cgtlbwqts.png)

![Invalidations 2](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/nkpgxfrlacghde7idti8.png)

![Invalidations 3](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/gz7xnpmabqc79xs8hezr.png)


## Result:
So, now we have a personal static website that is hosted on AWS S3 and uses CloudFront for HTTPS requests.

As part of [The Cloud Resume Challenge]("https://cloudresumechallenge.dev/") I added my own domain to the CloudFront distribution Additional CNAME domain settings. https://resume.codecloudmaster.space/

Thanks for reading and feel free to comment and critique.