Redirection CloudFront
Aperçu
Gardez à l'esprit que cette discussion est un exemple hypothétique.
Nous avons un site statique traduit en trois langues.
Les fichiers sources RST de tous les articles, toutes langues, font référence aux images et aux fichiers PDF du site. Ces fichiers se trouvent tous dans les répertoires images/ et sitepdfs/, à la racine du site.
Les fichiers de chaque langue doivent accéder à ceux des répertoires images/ et sitepdfs/. Or, au lieu de les chercher là où ils se trouvent, ils les cherchent dans les répertoires images/ et sitepdfs/, sous le répertoire spécifique à la langue, plutôt qu'à la racine.
Afin d'éviter de dupliquer ces fichiers sur le système local, j'ai créé des liens symboliques vers les répertoires où ils se trouvent.
Cela fonctionne correctement sur le site local.
S3 ne possède aucun lien symbolique. Nous pourrions les dupliquer dans le bucket S3, ce qui entraînerait un gaspillage d'espace de fichiers redondant.
Pour éviter cette duplication, nous pouvons résoudre le problème en demandant à CloudFront de réécrire les requêtes pour ces ressources afin qu'elles soient placées au bon endroit, obtenant ainsi le même effet que les liens symboliques.
Voici la procédure étape par étape.
Désolé, mais ce qui suit est en anglais. Nous n'avons pas encore eu le temps de le traduire.
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."