Setup CloudFront & Amazon S3 to Deliver objects on the Web Apps (securely & efficiently)
Tags: aws, cloud, devops, security
Published: 2023-03-20 12:08:15


## What is S3 ?
- **AWS S3 (Simple storage service)** is an object storage service offering industry-leading scalability, data availability, security, and performance.
- Businesses can store and retrieve any amount of data, at any time, from anywhere on the web. S3 is highly durable and designed to provide 99.999999999% durability of objects over a given year, making it a reliable and secure solution for storing critical data.
- S3 is widely used in storing and serving object on the internet, whether it is images, videos, or any other unstructured data. But when we use S3 with Cloudfront it provides lot of benefits

## What is Cloudfront ?
- Cloudfront is the AWS Content delivery network that speeds up distribution of your static and dynamic web content, such as .html, .css, .js, and image files, to your users.
- CloudFront delivers your content through a worldwide network of data centers called edge locations.

### Here are some applications of CloudFront:

- **Content Delivery:** CloudFront accelerates the delivery of your content by caching your content at edge locations worldwide. This reduces the time it takes for users to access your content and improves the performance of your web applications.

- **Video Streaming:** CloudFront can deliver high-quality video streaming to users worldwide. It can also integrate with AWS Elemental Media Services to provide a complete video streaming solution.

- **Website Security:** CloudFront integrates with AWS Shield to provide protection against DDoS attacks. It also supports SSL/TLS encryption to secure your content in transit.

- **Global Applications:** CloudFront provides a global presence to your application by caching your content at edge locations worldwide. This allows your users to access your content from a location that is geographically closer to them, reducing latency and improving their experience.

- **API Gateway:** CloudFront can be used as a custom origin for API Gateway. This allows you to cache API responses at edge locations, reducing the load on your API backend and improving the performance of your APIs.

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

### Serving S3 objects with CloudFront has several benefits:
![Image 1](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ok1q7v3nvorgut3rvoys.png) 
**1.) Improved performance:** CloudFront is a content delivery network (CDN) that caches content at edge locations around the world. By serving S3 objects with CloudFront, you can improve the performance of your application by reducing latency and improving load times for users located far away from the S3 bucket.

**2.) Reduced costs:** Serving S3 objects with CloudFront can help reduce your data transfer costs by caching frequently accessed content at edge locations. This reduces the number of requests made to the S3 bucket, which can help reduce your data transfer costs.

**3.) Improved security:** CloudFront can help improve the security of your S3 objects by enabling you to restrict access to your content using a variety of authentication methods, such as signed URLs or AWS Identity and Access Management (IAM) policies.

**4.) Customization:** CloudFront provides a range of customization options, such as custom SSL certificates, custom error pages, and content compression, which can help you optimize the delivery of your S3 objects to your users.

**5.) Scalability:** CloudFront is designed to handle high levels of traffic and can automatically scale to accommodate increases in demand. This can help ensure that your application remains highly available and responsive, even during periods of high traffic.

Overall, serving S3 objects with CloudFront is a best practice for many AWS customers who need to distribute their content globally, improve the performance of their applications, and reduce their costs.

## Setup the S3 and Cloudfront for serving objects through Web application.

### <u>**Objective**</u>
1.) Sign in to AWS management console.

2.) Create and setup the **_S3 Bucket (Private)_** to store objects.

3.) Create the **_Cloudfront distrubution_** for your S3 bucket.

4.) Setup the _**IAM role**_ and permissions for Web application.

5.) Finally, test the application !!!

### Steps for Implementation of the project:

#### **1.) Sign in to AWS management console.**
-  First, sign in to the AWS console with your username and password and select the appropriate region like us-east-1.

#### **2.) Create and setup the S3 Bucket (Private) to store objects.**
- Let's search for S3 and open th S3 console 
- Create S3 bucket:
   -  Give a **`globally unique name`** and region to your bucket.  
      ![s3 1](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ooduck2q1rmmdawewg66.png)
   - Set the **`object ownership`** and keep **`ACL's disabled`**.
     ![s3 2](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/h38e23vmm8p3kr07gida.png)
   - **`Block all public access`** -  It provides an additional layer of security for your data, preventing unauthorized access and ensuring that your data is protected at all times.
     ![s3 3](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/mnj8mbc3b6ujibr4j5s1.png)
   - **`Enable the versioning`** -  With S3 versioning, every time an object is updated or deleted, a new version of the object is created, allowing users to access and restore previous versions of the object.
     ![s3 4](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/i07o21symo7a139j1ygb.png)
   - **`Enable the encryption`** - In Server-side encryption, Amazon S3 encrypts your objects before saving them on disks in AWS data centers and then decrypts the objects when you download them. All Amazon S3 buckets have encryption configured by default and all new objects uploaded to an S3 bucket are automatically encrypted at rest
     ![S3 5](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/u9m3xmtdezu6bhdl3c20.png)
   -  **`Object lock`** - It helps to prevent accidental deletion or modification of objects. With Object Lock, you can set a retention period for objects in a bucket, during which time the objects cannot be deleted or modified. For now we'll keep this default.
      ![S3 6](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/pblc7r05jqkzjqxdnz7x.png)
   - Finally click on the **`Create bucket`** 
- Now let's upload some objects in S3 bucket for testing or project.
  ![S3 7](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ue9ci2fjbxq5kpq4t1tg.png)

#### **3.) Create the _Cloudfront distrubution_ for your S3 bucket.**
- Search for clodufront in AWS console search bar & open the cloudfront dashboard. 
- Select the **Origin domain** of your bucket from drop down & give the name of the cloudfront distribution. 
  ![cf 1](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/o4ze2vs0vmlc4u66xvd6.png)
- Set the **origin access** as **Origin access control settings**. 
  ![cf 2](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/mq3nekrwncpfjvi2ffuq.png)
- We also need to  create the _`access control setting`_ for this cloudfrony distro like below:
  ![cf 3](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/f6br0xsqf3hxcpe3hq5n.png)
- **`Enable the Shield`** as it helps to minimize your origin’s load, improve its availability, and reduce its operating costs.
  ![cf 4](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/dryiseq83g6speh9sjay.png)
- In **Default cache behaviour** settings set configurations as below, else keep it default.
  ![cf 5](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/jdvk46t7qv6gggtorqdv.png)
- Let **Function associations - optional** be as _default_ for now.
- In the **final section** i.e. settings, choose as per your usecase and requirements like below:
  - In this we need to choose the **price class** and AWS WAF web ACL we want to associate it with.
  - If we want to add a **custom domain** to the clodfront distribution then we can add it here.
  - In **default root object**, the object you specify will return if user requests root URL.
  ![cf 6](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xui9k6gn7qq9wme7ns6j.png)   
- Once the **Cloudfront Distribution got created** then we need to add the given policy in the respective **`S3 Bucket policy`**. So copy the bucket policy from here.
  ![Cf 7](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/a2f6fy1op406s2zqqukt.png)
- Then **`go to S3 bucket > Permissions > Edit bucket policy`**.
  ![cf 8](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5pqhpu8zx97unkkkgbf9.png)

#### **4.) Setup the IAM role and permissions for Web application.**
![Image 232](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/iqyqdb0rylspntq40s16.png)
- So now, you can use this cloudfront distribution in your applications. 
Usually Applications requires `PutObject`, `GetObject` and `DeleteObject` permissions for S3 bucket For that you need to give your application via _**IAM user or role (recommended)**_
- **The Get Operation (read access but only to web app user not anonymous)** will be handled by Cloudfront.
-  For Put and delete object you need to create an IAM role and attach the below IAM policy.

  ```
    {
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "VisualEditor0",
            "Effect": "Allow",
            "Action": [
                "s3:PutObject",
                "s3:DeleteObject"
            ],
            "Resource": [
                "arn:aws:s3:::cloudfront-demo1-s3/*",
            ]
        }
    ]
}
```
-  Now, assign the **IAM role** to web application server** and you are good to go.

#### **5.) Finally, test the Application !!**
-  Now we can test the cloudfront domain which is setup to deliver the object from private S3 bucket.
- By hitting the `https://Distribution-domain-name/s3-object-name`, it will return as below.
  ![Cf 9](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/re7p0cj9qxod1ku4rvht.png)
- While if we just hit the domain `https://Distribution-domain-name` then it will show us the object that we had set in default root object.
  ![cf 10](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2l61gahqnsglein28t49.png)

###🚩🚩 Note: Some helpful Links:
- [Accelerate your content using Amazon CloudFront](https://catalog.us-east-1.prod.workshops.aws/workshops/9331108e-464e-4699-8a9c-486090105878/en-US)
- [Improve Your Architecture With Amazon CloudFront](https://catalog.us-east-1.prod.workshops.aws/workshops/4557215e-2a5c-4522-a69b-8d058aba088c/en-US/basic-configuration/create-cloudfront-distribution)
- [CONFIGURE AMAZON CLOUDFRONT](https://www.wellarchitectedlabs.com/security/200_labs/200_automated_deployment_of_web_application_firewall/2_config_cloudfront/)
- [Creating Role and setting permissions](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_create_for-service.html)
- [Set up a CloudFront distribution for Amazon S3](https://aws.amazon.com/cloudfront/getting-started/S3/)

<img width="100%" style="width:100%" src="https://dev-to-uploads.s3.amazonaws.com/uploads/articles/fwfpcptd9hu6djzmrk4e.gif">