BK cloud / systèmes Articles
FR
English ENDeutsch DEEspañol ES中文 ZHFrançais FR
Prenons contact ↗
← Retour aux articles

Un site statique qui a du pouls : des statistiques de visite respectueuses de la vie privée sur AWS

Un site statique a quelque chose de délicieusement tranquille. Pas de serveur applicatif à mettre à jour, de pool de connexions à saturer ni d’API publique à maintenir éveillée jour et nuit. Le navigateur demande des fichiers ; le réseau de diffusion les lui fournit.

Cette simplicité posait une question intéressante pour mon portfolio : pouvais-je montrer d’où venaient les consultations et comment le trafic évoluait, sans transformer le site en application dynamique ni publier des informations privées ?

La réponse a pris la forme d’une petite chaîne de données : logs d’accès CloudFront, CloudWatch, Lambda, EventBridge et un objet JSON dans S3. Les visiteurs voient une carte du monde, des totaux par pays, les pages populaires et des courbes de requêtes. Ils ne reçoivent jamais les logs bruts, les adresses IP, les user-agents ni les parcours individuels.

Le site reste statique. Les données sont préparées ailleurs et arrivent sous la forme d’un fichier statique de plus.

L’architecture vue depuis une requête

Le chemin public reste volontairement court :

  1. Un visiteur accède au site via Amazon CloudFront.
  2. CloudFront fournit les fichiers en cache depuis un bucket S3 privé.
  3. Le navigateur récupère ensuite content/public-visitors.json comme n’importe quelle autre ressource statique.
  4. Le JavaScript côté client dessine la carte et les graphiques à partir de ce document anonymisé.

Le navigateur n’appelle pas Lambda, n’interroge pas CloudWatch et ne possède aucun identifiant AWS. Il ne peut pas demander une autre plage temporelle ni des données plus détaillées. Les traitements coûteux et sensibles restent hors du chemin des requêtes publiques.

En coulisses, les données suivent ce parcours :

CloudFront → CloudWatch Logs → scheduled Lambda → aggregated JSON → S3 → CloudFront → browser

Cette séparation est le choix d’architecture essentiel. Le système d’exploitation peut traiter des données d’accès détaillées ; le système de publication ne produit que le sous-ensemble destiné au public.

Collecter une fois, publier moins

La journalisation standard CloudFront version 2 envoie les champs sélectionnés à un groupe CloudWatch Logs. Le journal opérationnel suffit à examiner les requêtes et codes de statut, sans que toutes ces informations aient leur place sur un tableau de bord public.

La fonction de publication réduit délibérément les données à des agrégats :

  • pages HTML consultées avec succès, regroupées par code pays ;
  • chemins HTML les plus demandés ;
  • requêtes par minute calculées à partir des métriques agrégées de statut HTTP ;
  • horodatage de mise à jour et libellés des plages temporelles.

Le fichier ne contient ni IP source, ni localisation à l’échelle d’une ville, ni cookies, ni user-agents, ni séquences retraçant le parcours d’un visiteur. Il répond à « Quel trafic le site a-t-il reçu ? », pas à « Qui est venu ? ».

C’est aussi pourquoi je parle de pages vues, et non de personnes. Un lecteur peut générer de nombreuses requêtes. Robots de recherche, aperçus de liens, sondes de supervision et autres automatisations se mêlent au trafic humain. Le tableau de bord montre des signaux d’infrastructure, pas des identités.

Pourquoi CloudWatch fait l’intermédiaire

CloudWatch offre deux lectures d’une même activité. Logs Insights interroge les enregistrements structurés pour agréger les pays et les pages. Des filtres de métriques comptent les quatre familles HTTP — 2xx, 3xx, 4xx et 5xx — pour produire des séries de débit sans reparcourir chaque événement à chaque fois.

Le jeu de données public propose plusieurs vues :

  • totaux par pays sur 24 heures, 7 jours et 30 jours ;
  • points de débit sur 24 heures, 7 jours, 30 jours et 12 mois ;
  • intervalles plus larges pour les longues périodes, afin de garder un document compact.

Les logs CloudFront ne sont pas un flux temps réel. AWS précise qu’ils arrivent généralement sous une heure, mais que certaines entrées peuvent être retardées davantage. Ils conviennent donc à un tableau rétrospectif présenté honnêtement, pas à un compteur de visiteurs en direct.

Un instantané planifié plutôt qu’une API publique

Une règle EventBridge appelle la fonction Lambda de publication toutes les six heures. Elle lance ses requêtes bornées, récupère les séries de métriques, assemble le document et écrase une seule clé S3 : content/public-visitors.json.

Six heures est un choix volontairement prudent. Les statistiques n’exigent pas une fraîcheur à la seconde, et chaque actualisation analyse des logs. Raccourcir l’intervalle multiplierait les exécutions et les coûts sans rendre la page sensiblement plus utile.

Le JSON est servi avec des en-têtes de cache favorisant la revalidation. L’accueil peut ainsi découvrir un nouvel instantané, tandis que CloudFront protège toujours S3. Actualiser les statistiques n’exige ni déploiement complet du site ni invalidation globale du cache.

Ce modèle a un comportement intéressant en cas de panne : si une requête ou Lambda échoue, le document précédent reste disponible. Les statistiques peuvent vieillir, mais le portfolio reste en ligne et aucune requête n’attend la chaîne d’analyse.

Le moindre privilège limite les dégâts possibles

La fonction de publication utilise un rôle IAM dédié aux autorisations ciblées :

  • lancer et récupérer des requêtes uniquement sur le groupe de logs prévu ;
  • lire les métriques CloudWatch nécessaires au graphique ;
  • écrire uniquement content/public-visitors.json dans le bucket du site ;
  • écrire ses propres logs d’exécution.

Elle ne peut ni déployer d’autres fichiers du site, ni modifier la distribution CloudFront, ni exposer S3. EventBridge peut appeler cette fonction précise depuis la règle planifiée précise.

Le bucket reste privé. CloudFront utilise Origin Access Control pour signer ses requêtes vers S3 et empêcher les internautes de contourner la distribution en accédant directement au bucket.

Une carte publique volontairement moins précise

Plus de détails ne font pas forcément un meilleur tableau de bord public. Les repères par ville impressionnent, mais de petits volumes associés à un horaire précis et à une personne connue peuvent devenir identifiants. Les totaux par pays suffisent à raconter l’audience mondiale du site sans prétendre prouver où vit un lecteur.

La conception visuelle rappelle cette limite. La carte affiche l’intensité par pays et un classement ; un texte juste en dessous précise que les requêtes sont des signaux, pas des personnes. L’interface ne permet pas de descendre jusqu’aux événements individuels.

La nuance compte : un graphique soigné peut inspirer une certitude injustifiée. Un pays déduit d’une IP est une observation de la plateforme de périphérie. VPN, réseaux d’entreprise, opérateurs mobiles, robots et aperçus en cache compliquent la réalité humaine derrière le chiffre.

Le coût suit le volume analysé, pas la complexité visuelle

La carte et les courbes sont rendues dans le navigateur avec le code statique déjà distribué. Leur complexité ne crée donc pas de facture de rendu serveur. Les coûts opérationnels viennent surtout de la collecte et de la conservation des logs, de l’ingestion des métriques et de l’analyse planifiée.

Les garde-fous relèvent de l’architecture, pas de l’esthétique :

  • une rétention des logs de 30 jours évite une croissance indéfinie ;
  • la fonction ne tourne que quatre fois par jour ;
  • les requêtes utilisent des fenêtres bornées et les seuls champs nécessaires ;
  • les longues périodes utilisent des intervalles de métriques plus larges ;
  • le JSON publié est minuscule face aux logs source.

À cette échelle, l’exécution Lambda et le stockage d’un document compact dans S3 sont négligeables. Le volume analysé par Logs Insights est le poste à surveiller si le trafic ou la rétention augmente fortement.

Les enseignements de cette réalisation

Statique ne signifie pas aveugle. L’observabilité peut accompagner un site statique sans entrer dans son chemin de requête synchrone.

L’agrégation forme une frontière de sécurité. La transformation des logs opérationnels en document public doit être explicite, relue et à sens unique.

Une fraîcheur suffisante vaut mieux qu’un faux temps réel. Un instantané toutes les six heures respecte le décalage des logs standard et évite du travail inutile.

En cas d’échec, conserver le dernier état connu. Mieux vaut des statistiques vieillissantes qu’un accueil en panne parce que le service d’analyse est indisponible.

Expliquer les limites à côté du graphique. Une visualisation publique doit préciser l’effet des robots, des requêtes répétées, de la déduction géographique et la différence entre trafic et personnes.

Quand choisir une autre architecture

Ce schéma convient à un site personnel au trafic modéré avec quelques vues prédéfinies. Je le reverrais pour des requêtes libres, des tableaux authentifiés, une fraîcheur à la seconde ou de gros jeux multidimensionnels. Une API, un stockage analytique dédié ou une plateforme gérée pourraient alors se justifier.

Pour ce portfolio, ces ajouts résoudraient un problème que je n’ai pas. Une fonction planifiée et un document statique préservent ce qui rend le site intéressant : une petite surface d’attaque, un comportement prévisible et des composants faciles à comprendre.

Ce qu’il faut retenir

L’élément essentiel de ce tableau de bord n’est pas la carte. C’est la frontière qui la protège.

Les données détaillées restent dans l’environnement d’exploitation. Un traitement au moindre privilège les transforme régulièrement en agrégats anonymisés. Le site reçoit un instantané statique compact, et le navigateur le met en scène.

Le site a ainsi du pouls, sans cœur dynamique vulnérable.

Références