CloudFront Redirection

CloudFront Redirection

Overview

Keep in mind this discussion is a hypothetical example.

We have a static site that is translated into 3 languages.

The RST source files in all the articles in all the languages refer to images and pdf files on the site. All these image and pdf files exist unswe images/ and sitepdfs/ under the root directory of the site.

The files for each language must to access those in images/ or sitepdfs/ directories. But instead of looking for them where they are, they look for them in images/ and sitepdfs/ directories under the language specific directory rather than the root.

So to avoid duplicating those files on the local system I created symbolic links there to the actual directories where the files reside.

This works fine on the local site.

S3 does not have any kind of symbolic link. We could duplicate those in the S3 bucket, causing a redundant file waste of space in the S3 bucket.

To avoid the duplication, we can cope with the issue by by having CloudFront rewrite requests for those assets to go to the right place, thereby achieving the same effect as the symbolic links.

This is a step by step of how to accomplish that.

Create the rewrite function

  • Open the AWS Console and navigate to CloudFront.
  • In the left-hand menu, choose Functions.
  • Click Create function.
  • Give the function a name.
  • Paste JavaScript code below into the editor.
  • Click Publish

Name

imageAndPdfRewriter.

JavaScript code

function handler(event) {
    var request = event.request;
    var uri = request.uri;

    // We want to redirect any url like xxx/lang-version.en/images/... to
    // like xxx/images/... and same for .es and .fr cases

    // A list of language subdirectories. Adjust this array if needed.
    var langDirs = ["/lang-version.en", "/lang-version.es", "/lang-version.fr"];

    for (var i = 0; i < langDirs.length; i++) {
        var langPath = langDirs[i];

        // Check if the URI starts with a language path followed by "images" or "sitepdfs".
        if (uri.startsWith(langPath + "/images/") || uri.startsWith(langPath + "/sitepdfs/")) {
            // Rewrite the URI to point to the asset at the root.
            request.uri = uri.substring(langPath.length);
            break; // Exit loop after first match
        }
    }

    return request;
}

Associate the function with your distribution

  • Navigate to your CloudFront distribution.
  • Go to the Behaviors tab.
  • Edit the default behavior (*) that points to your S3 origin.
  • Scroll down to the Function associations section.
  • For the Viewer Request event type, select CloudFront Functions and choose your function Name.
  • Save the changes.

deploy script

For completeness we include a bash script that deploys the local site to S3, but ingnores the symbolic linked directories.

We use the following in a script called deploy.sh to deploy the site to s3.

#!/usr/bin/env bash
#
# Avoid Duplication By using a re-write function to accomplish
# the same effect as a symbolic link to a directory.
#
# This script deploys our site but ignores our symbolic link directories
# images and sitepdfs in each of our language subdirectories.
#
set -euo pipefail

MYPROGNAME=$(basename ${0})
ARG1NAME=${1:-NOARG}


# Set your S3 bucket name
S3_BUCKET="safesite.bernatchez.net"
LOCAL_BASE_DIR="./bucket"
LANGUAGEPREFIX="lang-version"

# 1. Sync the root content first, excluding the language subdirectories.
echo "Syncing root content, including shared assets, to s3://$S3_BUCKET..."
aws s3 sync "$LOCAL_BASE_DIR" "s3://$S3_BUCKET" \
  --delete \
  --exclude "${LANGUAGEPREFIX}*" \
  --follow-symlinks

# 2. Sync each language-specific directory, but explicitly exclude the assets.
# We also use the --no-follow-symlinks flag for safety.
echo "Syncing language-specific files to s3://$S3_BUCKET..."
for lang_dir in "$LOCAL_BASE_DIR"/${LANGUAGEPREFIX}.*; do
    lang_name=$(basename "$lang_dir")
    aws s3 sync "$lang_dir" "s3://$S3_BUCKET/$lang_name" \
      --delete \
      --exclude "images/*" \
      --exclude "sitepdfs/*" \
      --no-follow-symlinks
done

echo "Deployment complete."
Published by Pierre Bernatchez in «infrastructure». Key Words: examples, how to