Redirección de CloudFront
Descripción general
Tenga en cuenta que esta discusión es un ejemplo hipotético.
Tenemos un sitio web estático traducido a tres idiomas.
Los archivos fuente RST de todos los artículos en todos los idiomas hacen referencia a imágenes y archivos PDF del sitio.
Todos estos archivos se encuentran en images/ y sitepdfs/, en el directorio raíz del sitio.
Los archivos de cada idioma deben acceder a los directorios images/ o sitepdfs/. Sin embargo, en lugar de buscarlos donde se encuentran, los buscan en los directorios images/ y sitepdfs/, en el directorio específico del idioma, en lugar de en el directorio raíz.
Entonces,Para evitar la duplicación de esos archivos en el sistema local, creé enlaces simbólicos a los directorios donde residen.
Esto funciona correctamente en el sitio local.
S3 no tiene ningún tipo de enlace simbólico. Podríamos duplicarlos en el bucket de S3, lo que causaría una pérdida de espacio redundante.
Para evitar la duplicación, podemos solucionar el problema haciendo que CloudFront reescriba las solicitudes para que esos recursos se dirijan al lugar correcto, logrando así el mismo efecto que con los enlaces simbólicos.
A continuación, se explica paso a paso cómo lograrlo.
Lo Siento pero lo que sigue es en Ingles. Todavia no tuvimos tiempo para traducirlo.
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."