How to Host Static Webpage-CloudFront with S3 (part1)
Tags: cloudfront, aws, s3, security
Published: 2024-02-07 23:50:08


In these steps we will use AWS service CloudFront with S3 bucket. In the next tutorial (part 2), we will add ACM certificate, use Route 53 and improve security of website. 

CloudFront is **Content Delivery Network (CDN)**, one of the benefits of this service is caching content. It improves the read performance, because the content of the website is cached at the different edge locations. The fact, that our content is cached all around the world , then your users all around the world will have: 

- LOWER LATENCY
- IMPROVED THE USER EXPERIENCE BECAUSE OF LOW LATENCY

The best thing is that AWS keeps on adding locations to improve user experience even in the future everywhere. Also the users are protected by DDoS attacks, but you can use also Shield and Web Application Firewall. 


![cloudfront-s3-edge-location](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/obg1ghqdx329o2ztezts.png)


In your AWS account, on the search bar type S3 bucket and create S3 bucket with unique name. 

**a) Create S3 bucket to hold our files for distribution. Name of the bucket should be unique, per example below:**


![cloudfront-with-s3-create-bucket](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/u45dgbcya27ebo6vm85t.png)

Everything else in setup leave by default: 

 - Bucket versioning disabled
 - Tags 
 - Default encryption 
 - IMPORTANT: Block Public Access (LEAVE - you will see later why)
- Object ownership : ACLs disabled



**b) Upload your files in the bucket**

**c) If we try to open index.html (object URL), we will get the message "persmission is denied".**

**d) If we try and go on button "Open" , this generates pre-signed URL for S3 object, which allow us you to see your object.** 

You won't see the image, however, you should probably see the text. Why can't we see the image well? Because the image is not public (in our setup we blocked all public access for S3 for a reason.)


To resolve this "problem" and to see our files we will use CloudFront. CloudFront allow us to see the files, and protect them as well, using distribution, OAI security, S3 policy. In the next steps, we will make secure access to our files using CloudFront.     

In the search bar, type CloudFront and in the right corner you will see that is writing Global. Why? 
CloudFront is global service, you can make global distribution and use all benefits of security for your website. 

**1. Click on "Create distribution"**

    Origin domain: here you will choose your S3 bucket which you create in previous step. 
                   (also you can put here custom origin HTTP domain )

    Origin access: 

        Public: This means that bucket itself must be public (we don't want that because of security)
        **Origin access control settings (OAC) (recommended): ----->>> choose this <<<<<-----**
        Legacy access identities (this is used before)


Click on button "Create new OAC":


![create-new-oac-dialog](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/r7frxyqkxj93y9qw4pbg.png)


Click on "Create":

![create-new-oac](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/bluedn3jvkuo0hh4oxpp.png)


After this, we need to update S3 policy, so that CLoudFront can access the files in S3 bucket, but in MORE SECURE WAY. Files are not PUBLIC, BUT they are SAFE!

In this moment policy for S3 bucket is empty, public access is also blocked,so we need to edit bucket policy so CloudFront could access. 

To check permissions for S3, go to S3 bucket -> Permissions -> Edit and copy policy to allow CLoudFront access to files in S3.


**In CloudFront you can additional setup:** 

    - Disable WAF
    - Viewer protocol policy : Redirect from http to https
    - Default root object is : **index.html**

You can see that we have option, also import ACM certificate in out distribution, but we will come back on this later and show how to import ACM.

![custom-certificate-import](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1w4slyf7aiqlnl1bo0u9.png)


**FOR THIS PART OF DISTRIBUTION, AT THE END CLICK "CREATE DISTRIBUTION"**. We will need to wait a few minutes, maybe even 10 minutes, for our distribution to be created.

After you click to create distribution, you will see yellow warning for S3 to update policy.

You can click on **Copy policy** and then click on sentence "Go to S3 and update policy." This will open new window with Bucket policy, where we need to click on Edit and paste the new policy to allow CloudFront access our files.

**Click "Save changes" button.** 

![warning-for-s3-policy](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ggaork6j9b77ixrvrc12.png)

    {
    "Version": "2008-10-17",
    "Id": "PolicyForCloudFrontPrivateContent",
    "Statement": [
        {
            "Sid": "AllowCloudFrontServicePrincipal",
            "Effect": "Allow",
            "Principal": {
                "Service": "cloudfront.amazonaws.com"
            },
            "Action": "s3:GetObject",
            "Resource": "arn:aws:s3:::awsdevops-demo-bucket/*",
            "Condition": {
                "StringEquals": {
                    "AWS:SourceArn": "arn:aws:cloudfront::55555555555555:distribution/KFHAKLFKFLASFHALSF"
                }
            }
        }
    ]
    }

Explanation of policy: 

We allow the platform service to get object on any file in our bucket (our-bucket/*), as long as the platform distribution is the one we created to access S3 bucket. This policy is generated by AWS and it's correct.


Deploying distribution, we need to wait for message "deployed".

When you see message "**DEPLOYED**", you will copy domain name which will look something like: 

    https://dhssfjsj3w23.cloudfront.net 

Copy the link and in new browser paste it and click enter. You will need to see your page. 

First time you will retrieve  the webpage from S3, all other times when you access your pictures, it will be retrieved from the cache and you will have it immediately in your browser. 



Instagram: aws.devops.resources
Twitter:   awsdevopssource  
GitHub: https://github.com/awsdevopresources
GitHub: https://github.com/JustPLegend