Declare a Front End App on S3 via CloudFront with high-level design
Tags: aws, devops, react, webapp
Published: 2023-07-03 07:54:30

![WebApp Deployment Architecture](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/bhu14mcwe5i39l07a7bk.png)

---

## What?
In this post, we will host a static website on an S3 bucket with Route53, CloudFront and AWS Certificate Manager. The Website need to ensure high security with these Acceptance Criteria:
- S3 bucket must be not public. 
- End user can not access the Amazon CloudFront and AWS S3 
- End user can only access the WebApp via the Domain

The CDN which has the permission to view the S3 bucket privately with the help of bucket policy.

---

## Why do we have this post? 
At the beginning, I want to have a WebApp for my kid that is called **_FingerMath_** App. This will be a simple React App on Front End. You can find out what is the FingerMath methodology at the end of this post.

Also, I want to have a solution that will be cost effective and scalable with high performance. For this reason, I choose the combination of S3, CloudFront on AWS. With this architecture, end user can access the the WebApp via the CDN which has the permission to view the S3 bucket privately with the help of bucket policy.

---

## Why do we need S3 and CloudFront?

In summary, combining AWS S3 and CloudFront provides a scalable, highly available, and cost-effective solution for storing and delivering static websites globally with improved performance and security.

![S3 and CloudFront](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/efxwr9cx0bntybr110ee.jpg)

**_- Scalability and High Availability:_** S3 provides highly scalable and durable storage for static website assets, ensuring that the website can handle high traffic and remain available even during peak usage. CloudFront, as a globally distributed CDN, further enhances scalability by caching and delivering content from edge locations close to the user, reducing latency and improving performance.
**_- Cost-Effectiveness:_** S3 and CloudFront offer cost-effective solutions for hosting and delivering static websites. S3 provides affordable storage options, while CloudFront's pay-as-you-go pricing model helps optimize costs by minimizing data transfer and reducing bandwidth costs.
**_- Global Content Delivery:_** CloudFront caches website content in edge locations worldwide, ensuring that users can access the website quickly regardless of their geographical location. This improves the website's performance and user experience by reducing latency and improving load times.
**_- Security and Access Control:_** S3 provides robust security features. CloudFront supports SSL/TLS encryption and provides options for securing content delivery.
**_- Easy Management and Deployment:_** AWS provides user-friendly tools and APIs for managing S3 buckets and CloudFront distributions.

---

## How? 

Overall, we will complete the task in four steps:
1. Create and update S3 bucket
2. Request certificate with AWS Certificate Manager
3. Setup CDN with CloudFront
4. Create an alias DNS record on Route53

---

## Let's begin

**1. Create and update S3 bucket**
**_1.1. Create S3 bucket_**
Login into your AWS account, on the top center of the AWS console, jump to the search bar at the top and search for S3

![Create and update S3 bucke](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xqggo8neejq1nr2zprsu.png)


Inside the S3 dashboard, click on **_Create bucket_**.

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


In bucket name, please fill out the bucket name we want to create (e.g. **_finger-math-app-bucket-v2_**). Also, please confirm these options: 
- ACLs disabled (recommended)
- Block all public access
- All other options just like default

**_1.2. Set up S3 for static website hosting_**
After creating the bucket successfully, open this bucket and switch to Properties Tab and search the **_Static website hosting_** section, click on **_Edit_** button

![Set up S3](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/q1crdgbjg2ni0d347id1.png)


The default option be **_Disable_**, change it to **_Enable_**. Also, Fill out the index document and Error document with **_index.html_**
![Set up S3](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ll957t4mma7r9qif099q.png)

**_1.3. Upload build files to S3 bucket_**
Use some tools to upload the build folder such as: AWS Console, AWS CLI, Jenkins, Github Actions, Bitbucket pipelines, …

![Upload build files to S3 bucket](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/vz9lkqvfq9uw5lnithzz.png)


**2. Request certificate with AWS Certificate Manager**
On the top center of the AWS console, jump to the search bar at the top and search for Certificate Manager and click on this service.
When the AWS Certificate Manager is opened,  click on **_Request certificate_** and then choose the Option **_Request a public certificate_** to obtain new SSL certificate.
![Request certificate with AWS Certificate Manager](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/a6rqqven7pokqsa9sn3x.png)

On the next step, fill out the information as below and then click **_Request_**:
- Domain names, e.g fingermath-v2.primax.cloud
- Validation method, e.g. DNS validation - recommended
- Key algorithm, e.g RSA 2048

![Request certificate](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6f7e790q5dda37wvc8ra.png)


After the certificate is requested successfully, we need to create DNS records in Amazon Route 53 for validation by clicking on the created certificate.
![Request certificate](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ks59gne0neqeyi6rxgk2.png)

On next step, at the section **_Domains_**, click on button **_Create Records_** in Route 53

![Create Records in Route 53](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/q1k40ooyc44pyl1oh9qc.png)


On next step, click on **_Create records_**

![Create records](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9rq7jqu2sfnw2wg5r26f.png)


After a few minutes, the Status will change from **_Pending Validation_** to **_Issued_**

![Create records result](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/x4qrw3nwdaj07axbek0l.png)


**3. Setup CDN with CloudFront**
On the top center of the AWS console, jump to the search bar at the top and search for CloudFront and click on this service.
When the **_CloudFront_** is opened,  click on **_Distributions_** and then choose **_Create distribution_**.

![Setup CDN with CloudFront](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/wvslvcn0m7r0s0y97w0j.png)


On the next step, make sure that: 
- The S3 bucket that we have created on Step 1.1 as **_Origin Domain_**, e.g. finger-math-app-bucket-v2.s3.ap-southeast-1.amazonaws.com
- **_Legacy access identities_** as **_Origin access_**: We need to create the OAI (Origin access identity) for this by clicking on Button **_Create new OAI_**. Choose a specific name, for example: finger-math-app-bucket-v2-OAI and then click **_Create_**. Please note that the bucket policy will need to select Option **_Yes, update the bucket policy_**.

![Create OAI](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1285zgx028i229vtg0m5.png)


- Redirect HTTP to HTTPS as Viewer protocol policy 
- GET, HEAD, OPTIONS as Allowed HTTP methods
- Do not enable security protections as **_Web Application Firewall (WAF)_**
- A domain name created on Step 2.1 as **_Alternate domain name (CNAME)_** (e.g.: fingermath-v2.primax.cloud)
- HTTP/2, HTTP/3 as **_Supported HTTP versions_**
- The certificate that we have requested on Step 2.1 as **_Custom SSL certificate_**
- index.html as **_Default root object_**
- All other options just like default

After we click on Create distribution, AWS will deploy in several minutes (~ 10 mins). After deploying successfully, the Last modified will change from **_Deploying_** to a **_specific datetime_** (e.g. July 1, 2023 at 9:37:42 AM UTC)

**4. Create an alias DNS record on Route53**

On the top center of the AWS console, jump to the search bar at the top and search for Route53 and click on this service.
When the **_Route53_** is opened,  click on your Hosted zone (e.g. primax.cloud) and then click on your Domain name

![Create an alias DNS record on Route53](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7ebbnt14uh7pgd2qhc3f.png)


On the next Step, you will see a list of records of your Domain Name. Click on **_Create record_**
![Create records on Route53](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/emhitpi9il4le08sb00y.png)

On the next Step, make sure to choose:
- Your preferred subdomain as **_Record name_** (e.g. fingermath-v2)
- Turn on the **_Alias_** radio button
- Alias to CloudFront Distribution as **_Route traffic_** to
- Choose the Cloud Front that you have created on Step 3￼
- All other options just like default

![Create an alias DNS record on Route53](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/y6rfxna4pz2x7jea1xsk.png)


And voila, your website is going online in few minutes (~5 mins)

**_Thank you for reading the post._**

---

P/S: I have created a React App that will teach the Kids how to calculate with Finger Math methodology on this website https://fingermath.primax.cloud/. So, please be free to use this.


> Finger Math is a mathematical technique that uses fingers as a visual aid for performing calculations. It is commonly used as a tool to teach basic arithmetic concepts, particularly addition and subtraction, to young children.

> Finger Math helps children develop number sense, improve their counting skills, and gain a conceptual understanding of basic arithmetic operations. It engages their tactile and visual senses, making math more tangible and accessible. It is often used as a foundational learning tool before children progress to mental math strategies.

![FingerMath methodology](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/i3a0urbjx89c8aesgrv2.jpg)


If you found the topic helpful, you can buy me a coffee with this [link](https://www.buymeacoffee.com/hoangnph). Thank you so much.