Host a static website on AWS using S3, Route 53, AWS Certificate Manager and CloudFront
Tags: aws, cloud, cloudskills, devops
Published: 2023-05-17 12:53:53

Websites are key to modern day businesses' success. While they are essential, the cost of keeping one up and running can be daunting and this is greatly felt by small business. Seeing as hosting companies charge an arm and a leg for simple static sites, by utilising tools from cloud services like AWS we can achieve highly available and low latency static websites which are easily accessible round the world all at the fraction of the cost, and let’s face it, those hosting companies web load speeds kind of suck. 
&nbsp;
Let’s begin with a brief intro to each service used and then we proceed to build out the architecture. 
&nbsp;
### What is S3? 
Amazon Simple Storage Service (Amazon S3) is an object storage service that offers industry-leading scalability, data availability, security, and performance. Customers of all sizes and industries can use Amazon S3 to store and protect any amount of data for a range of use cases. Amazon S3 provides management features so that you can optimise, organise, and configure access to your data to meet your specific business, organisational, and compliance requirements.
In essence, think of S3 as a massive hard drive in the cloud with unlimited storage space which you can put stuff in and only pay for what you use.  You can [read more about S3.](https://docs.aws.amazon.com/AmazonS3/latest/userguide/Welcome.html)
&nbsp;
### What is Route 53?
Amazon Route 53 is a highly available and scalable Domain Name System (DNS) web service. Route 53 connects user requests to internet applications running on AWS or on-premises. In essence a DNS turns domain names into IP addresses, which allow browsers to get to websites and other internet resources. You can [read more about Route 53.](https://aws.amazon.com/route53/)
&nbsp;
### What is AWS Certificate Manager? 
We use AWS Certificate Manager (ACM) to provision, manage, and deploy public and private SSL/TLS certificates for use with AWS services and your internal connected resources. ACM removes the time-consuming manual process of purchasing, uploading, and renewing SSL/TLS certificates. In essence these certificates ensure that the traffic and from your applications (websites) are secure. More about [certificate manager.](https://aws.amazon.com/certificate-manager/)
&nbsp;
### What is CloudFront?
Amazon CloudFront is a content delivery network (CDN) service built for high performance, security, and developer convenience. It works by storing a copy of your application content at edge locations so it’s faster for your users to download and access them. This significantly speeds up application load time, [more about cloudfront.](https://aws.amazon.com/cloudfront/)
&nbsp;
Now that we know about these services, let’s move on to utilising them in creating a highly available and low latency website. 
&nbsp;
#### Before we proceed, here are basic assumptions i have: 
1. You have a copy of your website file (HTML, CSS, JS and their respective artefacts). 
2. You have a working AWS Account.
3. You have registered a domain name with AWS Route 53 or have utilised the hosted zone feature to connect  your domain to Route 53. If not [learn how to register one on aws](https://docs.aws.amazon.com/Route53/latest/DeveloperGuide/domain-register.html) and i covered how you can [connect an existing domain](https://dev.to/1zyik/how-to-connect-your-namecheap-domain-to-route-53-2i8)
&nbsp;

Alright let’s get started… 
&nbsp;
![Architecture Diagram of Site Hosting](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/hggxfi5vok9lx9nulknr.jpg)
*Image of the static website architecture*
&nbsp;

### Creating the static website with S3

**Step 1:** You navigate to the search bar on the AWS console and search for S3. Click on it to move to S3 Console. Click on create bucket next. 

![AWS search S3](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/t9spbgbb1ptcxz43biiy.png)

![S3 landing page](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/n86wm1o72houenfotuap.png)
&nbsp;
**Step 2:** Input the name of the bucket and ensure it’s the same as the domain name you purchase so `example.com` domain should be represented as `example.com` bucket name. Select a region you prefer. Since we would be using cloudfront you can pick anyone. Leave all the defaults and proceed to create the bucket.
&nbsp;
**Step 3:**  Click the name of the bucket to navigate into it and click upload to upload the static website files from the folder they are stored. Don’t upload the folder, only the files in the folder. You can also drag and drop the files into s3. Wait for the upload to complete and navigate back to the bucket.
![S3 created bucket](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/147b2891jp0hmbw0b4y6.png)
![S3 bucket successful upload](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5scw2ncjwl59tpce6s5w.png)
&nbsp;
**Step 4:** We will then need to configure our bucket so it is publicly available for our CloudFront to access. We can do this by making the bucket publicy accessible and pasting a policy statement into the Bucket Policy.
&nbsp;
To do that we go to **permissions, click edit on Block public access (bucket settings) uncheck the checkbox and click save changes.**

![Making bucket public](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/rzkwp66aup764gp99jgr.png)
&nbsp;
Next you scroll to bucket policy and click edit. We then paste the policy below. 

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

```
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "PublicReadGetObject",
            "Effect": "Allow",
            "Principal": "*",
            "Action": [
                "s3:GetObject"
            ],
            "Resource": [
                "arn:aws:s3:::Bucket-Name/*"
            ]
        }
    ]
}
```
*Make sure to edit the bucket name to match your bucket name.*
&nbsp;
You can make use of [aws policy generator](https://awspolicygen.s3.amazonaws.com/policygen.html) to generate your's.
&nbsp;
We now have a publicly accessible bucket. And it should be indicated at the top of the bucket name. 
&nbsp;
**Step 5:** We’ll also need to enable static website hosting under **properties section, scroll to the bottom and select Static website hosting, click on edit, select enable.**

![Edit static site settings](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/awysvpwd3xc3v8rziqpe.png)
&nbsp;
You will be presented with the option to input your index file and error file. Do so and ensure they are correctly spelt. Click save changes and a static site url would automatically be generated for you. 

![Provide static site file paths](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2kbsm5ulnfcw277nq8ob.png)
![Static site done](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/iggd3qxb267gfg435y40.png)
&nbsp;
Yay! You now have a fully functioning static website on AWS. But we are not stopping there right. 

### Creating a Certificate
Navigate to certificates manager from the AWS search bar. 
![AWS Certificate manager](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/zgcdqfkbntqnr4lqcarf.png)
&nbsp;
Click request certificate 
![Request certificate](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/qojohl1e366nsm3t0ivs.png)
&nbsp;
Provide the details for the domain name and make sure to leave DNS validation on. 
![Creating certificate - step one](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6fdxkypec2c9lrxydx6x.png)

![Creating certifictae - step two](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5ut8lmbr7csgdo9zww8g.png)
&nbsp;
You get a screen like this, showing pending validation. 

![Certificate created](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xnx75azy1loy5jtouvwl.png)
&nbsp;
Click into it and you should see the CNAME name and CNAME values you need to validate with Route 53. 

![Pending resolution](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/lovchd7x3sg49zw1oqtg.png)
&nbsp;
Navigate to the hosted zone of your domain in Route 53 and click add records to your domain. Ensure the value is type of CNAME then copy the CNAME name into the subdomain removing the `.yourwebsite.com`. Also copy the CNAME value into the values box. It should look like this. 

![CNAME record creating](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5xvyqwerb8fmcudmu3yl.png)
&nbsp;
Give it a few minutes and the certificate would be issued. 

![Certificte Issued](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/qedx114b42nnh3rqbbvs.png)
&nbsp;
Our next step is to make the website globally distributed with CloudFront.

### Set up Cloudfront Distribution
Navigate to cloudfront from AWS search bar.

![CloudFront Search](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/wokgb81ykdod73l3ik4d.png)
&nbsp;
Click create a cloudfront distribution

![Creating distribution](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/mm2l00j1oqtqarkfn6w7.png)
&nbsp;
Provide details for the origin by selecting your S3 bucket

![Set origin to S3](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ntxnel7ao7porhd3226w.png)
&nbsp;
Change viewer protocol policy to Redirect HTTP to HTTPS

![Change viewer protocol](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/iuchndic54u32q03ekai.png)
&nbsp;
Select your SSL certificate from the dropdown list and click create distribution

![Choose SSL and finish up](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/hl825snc2h1u9b722qf1.png)
&nbsp;
Give it a few minutes and your distribution should be created. You can verify by copying the link and testing out. 

![CloudFront created successfully](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/hx243iehonst6tvj23g4.png)

### Point Domain to our CloudFront distribution
Navigate back Route53 and select your hosted zone for your domain.
&nbsp;
Then click on add record. 
&nbsp;
This time we are creating an A record, make sure the alias is checked on. Then select your cloudfront distribution and hit save.
&nbsp;
Give it a few minutes and you should have a working website that is secure and globally accessible. 
&nbsp;
Yay!! You did it and i'll see you around..