Aller au contenu

CloudFront

On vient de mettre notre contenu angular dans un S3 mais celui-ci ne supporte pas directement de servir un SPA (Single Page Application) en HTTPS pour cela il nous manque une couche de présentation/de distribution de ce contenu, CloudFront va jouer ce role.

Concepts

CloudFront

CloudFront est le CDN de AWS. C'est un service permettant d'accélérer la distribution de nos contenus web statiques et dynamiques.

Cette accélération vient premièrement que les contenus sont servis depuis les régions et edges location d'AWS. On parle de POP, CloudFront Points Of Presence. Le contenu est donc servi au plus près des utilisateurs. Cela permet d'avoir de faibles latences.

De plus les contenus y sont mis en cache, selon des règles que l'on peut définir finement. Si le contenu n'est pas dans le cache du POP, celui-ci tente de le chercher dans le cache regional le plus près. Si ce cache n'était pas chaud le contenu est récupéré depuis l'origin.

Distributions

Sur CloudFront, on configure ce que l'on appelle des Distributions. On y déclare depuis où et comment notre contenu doit être servi.

En effet, il est possible de choisir une parmi les 3 classes de prix. Du moins cher au plus cher, notre contenu peut être servi depuis :

  • 100 - Amérique du Nord, Europe
  • 200 - Amérique du Nord, Europe, Asia, Moyen-Orient, Afrique
  • Tous les POP

Cloudfront supporte différentes origines de contenu : S3 ou un serveur HTTP classique, celui-ci doit par contre être accessible publiquement.

CloudFront permet de forcer le HTTPS et de faire différentes configurations autour de ça (redirections, cypher-suites).

CloudFront Fonctions et Labmda@Edge

CloudFront permet de customiser les requêtes et réponses qui transitent via des programmes que l'on peut écrire.

Ces petits programmes s'appellent des fonctions et AWS les a démocratisées avec son service Lambda. Ces fonctions ne nécessitent pas de création et gestion d'instances, c'est une des briques principales de ce que l'on appelle le serverless.

Les Lambda sont normalement exécutées dans les régions, mais dans le cas de CloudFront, ici, elles sont exécutées aux Edge Locations, d'où Labmda@Edge. Par contre, elles ont quelques limitations.

On peut se servir de ces fonctions pour différents usages :

  • Authentification
  • Authorization
  • Redirections
  • Gestion de Headers
  • Optimisations de cache
  • ...

Pour choisir entre les CloudFront Fonctions et Labmda@Edge, AWS fourni un tableau comparatif.

Globalement lorsque l'on peut, on préfère les CloudFront Fonctions qui doivent être plus légères plus rapides, sous la milliseconde. Elles ne sont, par contre, disponibles que pour la requête ou réponse de l'utilisateur et pas sur celles de l'origin.

Note

Il y a encore beaucoup de fonctionnalités et configurations que l'on ne mentionne pas ici:

  • Optimisations de cache
  • URLs et cookies signés
  • Restrictions Géographiques
  • Logs
  • Protections WAF / Shield
  • Field-level encryption
  • ...

TP

À vous de jouer

Le but de cette étape est donc de mettre en place votre distribution CloudFront servant et optimisant votre site web.

  • Vous pouvez continuer dans le même dossier Step5
  • Créez votre aws_cloudfront_distribution avec les différents paramètres suivants :
    • Votre bucket s3 pour origin avec S3-Origin comme origin_id
    • price_class = "PriceClass_100" pour limiter les coûts
    • Une behavior de cache par défault optimisée
    • Une behavior spécifique pour le index.html désactivant le cache
    • viewer_protocol_policy = "allow-all" pour les deux behavior afin d'autoriser le HTTP

Vous pouvez utiliser les polices de caches managées par AWS en utilisant les datasources Terraform.

data "aws_cloudfront_cache_policy" "managed_cache_disabled" {
  name = "Managed-CachingDisabled"
}

data "aws_cloudfront_cache_policy" "managed_cache_optimized" {
  name = "Managed-CachingOptimized"
}

Pour rappel une référence de datasource doit être préfixée par data. par exemple data.aws_cloudfront_cache_policy.managed_cache_optimized.id

On va pouvoir fixer le problème de 404 sur rafraichissement de page de notre SPA en utilisant les Custom Error Response de CloudFront :

custom_error_response {
  error_code            = 403
  error_caching_min_ttl = 0
  response_code         = 200
  response_page_path    = "/index.html"
}

Warning

Nous ferons la génération de certificats et mise en place de HTTPS avec la prochaine étape.

Par contre CloudFront ne permettant plus de ne faire que du HTTP (HTTP only), pour l'instant, il faut mettre pour les politiques de cache un viewer_protocol_policy en allow-all et mettre sur la distribution la configuration suivante :

viewer_certificate {
  cloudfront_default_certificate = true
}
Ensuite uniquement aller sur le site HTTP et pas HTTPS (même s'il est configuré) via le domaine name CloudFront, en http://xxx.cloudfront.net

Dans le cas contraire vous aurez des erreurs de votre browser ne faisant pas l'appel backend. Par exemple pour Chrome :

Mixed Content: The page at xxx was loaded over HTTPS, but requested an insecure XMLHttpRequest endpoint xxx.
This request has been blocked; the content must be served over HTTPS.

Pour cette étape on ne peut pas utiliser notre joli www.xxx.formation.takima.school car CloudFront voudra un un certificat couvrant le domaine. Nous le ferons dans la prochaine étape.

Note

Si vous avez fait des changements sur l'API_URL ici dans le main.xxx.js alors que celui-ci est déjà dans le cache vous pouvez faire une invalidation de cache pour que votre contenu soit rafaraichi sur les POPs.

Notez que Angular hash les fichiers (JS, CSS) lors de la compilation pour éviter les soucis lors du déploiement de nouvelles versions, et ainsi éviter que d'anciennes versions ne soient chargées. Ainsi on peut mettre une politique de cache optimisée par défault mais par pour l'index.html, car c'est lui qui load les JS, CSS etc. S'il était mis en cache les updates du site auraient des comportements non prévisibles.

Success

Vous avez désormais optimisé votre frontend afin de répondre plus rapidement et tout cela serverless !

Remarquez avec la console de votre browser le comprtement du cache client également. Vous verez des 304 permettant au POP de ne pas renvoyer le payload, car le browser a envoyé lors de la requpete les headers If-None-Match ou If-Modified-Since.

Notez que CloudFront n'ajoute pas tout seul de header Cache-Control sur la réponse c'est à l'origin de les mettre en place, cela permet de moduler également temps de rétentions par objet dans les POPs. Plus de détails ici.

Bonus

CloudFront OAC

Lorsque l'on a CloudFront devant S3, il est conseillé de mettre en place une bucket policy n'autorisant que la distribution CloudFront à accéder aux données via CloudFront Origin Access Control (OAC). Plus de détails ici.

Vous pouvez ainsi remettre toutes les sécurités du aws_s3_bucket_public_access_block et enlever le website hosting de S3.

Faites en sorte de respecter cette best practice.

Tip

Vous devrez ajouter un origin_access_control_id sur l'origin avec l'id du aws_cloudfront_origin_access_control que vous aurez créé.