Ce que vous saurez faire à la fin
- Créer un bucket S3 configuré pour héberger un site web statique HTML/CSS/JS.
- Distribuer ce site mondialement via CloudFront avec un certificat HTTPS gratuit (ACM).
- Connecter votre nom de domaine .sn ou .com à CloudFront via Route 53 ou un DNS externe.
- Mettre en place une politique de cache et d’invalidation pour publier des mises à jour rapidement depuis Dakar.
- Maîtriser le coût mensuel d’un site vitrine ou e-commerce léger pour une PME sénégalaise (entre 1 500 FCFA et 25 000 FCFA/mois selon le trafic).
Durée : 4h. Pré-requis : Compte AWS (carte Visa internationale ou Wave Pro), AWS CLI v2 installée, un nom de domaine (ex: monentreprise.sn acheté chez NIC Sénégal pour 15 000 FCFA/an, ou un .com chez OVH/Namecheap à partir de 6 000 FCFA/an), un site statique prêt (généré par Hugo, Jekyll, Astro, ou simplement HTML+CSS).
Étape 1 — Comprendre l’architecture S3 + CloudFront
Amazon S3 (Simple Storage Service) est un stockage objet capable de servir directement des fichiers HTML via une URL publique. Mais S3 seul présente trois limites pour un site sénégalais : latence élevée depuis Dakar (le bucket est dans une région comme eu-west-1 à Paris ou eu-west-3), pas de HTTPS sur un domaine personnalisé, et facturation par requête qui devient coûteuse en cas de pic de visiteurs.
CloudFront, le CDN d’AWS, résout ces trois problèmes. Il met en cache vos pages dans 600+ points de présence dans le monde (dont Lagos, Le Cap, Abidjan, Casablanca pour l’Afrique de l’Ouest), réduit la latence à moins de 80 ms depuis Dakar, gère HTTPS gratuitement, et coûte moins cher que les requêtes S3 directes au-delà de quelques Go/mois.
Étape 2 — Installer et configurer AWS CLI
Téléchargez AWS CLI v2 depuis aws.amazon.com/cli. Sur Windows, lancez l’installateur MSI. Sur macOS et Linux, utilisez le script officiel.
# Vérifier l'installation
aws --version
# aws-cli/2.15.0 Python/3.11.6 Linux/x86_64
# Configurer vos identifiants (créés dans IAM)
aws configure
# AWS Access Key ID : AKIA...
# AWS Secret Access Key : ...
# Default region name : eu-west-3
# Default output format : json
# Tester la connexion
aws sts get-caller-identity
Choisissez la région eu-west-3 (Paris) ou eu-west-1 (Irlande) pour bénéficier d’une latence raisonnable depuis l’Afrique de l’Ouest et d’une facturation en euros plus stable que us-east-1.
Étape 3 — Créer le bucket S3 pour le site
Le nom du bucket doit être globalement unique sur AWS, en minuscules, sans espace.
# Créer le bucket dans la région Paris
aws s3api create-bucket \
--bucket monentreprise-sn-site \
--region eu-west-3 \
--create-bucket-configuration LocationConstraint=eu-west-3
# Activer l'hébergement statique
aws s3 website s3://monentreprise-sn-site/ \
--index-document index.html \
--error-document 404.html
# Vérifier la configuration
aws s3api get-bucket-website --bucket monentreprise-sn-site
Étape 4 — Bloquer l’accès public direct au bucket
Contrairement à l’ancienne pratique consistant à rendre le bucket public, la méthode moderne (recommandée par AWS depuis 2023) consiste à laisser le bucket privé et à autoriser uniquement CloudFront à le lire via une OAC (Origin Access Control). Cela évite que des robots scannent vos fichiers et que vous payiez du trafic non désiré.
# Bloquer tout accès public au bucket
aws s3api put-public-access-block \
--bucket monentreprise-sn-site \
--public-access-block-configuration \
"BlockPublicAcls=true,IgnorePublicAcls=true,BlockPublicPolicy=true,RestrictPublicBuckets=true"
Étape 5 — Téléverser le site web
Préparez votre dossier local avec au minimum un index.html et un 404.html. Synchronisez-le avec S3.
# Synchroniser le dossier local avec le bucket
aws s3 sync ./public/ s3://monentreprise-sn-site/ \
--delete \
--cache-control "public, max-age=3600"
# Pour les fichiers immuables (CSS/JS avec hash dans le nom),
# définir un cache long
aws s3 cp ./public/assets/ s3://monentreprise-sn-site/assets/ \
--recursive \
--cache-control "public, max-age=31536000, immutable"
# Vérifier le contenu uploadé
aws s3 ls s3://monentreprise-sn-site/ --recursive --human-readable
Étape 6 — Demander un certificat HTTPS gratuit dans ACM
CloudFront exige que les certificats SSL soient créés dans la région us-east-1 (Virginie), peu importe où se trouve votre bucket. C’est une particularité historique d’AWS.
# Créer le certificat dans us-east-1
aws acm request-certificate \
--domain-name monentreprise.sn \
--subject-alternative-names www.monentreprise.sn \
--validation-method DNS \
--region us-east-1
# Récupérer les enregistrements DNS de validation
aws acm describe-certificate \
--certificate-arn arn:aws:acm:us-east-1:123456789012:certificate/abc-def \
--region us-east-1
Ajoutez les enregistrements CNAME de validation dans votre zone DNS (chez NIC Sénégal, Cloudflare, OVH, etc.). La validation prend de 5 à 30 minutes.
Étape 7 — Créer la distribution CloudFront
Créez un fichier distribution-config.json contenant la configuration. La méthode la plus simple reste l’interface AWS Console pour la première fois, mais voici la version CLI pour automatiser.
# Créer une OAC pour sécuriser l'accès au bucket
aws cloudfront create-origin-access-control \
--origin-access-control-config \
'Name=monentreprise-oac,SigningProtocol=sigv4,SigningBehavior=always,OriginAccessControlOriginType=s3'
# Créer la distribution avec le fichier de config
aws cloudfront create-distribution \
--distribution-config file://distribution-config.json
# Lister vos distributions
aws cloudfront list-distributions \
--query "DistributionList.Items[].{ID:Id,Domain:DomainName,Status:Status}"
Une fois la distribution créée, AWS renvoie un domaine du type d1234abcd.cloudfront.net. Notez-le, il servira à pointer votre domaine personnalisé.
Étape 8 — Autoriser CloudFront à lire le bucket S3
Mettez à jour la politique du bucket pour autoriser uniquement la distribution CloudFront créée à l’étape 7.
{
"Version": "2012-10-17",
"Statement": [{
"Sid": "AllowCloudFrontServicePrincipal",
"Effect": "Allow",
"Principal": {"Service": "cloudfront.amazonaws.com"},
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::monentreprise-sn-site/*",
"Condition": {
"StringEquals": {
"AWS:SourceArn": "arn:aws:cloudfront::123456789012:distribution/EABCDEFG12345"
}
}
}]
}
aws s3api put-bucket-policy \
--bucket monentreprise-sn-site \
--policy file://bucket-policy.json
Étape 9 — Pointer votre nom de domaine vers CloudFront
Connectez-vous à votre interface DNS (NIC Sénégal pour les .sn, Cloudflare/OVH/Gandi pour les autres). Créez deux enregistrements CNAME ou ALIAS :
| Hôte | Type | Valeur | TTL |
|---|---|---|---|
| monentreprise.sn | ALIAS / ANAME | d1234abcd.cloudfront.net | 300 |
| www.monentreprise.sn | CNAME | d1234abcd.cloudfront.net | 300 |
Si vous utilisez Route 53, créez un enregistrement A de type ALIAS pointant directement vers la distribution :
aws route53 change-resource-record-sets \
--hosted-zone-id Z1234567890ABC \
--change-batch file://route53-record.json
Étape 10 — Configurer la politique de cache et la compression
CloudFront propose des politiques de cache prédéfinies. Pour un site statique, utilisez CachingOptimized et activez la compression Brotli/Gzip pour réduire le poids des pages de 60 à 80 %.
# Lister les politiques managées
aws cloudfront list-cache-policies --type managed
# Politique recommandée : CachingOptimized
# ID : 658327ea-f89d-4fab-a63d-7e88639e58f6
# Vérifier la compression activée sur la distribution
aws cloudfront get-distribution-config \
--id EABCDEFG12345 \
--query "DistributionConfig.DefaultCacheBehavior.Compress"
Étape 11 — Invalider le cache après une mise à jour
Quand vous publiez une nouvelle version (logo modifié, texte corrigé, prix mis à jour), CloudFront continue de servir l’ancienne version jusqu’à expiration du cache. Pour forcer le rafraîchissement immédiat, lancez une invalidation.
# Workflow complet de déploiement
aws s3 sync ./public/ s3://monentreprise-sn-site/ --delete
# Invalider toutes les pages HTML
aws cloudfront create-invalidation \
--distribution-id EABCDEFG12345 \
--paths "/*"
# Pour économiser, n'invalider que les pages modifiées
aws cloudfront create-invalidation \
--distribution-id EABCDEFG12345 \
--paths "/index.html" "/contact.html" "/tarifs.html"
Les 1 000 premières invalidations par mois sont gratuites. Au-delà, comptez 0,005 USD (3 FCFA) par chemin invalidé.
Étape 12 — Sécuriser avec en-têtes HTTP modernes
Créez une Response Headers Policy pour ajouter automatiquement les en-têtes de sécurité recommandés par l’ANSI Sénégal et l’OWASP.
aws cloudfront create-response-headers-policy \
--response-headers-policy-config '{
"Name": "SecurityHeadersPME",
"SecurityHeadersConfig": {
"StrictTransportSecurity": {
"AccessControlMaxAgeSec": 31536000,
"IncludeSubdomains": true,
"Override": true
},
"ContentTypeOptions": {"Override": true},
"FrameOptions": {"FrameOption": "DENY", "Override": true},
"ReferrerPolicy": {
"ReferrerPolicy": "strict-origin-when-cross-origin",
"Override": true
}
}
}'
Étape 13 — Estimer la facture mensuelle pour une PME
| Trafic mensuel | Stockage S3 | Bande passante CloudFront | Requêtes | Total estimé |
|---|---|---|---|---|
| 5 000 visiteurs (site vitrine) | 500 Mo | 3 Go | 30 000 | ~1 500 FCFA |
| 30 000 visiteurs (catalogue) | 2 Go | 20 Go | 200 000 | ~7 000 FCFA |
| 150 000 visiteurs (e-commerce) | 5 Go | 100 Go | 1 200 000 | ~25 000 FCFA |
Activez les budgets AWS pour recevoir une alerte par email dès que la facture dépasse 5 000 ou 10 000 FCFA, afin d’éviter toute mauvaise surprise.
Étape 14 — Automatiser le déploiement avec un script
Créez un fichier deploy.sh à la racine de votre projet pour publier en une commande après chaque modification.
#!/bin/bash
set -e
BUCKET="monentreprise-sn-site"
DIST_ID="EABCDEFG12345"
echo "Build du site..."
hugo --minify # ou : npm run build, jekyll build, astro build
echo "Synchronisation S3..."
aws s3 sync ./public/ s3://$BUCKET/ \
--delete \
--exclude "*.map"
echo "Invalidation CloudFront..."
aws cloudfront create-invalidation \
--distribution-id $DIST_ID \
--paths "/*" \
--query "Invalidation.Id" \
--output text
echo "Site publié sur https://monentreprise.sn"
Erreurs courantes à éviter
- AccessDenied après création du bucket : vous avez oublié la politique du bucket (étape 8) ou l’OAC n’est pas correctement liée à la distribution.
- Certificat ACM créé en eu-west-3 : CloudFront ne le verra pas. Recréez-le impérativement en us-east-1.
- Boucle de redirection HTTPS : vérifiez que la stratégie de viewer protocol est sur « Redirect HTTP to HTTPS » et non « HTTPS only » si certaines pages sont encore en HTTP.
- Site qui affiche l’ancienne version après mise à jour : oubli d’invalidation ou cache navigateur. Testez en navigation privée.
- Facture qui explose après une attaque : activez AWS WAF (à partir de 3 000 FCFA/mois) ou la rate limiting CloudFront, et configurez un budget de coupure.
- Lien direct vers /contact renvoie 403 : ajoutez une fonction CloudFront pour réécrire les URLs sans extension vers /contact.html.
- Aucun trafic chiffré dans Dakar : vérifiez que le edge location servant Dakar est bien Lagos ou Abidjan via curl -I et l’en-tête x-amz-cf-pop.
Checklist de mise en production
- [ ] Bucket S3 créé en eu-west-3 avec hébergement statique activé
- [ ] Accès public bloqué au niveau du bucket
- [ ] Certificat ACM validé et émis en us-east-1
- [ ] Distribution CloudFront créée avec OAC liée au bucket
- [ ] Politique de bucket autorisant uniquement la distribution
- [ ] Domaine personnalisé (CNAME ou ALIAS) pointé vers CloudFront
- [ ] Compression Gzip/Brotli activée
- [ ] En-têtes de sécurité (HSTS, X-Frame-Options) ajoutés
- [ ] Page 404 personnalisée fonctionnelle
- [ ] Script deploy.sh testé localement
- [ ] Budget AWS configuré avec alertes email à 5 000 et 10 000 FCFA
- [ ] Sauvegarde du contenu source sur GitHub/GitLab privé
- [ ] Test de chargement effectué depuis Dakar via webpagetest.org (objectif < 2 s)
- [ ] Documentation interne du workflow de mise à jour partagée à l’équipe