Skip to main content

AWS - Static Website Hosting with S3 and Cloudfront, Geo Restriction, Cloudfront Functions, CloudFront Cache Invalidation

674 words·
AWS S3 Cloudfront Geo Restriction Cloudfront Functions https
Table of Contents

S3 Version without SSL Certificate
#

This tutorial is just a quick solution for testing purposes. It deploys a static websites consisting of html, css and js files. It provides no SSL/TSL encryption and the content of the S3 Bucket is public.

Disable and acknowledge the “Block all public access” option:

Go to the permissions section of your S3 Bucket and past the following configuration, replace s3.jklug.work with the name of your Bucket:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "PublicReadGetObject",
            "Effect": "Allow",
            "Principal": "*",
            "Action": [
                "s3:GetObject"
            ],
            "Resource": [
                "arn:aws:s3:::s3.jklug.work/*"
            ]
        }
    ]
}

Go to Objects Section of your S3 Bucket and upload an index.html file like this one:

<!DOCTYPE html>
<html>

<head>
	<title>jklug.work</title>
</head>

<body>
	<h1>S3 Static Website</h1>
</body>

</html>

Open the permissions section of your S3 Bucket, enable static website hosting and define an index document, in the example it’s “index.html”:

Save the changes, copy the bucket website endpoint and open it in a browser. Note that the website is not encrypted:

Cloudfront Version with SSL/TSL Certificate
#

This tutorial uses a S3 Bucket to host a static website but it’s content is only accessable through a Cloudfront Distribution. The Cloudfront Distribution also provides the necessary encryption the provide secure data transfair.

Create S3 Bucket
#

Create a new S3 Bucket with standard settings. The “Block all public access” option should be enabled by default:

Go to Objects Section of your S3 Bucket and upload an index.html file like this one:

<!DOCTYPE html>
<html>

<head>
	<title>jklug.work</title>
</head>

<body>
	<h1>S3 Cloudfront</h1>
</body>

</html>

Create Cloudfront Distribution
#

Select your S3 Bucket, enable the “Origin access control settings” and click the “Create control setting” buttion:

Create a control setting and make sure it’s selected in the main view:

Enable the “Redirect HTTP to HTTPS” option:

Select a price class / region, select your SSL certificate - note: for CloudFront the SSL Certificate must be in the us-east-1 region - and define a default root object, in the example the root object is “index.html”:

Create the CloudFront Distribution, open the objects section of your distribution, select the origin name and click “edit”:

Copy the origin access control bucket policy - it should look like in the example below - and past it as permission to your bucket policy:

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

Add Access Policy to S3 Bucket
#

Open the permissions section of your S3 Bucket and paste the policy:

Route 53 DNS entry
#

Open Route 53 and create an DNS entry to routes the traffic to your CloudFront Distribution:

Open your URL in a Browser, note that it’s secure now:

Cloudfront: Geographic Restrictions
#

Option it can be useful to allow traffic to your website only from specified countries. Open the Geographic Restrictions Panel of your CloudFront Distribution:

Choose allow list and select the desired countries:

Test the Whitelist Settings with Geo Browse:
https://geotargetly.com/geo-brow

Cloudfront Function: Redirect to index.html
#

For some web applications it’s necessary to create a function that adds index.html to the end of every URL. This is common with static site generators. Open the CloudFront / Function Panel and create a new function:

Copy and paste the following function and save the changes:

function handler(event) {
    var request = event.request;
    var uri = request.uri;
    
    // Check whether the URI is missing a file name.
    if (uri.endsWith('/')) {
        request.uri += 'index.html';
    } 
    // Check whether the URI is missing a file extension.
    else if (!uri.includes('.')) {
        request.uri += '/index.html';
    }

    return request;
}

Go to the Publish section of your functiona and publish it:

After the function is published add an association / your CloudFront Distribution:


CloudFront Cache Invalidation
#

The remove all files from the cache, for example after the websites was updated, proceed as follows:

  • Select the Distribution
  • Open the “Invalidations” Tab
  • Click “Create invalidation”
  • Add object paths: /*

This invalidates all files in the distribution.