Dans cet article, je vais expliquer pourquoi et comment déployer un site Web statique généré avec Jekyll (par exemple un blog) dans le cloud, avec Amazon S3 et CloudFront.

De quoi s’agit-t-il exactement?

Commençons par Jekyll: il s’agit de générateur de site Web à partir de fichiers sources au format Markdown. Je ne vais pas rentrer dans les détails de Jekyll ici, donc si vous ne connaissez pas, allez d’abord voir la documentation ;-)

Un site construit avec Jekyll contient uniquement des fichiers statiques: HTML, images, CSS, et éventuellement JavaScript. Pour déployer un tel site en production, il n’y a donc pas besoin de serveur PHP ni de base de données (comme c’est le cas pour un site WordPress): un simple serveur Web (comme Apache ou nginx) suffit.

En fait grâce au cloud, il est même possible de se passer complètement du serveur Web: tous les fichiers du site peuvent être stockés sur Amazon S3 et publiés avec Amazon CloudFront. Amazon S3 (Simple Storage Service) est ce que l’on appelle un Object Store: il permet de stocker en vrac des fichiers de toute taille, et d’y accéder par exemple en HTTP(s) depuis Internet. Amazon CloudFront est un CDN (Content Delivery Network), c’est-à-dire un énorme cache distribué dans le monde entier, qui permet de diffuser efficacement des ressources Web (images, vidéos, fichiers JavaScript, etc.) en les répliquant sur des serveurs proches des utilisateurs.

L’intérêt principal de CloudFront, et d’un CDN en général, est d’améliorer la vitesse et la disponibilité du site. En effet, sans le CDN, toutes les requêtes HTTP sont envoyées sur le(s) serveur(s) Amazon S3 d’une certaine région (celle où vous avez choisi de stocker les fichiers), qui est potentiellement très éloignée des utilisateurs qui accèdent au site, ce qui entraîne une certaine latence réseau. Avec le CDN, les requêtes seront traitées par un serveur plus proche, ce qui diminue la latence si le fichier demandé est déjà mis en cache.

Publication du site sur Amazon S3

Pour cette étape, il faut d’abord souscrire à un abonnement sur AWS (Amazon Web Services), en profitant éventuellement de l’offre d’essai gratuite.

Ensuite, dans la console AWS, il faut choisir le service S3 (dans la catégorie Stockage), et créer un nouveau “compartiment” (bucket), en lui donnant par exemple le nom du site à déployer (disons blog.monsite.com).

Dans les propriétés du compartiment, activer l’option “Hébergement de site Web statique”, noter quelque part l’URL du “Point de terminaison” et mettre index.html comme Document d’index. Pour autoriser l’accès public au site, il faut créer une “Stratégie de compartiment” (bucket policy) dans l’onglet “Autorisations”, et copier le contenu suivant:

{
    "Statement": [
        {
            "Sid": "Acces en lecture",
            "Effect": "Allow",
            "Principal": {
                "AWS": "*"
            },
            "Action": "s3:GetObject",
            "Resource": "arn:aws:s3:::blog.monsite.com/*"
        }
    ]
}

en mettant le nom du compartiment dans le champ “Resource”.

Une fois le compartiment créé, il ne reste plus qu’à générer et copier les fichiers du site. On peut le faire depuis l’interface Web, ou bien avec le client aws en ligne de commande, par exemple comme ceci sous Linux ou macOS:

JEKYLL_ENV=production bundler exec jekyll build --destination ~/blog --incremental
aws s3 sync ~/blog s3://blog.monsite.com

Maintenant pour tester que tout fonctionne, essayez d’ouvrir l’URL notée précédemment (qui devrait ressembler à quelque chose comme http://blog.monsite.com.s3-website.eu-west-3.amazonaws.com), et normalement le site devrait apparaître !

Configuration de CloudFront

Pour l’instant, le site est déjà accessible sur Internet depuis Amazon S3, mais l’objectif était que tout le trafic passe par le CDN d’Amazon, autrement dit CloudFront.

Avant de configurer CloudFront, il faut d’abord créer un certificat SSL/TLS pour votre nom de domaine, pour pouvoir accéder au site en HTTPS. Cherchez “Certificate Manager” dans la console AWS, et suivez les instructions.

Une fois le certificat SSL/TLS crée, il faut retourner dans la console AWS, ouvrir le service “CloudFront”, et choisir “Créer une distribution”. A l’étape 1, choisir “distribution Web”, puis à l’étape 2, remplir les champs suivants:

  • Nom du domaine d’origine: mettre le domaine du site créé sur Amazon S3, dans notre cas blog.monsite.com.s3-website.eu-west-3.amazonaws.com. Attention! Il ne faut pas choisir blog.monsite.com.s3.amazonaws.com, sinon le site ne fonctionnera pas correctement (les URLs des sous-répertoires du site ne s’afficheront pas)

  • Stratégie de protocole d’utilisateur: choisir l’option “Rediriger HTTP vers HTTPS”

  • Autres noms de domaines (CNAME): mettre votre nom de domaine (blog.monsite.com)

  • Cerfificat SSL personnalisé: choisir le certificat SSL/TSL créé précédemment

Enfin, cliquer sur “Créer une distribution” pour finaliser la création.

Maintenant vous pouvez accéder à votre site avec le nom de domaine CloudFront indiqué dans la console, par exemple https://d115ozry1ec5gl.cloudfront.net.

La dernière étape est de déclarer votre nom de domaine comme un alias (CNAME) du domaine CloudFront. La procédure exacte dépend de votre fournisseur de DNS, mais dans tous les cas l’enregistrement DNS devrait ressembler à quelque chose comme:

blog.monsite.com.   IN  CNAME d115ozry1ec5gl.cloudfront.net.

(attention à ne pas oublier le . à la fin du CNAME !)

Et voilà, si vous avez suivi toutes les étapes, vous devriez avoir un site https://blog.monsite.com rapide comme l’éclair, servi par Amazon CloudFront !

Contrôle du cache

Malheureusement, les ennuis vont commencer dès que vous voudrez faire une mise à jour de votre site.

En effet, si vous essayez de modifier la page d’accueil et de la republier sur Amazon S3, il y a de fortes chances que les modifications n’apparaissent tout simplement pas, même en forçant un raffraîchissement de la page dans le navigateur !

Pour éviter ce problème, il faut éditer les propriétés du fichier index.html dans la console S3, et ajouter la métadonnée Cache-Control avec la valeur no-cache, ce qui indiquera à CloudFront (et au navigateur) qu’il faut toujours envoyer une requête au serveur d’origine (S3 dans ce cas) pour vérifier si le fichier n’a pas été modifié depuis la mise en cache.

Si le mal est déjà fait, il est possible d’invalider manuellement un fichier mis en cache dans CloudFront, en choisissant “Créer une invalidation” dans l’onglet “Invalidations” de la console CloudFront.