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

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.