Host a static website in AWS S3 bucket through Cloudfront CDN
Tags: aws, s3, cdn, website
Published: 2023-11-16 18:09:23

# Introduction
In today's digital era, having a well-structured, functional website is a must for any business or individual seeking to maintain an online presence.  In this blog, we'll walk you through the process of hosting a static website on an Amazon S3 bucket, and using CloudFront for the Content Delivery Network (CDN). Let's get started.

>
> This guide assumes you have a basic understanding of AWS and have the source code for your website ready to go. 
>
> We'll be building the source code with Astro framework. 
>

**Why did I choose to host my website on an S3 bucket ?**
Because this is a flexible and low maintenance solution, compared to hosting on a server. Once the setup is done, the website update requires only a folder upload to a bucket. Also is it a very low cost solution, depending on the number of visits, starting at a few cents par month in my case, for a personal website with very low traffic.

# Step by step guide

> 
> The requirements for this guide : 
> - the source code for a static website
> - an AWS account
> - a DNS hosted in Route 53 (or the provider of your choise), domain name as `your.website.url` in this tutorial
> - bucket name as `my-bucket-name` in this tutorial
> 

## 1. Preparing your website source code
First of all, we will need the sources for our static website, built by the framework of your choise, or in plain HTML/JS/CSS if you prefer. 

In my case, I'm developing my website with Astro framework with static site feature. 
```sh
npm install
npm run build
```

This command line installs all required Nodejs dependencies, and builds the final source code for the static website. 
By default the sources are generated in the folder `dist/`. This content will be uploaded to our S3 bucket in order to host as a website. 

Is is important to have the following pages in the root of your website.
- `/index.html`, the homepage for your website
- `/error.html`, the default error page, in the following example I also have a `404.html` page, for 404 not found error redirections. 


## 2. Configuring a Static Website on Amazon S3
Once the source code for the website is prepared and the final sources are built, the next step is creating a bucket on Amazon S3 and uploading the prepared source files. This process involves setting up the S3 bucket, enabling the static website hosting, adjusting permissions, and setting up error redirection.

### Setting Up the S3 Bucket
Navigate to Amazon S3's Bucket Management and create a new bucket : 
- Bucket name : my-bucket-name
- AWS region of your choise
- Uncheck option "Block all public access", this sets the bucket as public. 
- Make sure to acknowledge the security settings and keep the default configurations.
- Once the bucket is created, upload the source files from step 1

>
> *Check out [AWS S3 bucket naming best practices](https://docs.aws.amazon.com/AmazonS3/latest/userguide/bucketnamingrules.html)*
>

### Enabling Static Website Hosting
Next, enable the static website hosting in the bucket properties. 
- Go to your bucket, then under tab Properties
- Edit the Static website hosting and enable 
- Hosting type : "Host a static website"
- Index document : index.html (or the name of your homepage in the source files)
- Error document : error.html (or your specific error page in the source files)

Save the changes made.

**You will find the static website URL for your bucket under the Properties tab, section Static website hosting**

>
> *Find more usefull information in the [AWS documentation S3 : Enabling website hosting](https://docs.aws.amazon.com/AmazonS3/latest/userguide/EnableWebsiteHosting.html)*
>

### Adjusting Permissions
At this stage, when you navigate to the website URL, you may encounter an error `403 Forbidden with code : AccessDenied`. 
We will resolve this issue by adjusting the permissions in the bucket edition.
- Go to your bucket, then under Permissions tab
- Scroll to Bucket Policy and edit 
- Paste the following policy and set up your bucket as the resource (*replace `my-bucket-name` with your bucket name*)
- Finally save the changes.

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

>
> *Refer to the [AWS documentation S3 : Setting permissions for website access](https://docs.aws.amazon.com/AmazonS3/latest/userguide/WebsiteAccessPermissionsReqd.html)*
>

### Setting Up Error Redirection (optional)
To provide a better user experience, you can set up automatic redirection to a custom page for non-existing pages (404 error). This process involves setting up redirection rules in the static website hosting configuration of your bucket.
- Go to your bucket then under tab Properties
- Edit the Static website hosting configuration
- Paste the following redirection rule, adapt according to your setup (*replace `my-bucket-name.s3-website.eu-west-3.amazonaws.com` with your S3 bucket website host*)

```json
[
    {
        "Condition": {
            "HttpErrorCodeReturnedEquals": "404"
        },
        "Redirect": {
            "HostName": "my-bucket-name.s3-website.eu-west-3.amazonaws.com",
            "ReplaceKeyWith": "404.html"
        }
    }
]
```

>
> This step is optional. Checkout the possible redirections rules in the [AWS documentation S3: Configuring a webpage redirect](https://docs.aws.amazon.com/AmazonS3/latest/userguide/how-to-page-redirect.html?icmpid=docs_amazons3_console)
>

## 3. Configuring SSL Certificate and CDN
After setting up the static website on Amazon S3, the next step is securing your domain with an SSL certificate and setting up a Content Delivery Network (CDN) using Amazon CloudFront.

### Requesting an SSL Certificate
Navigate to the Certificate Manager and request a new certificate for your domain. 
- Remember that the certificate must be in the us-east-1 region, this is a Cloudfront requirement for now (november 2023) 
- Request a public certificate
- Domain name : `your.website.url`
- Choose the validation method that better suits you (DNS or email)
- Once the certificate is requested, the status is in "Pending validation"

>
> *Follow the instructions for the validation process according to the chosen method, by email or DNS*
>

### Validating certificate through Route 53 
>
> *If your DNS is not hosted in AWS Route 53, refer to the documentation of your DNS provider. You will need the CNAME name and value in the SSL certificate page*
> 

- Go to Route 53 under your DNS
- create a new record type CNAME
- copy the name and value from SSL certificate in the previous step

The validation process may take a few minutes to complete. 

## 4. Setting up CDN and DNS for your website
Now that we have our website running in our S3 bucket and that we have a SSL certificate for our custom DNS, we can complete the Cloudfront CDN setup and finally configure the website domain name. The domain name will redirect to the Cloudfront distribution. 

### Create your Cloudfront distribution
- Navigate to CloudFront and create a new distribution
- In the origin domain, paste your S3 bucket website host : `my-bucket-name.s3-website.eu-west-3.amazonaws.com` (*replace with your S3 bucket website host*)  
- Choose request redirects from HTTP to HTTPS
- Choose the certificate that you've just validated
- Add an alternate domain, pointing to your DNS `your.website.url`

>
> If you do not see the certificate, it might be one of the following : 
> - try to refresh the page, or the refesh button next to the certificate selection
> - is the SSL certificate valid ?
> - is the SSL certificate in the correct region required by Cloudfront (us-east-1 as of november 2023)
>

### Setting up domain name to Cloudfront distribution

>
> *If your DNS is not hosted in AWS Route 53, refer to the documentation of your DNS provider. You will redirect your custom domain name to the Cloudfront distribution domain name found under the Cloudfront distribution and General tab. The domain name looks like the following : `<dsitribution ID>.cloudfront.net`*
> 

#### Route 53
The last step is setting up your domain to point to the Cloudfront distribution. 
- Go to in Route 53
- Create an new record
- Name is your custom domain `your.website.url`
- Select Alias, and choose `Alias to CloudFront distribution`. 
- Choose your created distribution 

After a few minutes, your website will be available through your custom domain with the proper SSL certificate.

#### Other DNS providers
- Go to your DNS provider
- Create an new A record
- Name is your custom domain `your.website.url`
- Value is the CDN distribution host : `<dsitribution ID>.cloudfront.net`

# Conclusion
In conclusion, hosting a static website on Amazon S3 is a practical, low cost and efficient method for maintaining an online presence. The process involves building the website's source code, configuring the static website on Amazon S3, securing the domain with an SSL certificate, and setting up a CDN with Amazon CloudFront.

This guide covered each of these steps in detail, from setting up the S3 bucket and enabling static website hosting, to adjusting permissions and setting up error redirection. Additionally, it touched on the steps to secure your domain, request an SSL certificate, and set up a CDN. Lastly, it highlighted the importance of finalizing DNS setup to ensure your website is available with the appropriate SSL certificate.

By following these guidelines you can create, host, and manage their static websites in a secure and reliable environment. This not only ensures a seamless user experience but also leverages the power and flexibility of Amazon's web services ecosystem.