Read this before implementing S3 and CloudFront using Terraform.
Tags: aws, terraform, project, website
Published: 2021-05-25 21:46:13

2020 was a difficult year for everyone. It tested how we are able to transition from in person interactions to almost being exclusively online in a very short period on time. It also provided us with an opportunity to connect via online platforms from anywhere in the world. As cool as this all has been, I do hope that one day soon the default switches back to in person.

In this article we will imagine that you are working for a company that is about to release a large marketing campaign for one of their newest products and they are expecting thousands of customers to visit its website. Your manager reached out to you and shared this information with you and expressed that he would like you to think of how to build an architecture design for this website.

**Facts to take into consideration**

- Marketing campaign is for few days only
- Company doesn’t know how many viewers this campaign will attract to their website, but they are forecasting thousands for the first couple of days after the campaign launch
- There is a big concern about DoS/DDoS attacks
- Has to be within their budget
- Needs to be reachable fast from anyone anywhere in the world

For the purpose of this article, you will be focusing more on the architecture design where you can host your website to achieve the requirements allocated for this task and not so much on the website development itself.

Having a website is a hot topic this year as every business needs one. You might be asking yourself where can I host this website?

Let me introduce you to 2 powerful AWS services that can help you to start this project by securing a global website content distribution:

- AWS CloudFront
- AWS S3

**Diagram 1: CloudFront and S3.**

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/on85ibhp7dncisl9gcsx.png)

**What method will we be using to deploy this infrastructure?**

We will be deploying this infrastructure as a code (IaC) using Terraform.

**What is Terraform and why is so useful?**

>"Terraform is a tool for building, changing, and versioning infrastructure safely and efficiently. Terraform can manage existing and popular service providers as well as custom in-house solutions.”

[The official Terraform documentation](https://www.terraform.io/intro/index.html)

Terraform is a powerful declarative tool that helps us to manage a vast majority of cloud services as well as provides consistency and visibility of infrastructure changes happening across different workspace and environments. This functionality not only serves as an important improvement to the quality-of-life of our projects but also keeps software engineers and others on the same team informed.

Please note that we can create or configure any AWS server through the AWS management console, but the problem is that it takes time if you do the same thing again and again. By using Terraform, we don't need to sign in on the AWS management console and can finish our work with the command-line alone.

In this project you will encounter 2 modules. One module will help you to deploy an S3 bucket to store your web files and also will be using the S3 bucket website endpoint from the static website hosting feature serving as origin with CloudFront as a CDN.

The second one will help to deploy S3 buckets to store your web files but this time around CloudFront will serve as a CDN as well as an origin. I recommend the second module as you wouldn’t need to enable static website hosting on your bucket because this infrastructure will be using a REST API endpoint from the bucket instead of the website endpoint from the static website hosting feature.

**Terraform templates previous**

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/rtvir269tph75ipnq6kv.png)

**What is CloudFront?**

>"CloudFront is a fast Content Delivery Network (CDN) service. CloudFront will be providing to our project a global distributed network to our design which would serves as a cache content such as images, videos, and static files from distributed data centers called edge locations."

[The official AWS documentation](https://aws.amazon.com/cloudfront/#:~:text=Amazon%20CloudFront%20is%20a%20fast,within%20a%20developer%2Dfriendly%20environment)

While CloudFront improves the user experience when delivering static content, it also can be used to manage multiple user requests while delivering great services to customers. But CloudFront features do not end here. It has awesome built-in security features such as mitigation of DoS/DDoS attacks, Origin Access Identity (OAI) which we will be using to seamlessly control access to our S3 buckets. We can also use the geo-location feature in the CloudFront distribution which can help us to serve our content within certain regions or countries. There are more features than this but for the purpose of this article I’ll only mention a few.

An interesting point to mention is that delivering content through CloudFront will be more cost effective when the number of requests grow compared to S3 as well as when the data being transferred between AWS services and CloudFront does not fall under the data transfer cost.

**What is S3?**

>"Amazon Simple Storage Service (Amazon S3) is an object storage service that offers industry-leading scalability, data availability, security, and performance."

[The official AWS documentation](https://aws.amazon.com/s3/)

Other than being an object storage service S3 also is able to host static websites with client-side techniques such as HTML, CSS, and JavaScript which does not require server-side scripts such as PHP or ASP.NET.

The easiest aspect about having S3 as a website hosting bucket is that we will not need to request a form to host our static website nor pay any initial cost. Once the S3 static website is configured, an Amazon S3 website endpoint is automatically generated for the bucket. We will be using the website endpoint to test speed and performance

Another important cost saving point is that instead of running web servers such as Nginx or Apache on EC2 instances which can be costly we can host the static files in S3.

[S3 simple monthly calculator link here](https://calculator.s3.amazonaws.com/index.html)

Content DNS delivery speed using **CloudFront website** endpoint vs **S3 website** endpoint test

Using AWS CloudFront **name.cloudfront.net** vs **bucketname-x23x.s3.amazonaws.com** website endpoints performance score
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/awlm2s21m4ygozhhhoqc.png)

The request map displays each of the locations the website was profiled from

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7y69xldrxi7e74funpki.png)

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/27dfofbqad78p7ztlh92.png)

Average performance scores provide a basic overview of any location round-trip time.

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/abdc214vpcca3n6cwkl6.png)

**Conclusion**

Both services, AWS CloudFront and AWS S3, complement each other and can provide you with a powerful space to host your website and is worth a try.

**Benefits of using S3 and CloudFront:**

- Faster speed CDN with CloudFront
- Low storage cost with S3 and free data transfer to CloudFront
- Strong security for both

Important to note that this infrastructure can be more robust by adding other servers such as AWS WAF, AWS Shield or Route53 which I will probably be adding in a later article 😊.

Having Terraform in the mix facilitates the creation, destruction of resources, testing and debugging of your projects.

This Terraform project is dynamically designed to deploy one or more S3 buckets depending on your requirements. It also creates a CloudFront CDN association for each bucket.

Functions, arguments and expressions of Terraform that were used in the above project:

[providers](https://www.terraform.io/docs/language/providers/index.html)
[variables and outputs]()
[modules](https://www.terraform.io/docs/language/modules/index.html)
[resources](https://www.terraform.io/docs/language/resources/index.html)
[count](https://www.terraform.io/docs/language/meta-arguments/count.html)
[types and values](https://www.terraform.io/docs/language/expressions/types.html)
[random_string](https://registry.terraform.io/providers/hashicorp/random/latest/docs/resources/string)
[join](https://www.terraform.io/docs/language/functions/join.html)
[splat or [*]] (https://www.terraform.io/docs/language/expressions/for.html)– One of my favorites
[for](https://www.terraform.io/docs/language/expressions/for.html)

[Find the Terraform repo and directions for this project here](https://github.com/ValAug/S3_CloudFront_Webdeployment)

I would like to give a big shout out to my mentor Derek Morgan. Thank you for all of your support all these months and for the amazing course ["More Than Certified in Terraform" the best course out there. Link to the course here.](https://morethancertified.teachable.com/) If you want to connect with him and ask questions about his course, contact him via [LinkedIn Derek Morgan](https://www.linkedin.com/in/derekm1215/) or you can join the [Discord channel here.](https://discord.gg/PvgMBQbV)