S3 : créer un bucket et sécuriser les accès
À la fin de ce tutoriel, vous aurez un bucket S3 en
ca-central-1avec Block Public Access, chiffrement, versioning optionnel, une politique de bucket restrictive, et un test d’accès via CLI — sans jamais exposer le bucket au public.Niveau : Débutant · Temps estimé : 50 min · Versions testées : S3 Console / API 2026, AWS CLI v2 · Dernière vérification : 2026-09-11 · Region lab :
ca-central-1← Précédent : EFS · Hub : Démarrer avec AWS
Publish : HOLD
Prérequis
- Profil CLI
lab, Regionca-central-1 - IAM de base (IAM) — idéalement politique
LabS3ListLabPrefixdéjà créée - Budget d’alerte actif (AWS Budgets ≥ 1 USD)
- Comprendre : bucket = conteneur régional ; le nom est globalement unique
export AWS_PROFILE=lab
export AWS_DEFAULT_REGION=ca-central-1
# PowerShell : $env:AWS_PROFILE='lab'; $env:AWS_DEFAULT_REGION='ca-central-1'
Coût estimé lab (ca-central-1, ordres de grandeur 2026) :
| Ressource | Ordre de grandeur | Remarque |
|---|---|---|
| Stockage Standard | ~0,025 USD/Go·mois | Quelques Ko → négligeable |
| PUT / GET | fractions de cent | Lab = dizaines de requêtes |
| Versioning | +stockage des versions | Purgez en nettoyage |
| Data transfer | 0 si reste en Region | Pas de Cross-Region ici |
Supprimez le bucket (et ses versions) en fin de lab. Un bucket versionné oublié avec des Go de logs peut surprendre sur Cost Explorer.
Ce que nous allons construire
Bucket lab-<ACCOUNT_ID>-demo
├── Block Public Access : ON (tout)
├── Encryption : SSE-S3 (AES256)
├── Versioning : Enabled (lab)
├── Bucket policy : Deny non-HTTPS (aws:SecureTransport)
└── Test : put/get object en CLI avec admin-lab
(Schéma — alt : « Bucket S3 privé, BPA, encryption, deny HTTP ».)
Étape 1 — Concepts S3 utiles à la certif
| Concept | À retenir |
|---|---|
| Bucket | Conteneur régional (le nom est globalement unique) |
| Object | Fichier + métadonnées, clé = chemin logique |
| Block Public Access | Filet de sécurité au-dessus des ACL / policies |
| SSE-S3 / SSE-KMS | Chiffrement côté serveur |
| Bucket policy | Resource-based ; complète IAM identity-based |
Nommez toujours vos buckets lab avec un préfixe lab- + account id pour éviter les collisions et coller à la policy lab-*.
Repère examen SA : durabilité S3 Standard ≈ 99,999999999 % (11 neuf) sur plusieurs AZ ; disponibilité conception ~99,99 %. BPA n’est pas un substitut à IAM : c’est un filet anti-fuite publique. SSE-S3 chiffre au repos sans gérer de clé KMS ; SSE-KMS ajoute audit CloudTrail sur l’usage de la clé.
Étape 2 — Créer le bucket
ACCOUNT_ID=$(aws sts get-caller-identity --query Account --output text)
BUCKET="lab-${ACCOUNT_ID}-demo"
echo "$BUCKET"
aws s3api create-bucket
--bucket "$BUCKET"
--create-bucket-configuration LocationConstraint=ca-central-1
--region ca-central-1
En
us-east-1seulement, on ometLocationConstraint. Ici ca-central-1 l’exige.
Console : S3 → Create bucket → Region Canada (Central) → ACL disabled (recommandé) → Block Public Access all coché.
Étape 3 — Block Public Access (vérifier)
aws s3api put-public-access-block
--bucket "$BUCKET"
--public-access-block-configuration
BlockPublicAcls=true,IgnorePublicAcls=true,BlockPublicPolicy=true,RestrictPublicBuckets=true
aws s3api get-public-access-block --bucket "$BUCKET"
Ne désactivez BPA « pour tester un site » sans comprendre CloudFront + OAC (tuto CloudFront plus loin).
Étape 4 — Chiffrement par défaut
aws s3api put-bucket-encryption
--bucket "$BUCKET"
--server-side-encryption-configuration '{
"Rules": [{
"ApplyServerSideEncryptionByDefault": {
"SSEAlgorithm": "AES256"
},
"BucketKeyEnabled": true
}]
}'
Pour KMS (prod) : SSEAlgorithm = aws:kms + KMSMasterKeyID. En lab, SSE-S3 suffit.
Étape 5 — Versioning
aws s3api put-bucket-versioning
--bucket "$BUCKET"
--versioning-configuration Status=Enabled
Utile contre les suppressions accidentelles ; les versions coûtent du stockage — à vider en nettoyage.
Étape 6 — Bucket policy : refuser le HTTP clair
Fichier bucket-deny-http.json (remplacez le nom) :
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "DenyInsecureTransport",
"Effect": "Deny",
"Principal": "*",
"Action": "s3:*",
"Resource": [
"arn:aws:s3:::BUCKET_NAME",
"arn:aws:s3:::BUCKET_NAME/*"
],
"Condition": {
"Bool": { "aws:SecureTransport": "false" }
}
}
]
}
sed "s/BUCKET_NAME/$BUCKET/g" bucket-deny-http.json > /tmp/bucket-policy.json
# PowerShell : (Get-Content ...) -replace ...
aws s3api put-bucket-policy --bucket "$BUCKET" --policy file:///tmp/bucket-policy.json
IAM autorise ; la bucket policy Deny gagne si quelqu’un tente HTTP.
Étape 7 — Put / Get d’un objet test
echo "hello-s3-lab" > /tmp/hello.txt
aws s3 cp /tmp/hello.txt "s3://$BUCKET/demo/hello.txt"
aws s3 cp "s3://$BUCKET/demo/hello.txt" /tmp/hello-downloaded.txt
cat /tmp/hello-downloaded.txt
aws s3api head-object --bucket "$BUCKET" --key demo/hello.txt
Avec la politique LabS3ListLabPrefix sur un user restreint : List/Get OK sur lab-*, Put peut être refusé — c’est voulu pour démontrer le moindre privilège (élargi plus tard).
Preuve chiffrement sur l’objet
aws s3api head-object --bucket "$BUCKET" --key demo/hello.txt --query '{SSE:ServerSideEncryption,Class:StorageClass,Size:ContentLength}' --output table
Vous devez voir AES256 (SSE-S3). En prod avec KMS, la valeur serait aws:kms et un SSEKMSKeyId apparaîtrait.
Étape 7b — Ownership et ACL (2026)
Depuis la réforme Object Ownership, le mode recommandé est Bucket owner enforced (ACL désactivées). Vérifiez :
aws s3api get-bucket-ownership-controls --bucket "$BUCKET"
Si absent, forcez le mode moderne :
aws s3api put-bucket-ownership-controls --bucket "$BUCKET" --ownership-controls 'Rules=[{ObjectOwnership=BucketOwnerEnforced}]'
Ne réactivez pas les ACL « public-read » pour un lab : préférez CloudFront + Origin Access Control dans le tuto CDN.
Tags et Cost allocation
aws s3api put-bucket-tagging --bucket "$BUCKET" --tagging 'TagSet=[{Key=Project,Value=lab},{Key=Series,Value=aws-p1}]'
Les tags aident Cost Explorer et les politiques basées sur aws:ResourceTag plus tard.
IAM vs bucket policy (qui gagne ?)
Ordre mental pour le troubleshooting AccessDenied :
- Deny explicite (IAM ou bucket policy) → toujours refuse.
- Sinon, il faut un Allow sur le chemin identity-based ou resource-based.
- BPA peut bloquer même une policy « Allow public ».
En lab solo, admin-lab avec droits admin n’a pas besoin de bucket policy pour put/get ; la policy Deny HTTP reste utile comme garde-fou. En équipe, combinez groupe IAM lab-s3-readers + bucket privé.
Étape 8 — Vérification
aws s3api get-bucket-location --bucket "$BUCKET"
aws s3api get-public-access-block --bucket "$BUCKET"
aws s3api get-bucket-encryption --bucket "$BUCKET"
aws s3api get-bucket-versioning --bucket "$BUCKET"
aws s3api get-bucket-policy --bucket "$BUCKET"
Checklist : Region ca-central-1 · BPA all true · SSE-S3 · versioning Enabled · Deny insecure transport · objet demo/hello.txt lisible · tags Project=lab présents.
Si un contrôle échoue : reprenez l’étape correspondante (BPA = étape 3, encryption = 4, policy = 6) plutôt que de recréer tout le bucket — sauf en cas de mauvais nom / mauvaise Region.
Nettoyage
# Vider versions + delete markers
aws s3api list-object-versions --bucket "$BUCKET" --output json > /tmp/vers.json
# Approche simple lab (bucket petit) :
aws s3 rm "s3://$BUCKET" --recursive
# Si versioning : utiliser un script de purge ou la console « Empty »
aws s3api delete-bucket-policy --bucket "$BUCKET"
aws s3api delete-bucket --bucket "$BUCKET"
Si BucketNotEmpty : il reste des versions — purgez-les avant delete-bucket.
Contrôle anti-facture :
aws s3api list-buckets --query "Buckets[?starts_with(Name,'lab-')].Name" --output table
aws s3api list-object-versions --bucket "$BUCKET" --max-items 5 2>/dev/null || echo "bucket déjà supprimé"
La liste lab-* doit être vide (ou seulement vos buckets volontaires). Vérifiez aussi S3 → Buckets dans la console ca-central-1.
Erreurs fréquentes
| Symptôme | Cause probable | Correction |
|---|---|---|
IllegalLocationConstraintException |
Mauvaise combo Region / LocationConstraint | ca-central-1 + LocationConstraint=ca-central-1 |
BucketAlreadyExists / BucketAlreadyOwnedByYou |
Nom global déjà pris (ou déjà à vous) | Suffixe account id ; ou réutiliser le bucket existant |
AccessDenied put policy publique |
BPA BlockPublicPolicy |
Ne pas publier ; garder privé + CloudFront + OAC plus tard |
| Objet « disparu » | Mauvaise Region CLI | --region ca-central-1 / AWS_DEFAULT_REGION |
Delete bucket fail / BucketNotEmpty |
Versions / delete markers restants | Empty console ou purge versions puis delete-bucket |
AccessDenied sur put/get |
IAM trop strict ou Deny HTTP mal formé | Vérifier identity policy + get-bucket-policy |
InvalidBucketName |
Traits, majuscules, trop court/long | Minuscules, chiffres, tirets ; 3–63 caractères |
| Confusion ACL vs Ownership | ACL public-read sur bucket moderne |
BucketOwnerEnforced — pas d’ACL ; policy + BPA |
Lab bonus (5–8 min) — Deny HTTP en action
- Gardez la policy
DenyInsecureTransportactive. - Tentez un accès non TLS (outil ou SDK mal configuré) : vous devez obtenir
AccessDenied/InvalidRequestlié à SecureTransport. - Avec la CLI v2 (HTTPS par défaut),
aws s3 cpcontinue de fonctionner — c’est le comportement attendu. - Option : créez un user IAM
lab-s3-readeravecLabS3ListLabPrefixseule, puisaws s3 ls s3://$BUCKET/demo/ --profile lab-reader→ List OK ; uncpupload doit échouer (moindre privilège).
Ce mini-lab ancre deux idées SA : Deny explicite gagne, et BPA + policy ne remplacent pas une IAM identity bien découpée.
Quiz (5 questions)
1. Block Public Access sert surtout à :
– A. Accélérer les downloads
– B. Empêcher une exposition publique accidentelle (ACL/policy)
– C. Remplacer IAM
2. Un nom de bucket S3 est unique :
– A. Par Region seulement
– B. Globalement dans AWS
– C. Par VPC
3. Une bucket policy Deny + aws:SecureTransport: false :
– A. Force l’usage de HTTPS
– B. Ouvre le bucket en HTTP
– C. Désactive le versioning
4. En ca-central-1, create-bucket exige :
– A. Aucun paramètre de localisation
– B. LocationConstraint=ca-central-1
– C. Un VPC endpoint obligatoire
5. Le mode Object Ownership recommandé en 2026 est :
– A. ACL public-read sur chaque objet
– B. Bucket owner enforced (ACL désactivées)
– C. Object writer avec ACL héritées
Réponses : 1‑B · 2‑B · 3‑A · 4‑B · 5‑B
Pour aller plus loin
- S3 security best practices
- Blocking public access
- Prochains tutos : classes/lifecycle · site statique · CloudFront + OAC
Maillage série AWS (P1)
| ← Précédent | EFS |
| → Suivant | S3 classes & lifecycle |
| Aussi | IAM · CloudFront |
Retour parcours AWS — hub de la série et leçons sœurs.



