Hoster son site (presque) statique sur AWS avec S3, CloudFront, Route 53, Certificate Manager et Lambda

Hoster son site (presque) statique sur AWS avec S3, CloudFront, Route 53, Certificate Manager et Lambda

Dans cet article, nous allons démystifier quelques produits proposés par AWS, la solution cloud d'Amazon. Notre objectif sera la mise en place d'un hébergement robuste, résilient pour un site Web statique tel qu'une vitrine de marque ou une page personnelle de développeur par exemple. Pour couronner le tout, nous ajouterons une gestion d'un formulaire de contact en mettant en place un endpoint d'envoi de mail.

Les différents outils

S3

S3, pour Simple Storage Service est la solution de stockage de fichiers d'AWS. Elle se présente sous la forme de buckets (compartiments en bon français) dans lesquels on peut déposer des fichiers. Plusieurs classes de stockage existent, avec des pricing différents en fonction de la disponibilté souhaitée. Par exemple, S3 Glacier est l'équivalent Cloud du stockage sur bandes magnétiques : très peu coûteux, assez rapide en écriture, mais qui peut nécessiter du temps pour la récupération des données : c'est donc très adapté pour stocker vos 10 derrnières années de comptabilité, un peu moins dans le use-case d'hosting de site Web qui nous intéresse dans cet article.

CloudFront

CloudFront est le CDN (Content Delivery Network) proposé par AWS. Son rôle est de permettre l'accès à une ressource Web depuis n'importe où dans le monde, et ce de façon efficiente. Contrairement à la plupart des services, CloudFront n'est pas associé à une région spécifique puisque son but est justement de s'affranchir des contraintes géographiques et d'assurer des délais d'accès rapides depuis le monde entier. Dans notre cas, CloudFront va permettre d'exposer le contenu de notre compartiment de stockage.

Route 53

Route 53 permet de gérer des domaines : il s'agit d'un registrar qui permet de commander des nouveaux noms de domaine (idéal pour tous ces projets personnels qui n'aboutiront jamais, mais dont on ne peut se résigner à abandonner le domaine), ou transférer la gestion de domaines existants. Route 53 gère également la configuration DNS associée à chaque domaine : manuellement pour les redirections vers des services externes, ou bien automatiquement pour les produits AWS : par exemple, si vous utilisez AWS WorkMail pour disposer d'une adresse personnalisée avec un nom de domaine, Route 53 et WorkMail se synchronisent automatiquement pour les enregistrements MX et les URLs d'aurodiscover Exchange.

Certificate Manager

Contrairement à ce que son nom pourrait laisser penser, Certificate Manager est un outil de gestion des certificats ! Il va nous permettre de servir notre site Web en HTTPS avec un certificat SSL lié à notre domaine.

Lambda

Lambda est la solution d'exécution en Serverless d'Amazon. Concrètement, Lambda propose un environnement d'exécution permettant de lancer une fonction. Lambda est compatible avec de nombreux langages et frameworks : Node, .Net, Python, Java, PHP... Une Lambda se compose d'un runtime (la technologie utilisée), et d'un déclencheur : dans notre cas, c'est un appel HTTP à une passerelle qui va déclencher l'exécution de notre Lambda d'envoi de mail.

API Gateway

L'API Gateway est la solution de passerelle HTTP permettant de router du trafic vers différents services et de gérer des problématiques d'API Management telles que du contrôle d'accès, de la gestion de quota etc... Dans notre cas, nous allons utiliser une Gateway pour exposer notre Lambda d'envoi de message de contact sur Internet.

Architecture globale de la solution

Installation de la CLI AWS

Avant de démarrer, on va s'assurer que la CLI est installée et configurée sur votre compte.

En fonction de votre OS, rendez-vous sur cette page :

https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html

Et lancez le script correspondant à votre système : par exemple, sur un Mac, exécutez la commande :

curl "https://awscli.amazonaws.com/AWSCLIV2.pkg" -o "AWSCLIV2.pkg"
sudo installer -pkg AWSCLIV2.pkg -target /

Sur Linux, le process est le même :

curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip"
unzip awscliv2.zip
sudo ./aws/install

Sur Windows, un package MSI est disponible :

https://awscli.amazonaws.com/AWSCLIV2.msi

Et suivez les instructions.

Une fois le paquet installé, vous devez désormais configurer l'accès à votre compte via la commande aws configure.

Vous aurez alors besoin de générer une clé d'accès depuis les réglages de votre compte. Vous pouvez générer jusqu'à 2 clés d'accès, et elles doivent être associées à une identité IAM : attention, générer une clé disposant des mêmes droits que votre utilisateur admin global est une mauvaise pratique et peut s'avérer dangereux en cas de compromission de la clé.

Une fois cette clé d'accès générée, vous pouvez enregistrer l'identifiant et la clé secrète associée dans le prompt de la CLI, choisir votre région par défaut (dans notre cas, eu-west-3 pour Paris), et la CLI est prête pour utilisation.

Mise en place

Création du bucket de stockage

Nous allons commencer par créer un nouveau compartiment pour stocker nos fichiers, et gérer les accès pour en autoriser l'accès en lecture sans authentification : on donne donc un nom à notre compartiment, on choisit la région dans laquelle il va être créé (On choisira autant que possible la région de Paris : eu-west-3 pour les intimes), et on permet l'accès public à notre bucket.

echo '{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "PublicReadGetObject",
            "Effect": "Allow",
            "Principal": "*",
            "Action": "s3:GetObject",
            "Resource": "arn:aws:s3:::website-storage/*"
        }
    ]
}' > /tmp/website_storage_policy.json

aws s3api create-bucket \
    --bucket website-storage \
    --region eu-west-3 \
    --create-bucket-configuration LocationConstraint=eu-west-3
&& aws s3api put-bucket-policy \
    --bucket website-storage \
    --policy file:///tmp/website_storage_policy.json

Création de la distributon CloudFront

Une fois que le compartiment de stockage est créé, il faut lui associer une distribution CloudFront qui permettra de servir les fichiers de manière statique à la manière d'un serveur Apache ou nginx par exemple.

aws cloudfront create-distribution \
    — origin-domain-name website-storage.s3.eu-west-3.amazonaws.com \
    — default-root-object index.html
Enregistrement du domaine et paramétrage DNS

Enregistrement du nom de domaine

Rendez-vous sur la console de Route 53. Il est ici possible de réserver un nouveau domaine, ou de transférer le domaine d'un registrar différent.

Vous pouvez alors rechercher le domaine qui vous intéresse depuis l'interface de recherche, et vérifier s'il est bien disponible, ainsi que le tarif associé. Tous les TLD ne sont pas disponibles au même prix.

Création du certificat SSL

Une fois le domaine créé, il faut alors lui associer un certificat SSL afin de pouvoir servir le contenu de notre site de manière chiffrée, en HTTPS, sur le port 443.

On se rend donc dans Certificate Manager, qui comme son nom l'indique, nous permet de gérer les différents certificats de notre compte AWS.

On renseigne ensuite le nom du domaine auquel on souhaite associer le certificat SSL, puis la méthode de validation. Ici, étant donné que le domaine et le certificat sont gérés par Amazon, on choisit la validation via DNS. Concrètement, AWS va ajouter des enregistrements au niveau du DNS pour s'assurer qu'on est bien le propriétaire du domaine qu'on cherche à sécuriser.

AWS est capable d'ajouter automatiquement ces enregistrements, via Route 53 : aucune opération manuelle n'est nécessaire. Le certificat nouvellement créé est passé au statut "En attente de vérification", et un bouton "Créer les enregistrements dans Route 53" est disponible.

La validation prend ensuite quelques instants.

Après cette étape, votre site est visible sur Internet, et sécurisé par HTTPS.

Il ne nous reste plus qu'à mettre en place le formulaire de contact pour que le monde entier puisse vous écrire à quel point votre site est beau !

Endpoint d'envoi de message exposé sur Internet

Il nous reste désormais 2 étapes :

  • Ecrire un backend exposant un endpoint qui prendra en entrée les données du formulaire de contact.

  • Exposer ce backend via une Lambda AWS et une API Gateway vers Internet.

Pour l'écriture du backend, le but de cet article étant de présenter l'infrastructure Cloud AWS, je vous invite à reprendre l'excellent article d'Olivier Penhoat sur la mise en place d'un backend Node JS avec fastify, ou à utiliser votre techno de prédilection. Lambda supporte de nombreuses technos : Python, Ruby, Java, .Net etc...

Une fois ce backend disponible, il ne reste plus qu'à l'uploader via la CLI pour le déployer.

On commence par créer un rôle d'exécution dans IAM :

aws iam create-role --role-name lambda-ex --assume-role-policy-document '{"Version": "2012-10-17","Statement": [{ "Effect": "Allow", "Principal": {"Service": "lambda.amazonaws.com"}, "Action": "sts:AssumeRole"}]}'

On uploade ensuite notre backend packagé en archive Zip (en remplaçant le rôle par l'ARN du rôle créé à l'étape précédente) :

aws lambda create-function --function-name my-function \
--zip-file fileb://function.zip --handler index.handler --runtime nodejs18.x \
--role arn:aws:iam::123456789012:role/lambda-ex

La Lambda est maintenant prête, et peut être exécutée via la CLI, mais pas encore exposée sur Internet.

On va donc lui associer une Gateway qui va remédier à ce problème. Pour ce faire, rien de plus facile, on se rend dans la console AWS, sur les paramètres de notre Lambda, et on va lui ajouter un Déclencheur sous la forme d'une API Gateway. AWS paramétrera automatiquement tout pour que la Lambda puisse être appelée depuis une URL de notre domaine.

Et voilà, le tour est joué, notre site statique est en ligne, et notre formulaire de contact permet de recueillir les commentaires de nos nombreux visiteurs !

Conclusion

A travers cet article, on a pu se rendre compte de la facilité avec laquelle on peut propulser un site Web scalable à l'infini grâce aux technos AWS. Ici, sans être obligé d'installer un serveur Apache, ou nginx sur un serveur qu'on devra régulièrement mettre à jour, on obtient un hébergement fiable, tirant parti de la puissance du CDN Cloudfront, et un backend hébergé en serverless qui tiendra la charge en cas de sollicitation importante, tout en ne coûtant rien lorsque peu de visiteurs l'utilisent.

La quasi totalité des produits utilisés ici disposent d'un free-tier, qui permet de ne pas avoir à se soucier de la facture tous les mois, du moins tant que les visites restent modérées.