Logo AWS S3

Amazon S3

Le service de stockage d'objets d'AWS offrant une durabilité de 99,999999999% et une disponibilité inégalée, parfait pour stocker et récupérer n'importe quelle quantité de données, n'importe quand et n'importe où.

Pour les non-initiés

Qu'est-ce qu'Amazon S3 ?

Imaginez un immense entrepôt ultra-sécurisé avec une capacité pratiquement illimitée, capable de stocker tous vos objets précieux. Dans cet entrepôt, chaque objet est soigneusement étiqueté, peut être rapidement retrouvé, et est protégé contre pratiquement toute perte ou dommage. De plus, vous pouvez accéder instantanément à n'importe quel objet à tout moment, depuis n'importe où dans le monde.

Amazon S3 (Simple Storage Service) est l'équivalent numérique de cet entrepôt. C'est un service de stockage d'objets dans le cloud qui offre une durabilité, une disponibilité et une performance exceptionnelles pour stocker et protéger vos données.

Comment fonctionne S3 ?

Buckets et Objets

S3 organise les données en "buckets" (conteneurs) qui stockent les "objets" (fichiers). Pensez aux buckets comme des entrepôts et aux objets comme les articles à l'intérieur.

Fiabilité exceptionnelle

S3 est conçu pour offrir une durabilité de 99,999999999% (11 neuf), ce qui signifie que si vous stockez 10 000 objets, vous pourriez théoriquement en perdre un tous les 10 millions d'années.

S3 est utilisé pour de nombreuses applications, de la sauvegarde et l'archivage de données à l'hébergement de sites web, en passant par le stockage d'applications mobiles et les lacs de données pour l'analyse. Sa flexibilité, sa sécurité et sa scalabilité en font un choix privilégié pour les entreprises de toutes tailles.

Pour les développeurs

Fonctionnement technique

Amazon S3 est un service de stockage d'objets qui stocke les données sous forme d'objets dans des buckets. Son architecture est conçue pour offrir une durabilité et une disponibilité exceptionnelles tout en permettant un accès rapide et une sécurité robuste.

Concepts clés

Buckets et objets

Buckets : Conteneurs de niveau supérieur pour les objets. Ils ont un nom unique globalement et sont associés à une région AWS spécifique.

Objets : Entités de base stockées dans S3, composées de :

  • Données : Le contenu réel de l'objet (fichier)
  • Clé : Identifiant unique de l'objet dans le bucket, formant une structure de pseudo-dossiers avec les "/"
  • Métadonnées : Ensemble de paires nom-valeur (type de contenu, date de dernière modification, etc.)
  • Identifiant de version : Si le versionnement est activé pour le bucket
  • Sous-ressources : ACL, torrent, politique de cycle de vie, etc.

Opérations de base avec AWS SDK

Voici comment utiliser le SDK AWS pour JavaScript avec S3 :

Utilisation de S3 avec AWS SDK pour Node.js
// Exemples d'utilisation du SDK AWS pour Node.js avec S3 const { S3Client, PutObjectCommand, GetObjectCommand, ListObjectsV2Command, DeleteObjectCommand } = require('@aws-sdk/client-s3'); const { getSignedUrl } = require('@aws-sdk/s3-request-presigner'); const fs = require('fs'); // Initialisation du client S3 const s3Client = new S3Client({ region: 'eu-west-3' }); // 1. Téléversement d'un fichier dans un bucket async function uploadFile(bucketName, key, filePath) { try { const fileContent = fs.readFileSync(filePath); const command = new PutObjectCommand({ Bucket: bucketName, Key: key, Body: fileContent, ContentType: 'application/pdf', // Ajustez selon le type de fichier Metadata: { 'x-amz-meta-title': 'Mon document important', 'x-amz-meta-owner': 'user123' }, // Chiffrement côté serveur avec clés gérées par AWS ServerSideEncryption: 'AES256' }); const result = await s3Client.send(command); console.log('Fichier téléversé avec succès', result); return true; } catch (err) { console.error('Erreur lors du téléversement:', err); return false; } } // 2. Récupération d'un fichier depuis un bucket async function downloadFile(bucketName, key, outputPath) { try { const command = new GetObjectCommand({ Bucket: bucketName, Key: key }); const response = await s3Client.send(command); // Création d'un stream d'écriture vers le fichier local const writeStream = fs.createWriteStream(outputPath); // Pipe du corps de la réponse vers le fichier response.Body.pipe(writeStream); return new Promise((resolve, reject) => { writeStream.on('finish', () => { console.log('Fichier téléchargé avec succès'); resolve(true); }); writeStream.on('error', (err) => { console.error('Erreur d'écriture du fichier:', err); reject(err); }); }); } catch (err) { console.error('Erreur lors du téléchargement:', err); return false; } } // 3. Génération d'une URL présignée pour un accès temporaire async function generatePresignedUrl(bucketName, key, expirationSeconds = 3600) { try { const command = new GetObjectCommand({ Bucket: bucketName, Key: key }); const url = await getSignedUrl(s3Client, command, { expiresIn: expirationSeconds }); console.log('URL présignée:', url); return url; } catch (err) { console.error('Erreur lors de la génération de l'URL:', err); return null; } } // 4. Liste des objets dans un bucket async function listBucketObjects(bucketName, prefix = '') { try { const command = new ListObjectsV2Command({ Bucket: bucketName, Prefix: prefix, MaxKeys: 1000 }); const response = await s3Client.send(command); console.log(`${response.KeyCount} objets trouvés dans le bucket`); response.Contents.forEach(item => { console.log(`- ${item.Key} (${item.Size} octets, modifié le ${item.LastModified})`); }); // Gérer la pagination si nécessaire if (response.IsTruncated) { console.log('Résultats tronqués, ContinuationToken pour la page suivante:', response.NextContinuationToken); } return response.Contents; } catch (err) { console.error('Erreur lors de la liste des objets:', err); return []; } } // 5. Suppression d'un objet async function deleteObject(bucketName, key) { try { const command = new DeleteObjectCommand({ Bucket: bucketName, Key: key }); const response = await s3Client.send(command); console.log('Objet supprimé avec succès', response); return true; } catch (err) { console.error('Erreur lors de la suppression:', err); return false; } }

Hébergement de sites web statiques

S3 peut héberger des sites web statiques complets avec HTML, CSS, JavaScript, images et autres fichiers :

Configuration d'hébergement de site statique sur S3 avec Terraform
# 1. Configuration d'un bucket S3 pour l'hébergement de site statique via Terraform resource "aws_s3_bucket" "website" { bucket = "example-static-website" // Les ACLs sont dépréciées dans les nouvelles versions de Terraform AWS Provider } resource "aws_s3_bucket_website_configuration" "website" { bucket = aws_s3_bucket.website.id index_document { suffix = "index.html" } error_document { key = "error.html" } routing_rule { condition { key_prefix_equals = "docs/" } redirect { replace_key_prefix_with = "documents/" } } } resource "aws_s3_bucket_ownership_controls" "website" { bucket = aws_s3_bucket.website.id rule { object_ownership = "BucketOwnerPreferred" } } resource "aws_s3_bucket_public_access_block" "website" { bucket = aws_s3_bucket.website.id block_public_acls = false block_public_policy = false ignore_public_acls = false restrict_public_buckets = false } resource "aws_s3_bucket_acl" "website" { depends_on = [ aws_s3_bucket_ownership_controls.website, aws_s3_bucket_public_access_block.website, ] bucket = aws_s3_bucket.website.id acl = "public-read" } # Politique de bucket pour permettre l'accès public en lecture resource "aws_s3_bucket_policy" "website" { bucket = aws_s3_bucket.website.id policy = jsonencode({ Version = "2012-10-17" Statement = [ { Principal = "*" Action = [ "s3:GetObject" ] Effect = "Allow" Resource = [ "${aws_s3_bucket.website.arn}/*" ] }, ] }) } # 2. Configuration d'un CloudFront avec S3 comme origine pour un site web resource "aws_cloudfront_distribution" "website" { origin { domain_name = aws_s3_bucket_website_configuration.website.website_endpoint origin_id = "S3-${aws_s3_bucket.website.id}" custom_origin_config { http_port = 80 https_port = 443 origin_protocol_policy = "http-only" origin_ssl_protocols = ["TLSv1.2"] } } enabled = true is_ipv6_enabled = true default_root_object = "index.html" price_class = "PriceClass_100" # Utiliser uniquement les emplacements les moins chers # Alias pour le domaine personnalisé aliases = ["www.example.com", "example.com"] default_cache_behavior { allowed_methods = ["GET", "HEAD"] cached_methods = ["GET", "HEAD"] target_origin_id = "S3-${aws_s3_bucket.website.id}" forwarded_values { query_string = false cookies { forward = "none" } } viewer_protocol_policy = "redirect-to-https" min_ttl = 0 default_ttl = 3600 max_ttl = 86400 compress = true } # Configuration pour les fichiers d'erreur personnalisés custom_error_response { error_code = 404 response_code = 404 response_page_path = "/error.html" error_caching_min_ttl = 300 } # Configuration des restrictions géographiques restrictions { geo_restriction { restriction_type = "none" } } # Certificat SSL/TLS viewer_certificate { acm_certificate_arn = "arn:aws:acm:us-east-1:123456789012:certificate/abcdef01-2345-6789-abcd-ef0123456789" ssl_support_method = "sni-only" minimum_protocol_version = "TLSv1.2_2021" } }

Politiques de bucket et sécurité

Les politiques de bucket permettent un contrôle d'accès granulaire basé sur des conditions diverses :

Exemple de politique de bucket S3
{ "Version": "2012-10-17", "Statement": [ { "Sid": "PublicReadForGetBucketObjects", "Effect": "Allow", "Principal": "*", "Action": "s3:GetObject", "Resource": "arn:aws:s3:::example-bucket/*" }, { "Sid": "AllowCloudFrontServicePrincipal", "Effect": "Allow", "Principal": { "Service": "cloudfront.amazonaws.com" }, "Action": "s3:GetObject", "Resource": "arn:aws:s3:::example-bucket/*", "Condition": { "StringEquals": { "AWS:SourceArn": "arn:aws:cloudfront::123456789012:distribution/EDFDVBD632BHDS5" } } }, { "Sid": "DenyUnencryptedObjectUploads", "Effect": "Deny", "Principal": "*", "Action": "s3:PutObject", "Resource": "arn:aws:s3:::example-bucket/*", "Condition": { "StringNotEquals": { "s3:x-amz-server-side-encryption": "AES256" } } }, { "Sid": "RestrictToSpecificIP", "Effect": "Deny", "Principal": "*", "Action": "s3:*", "Resource": "arn:aws:s3:::example-bucket/*", "Condition": { "NotIpAddress": { "aws:SourceIp": [ "192.0.2.0/24", "198.51.100.0/24" ] }, "Bool": { "aws:SecureTransport": "false" } } } ] }

Intégration avec Lambda via des triggers d'événements

S3 peut déclencher des fonctions Icône LambdaLambda lors d'événements spécifiques :

Configuration de triggers d'événements S3 avec Terraform
# Configuration d'un trigger Lambda sur un événement S3 avec Terraform # Définition d'une fonction Lambda qui sera déclenchée lors du téléversement de fichiers resource "aws_lambda_function" "s3_trigger_function" { function_name = "s3-event-processor" handler = "index.handler" runtime = "nodejs16.x" role = aws_iam_role.lambda_exec.arn filename = "lambda_function.zip" environment { variables = { OUTPUT_BUCKET = aws_s3_bucket.processed_bucket.bucket } } } # Création d'une permission pour que S3 puisse invoquer la fonction Lambda resource "aws_lambda_permission" "allow_s3" { statement_id = "AllowExecutionFromS3Bucket" action = "lambda:InvokeFunction" function_name = aws_lambda_function.s3_trigger_function.function_name principal = "s3.amazonaws.com" source_arn = aws_s3_bucket.source_bucket.arn } # Configuration de la notification sur le bucket source resource "aws_s3_bucket_notification" "bucket_notification" { bucket = aws_s3_bucket.source_bucket.id lambda_function { lambda_function_arn = aws_lambda_function.s3_trigger_function.arn events = ["s3:ObjectCreated:*"] filter_prefix = "uploads/" filter_suffix = ".jpg" } depends_on = [aws_lambda_permission.allow_s3] } # Code de la fonction Lambda (index.js) /* exports.handler = async (event, context) => { // Récupération des informations sur l'événement S3 const bucket = event.Records[0].s3.bucket.name; const key = decodeURIComponent(event.Records[0].s3.object.key.replace(/+/g, ' ')); const outputBucket = process.env.OUTPUT_BUCKET; console.log(`Nouveau fichier détecté: ${key} dans le bucket ${bucket}`); try { // Traitement du fichier (par exemple, redimensionnement d'image) // ... // Génération d'un nouveau nom de fichier pour la sortie const outputKey = `processed/${path.basename(key)}`; // Sauvegarde du fichier traité dans le bucket de sortie // ... console.log(`Traitement réussi, résultat sauvé dans ${outputBucket}/${outputKey}`); return { statusCode: 200, body: JSON.stringify({ message: 'Traitement réussi' }) }; } catch (error) { console.error('Erreur lors du traitement:', error); throw error; } }; */

Fonctionnalités avancées

  • Classes de stockage : Différentes options pour optimiser les coûts en fonction des besoins d'accès (Standard, Intelligent-Tiering, Standard-IA, One Zone-IA, Glacier, Glacier Deep Archive)
  • Versionnement : Conservation de plusieurs versions d'un même objet pour la protection contre les suppressions et modifications accidentelles
  • Verrouillage d'objets : Prévention de la suppression ou du remplacement d'objets pendant une période définie (mode gouvernance ou conformité)
  • Chiffrement : Chiffrement côté serveur (SSE-S3, SSE-KMS, SSE-C) et chiffrement côté client
  • Gestion du cycle de vie : Configuration de règles pour transférer automatiquement les objets entre classes de stockage ou les supprimer après une période définie
  • Réplication : Réplication entre régions (CRR) ou dans la même région (SRR) pour la résilience et la réduction de la latence
  • Transfer Acceleration : Transferts de fichiers rapides sur de longues distances via les emplacements edge de CloudFront
  • Points d'accès : Création de points d'entrée dédiés pour les buckets avec des politiques personnalisées
  • Inventaire : Génération de rapports sur les objets et leurs métadonnées pour l'analyse et la gestion
  • Analyses : Analyse des patterns d'accès pour optimiser les classes de stockage et les coûts
  • Sélection d'objets : Requêtes SQL pour récupérer uniquement les données pertinentes d'objets volumineux

Performance et optimisation

  • Préfixes parallèles : Distribution des objets avec différents préfixes pour une meilleure performance (3500+ requêtes PUT/COPY/POST/DELETE ou 5500+ requêtes GET/HEAD par seconde par préfixe)
  • Téléversement multipartite : Division des fichiers volumineux en parties téléversées en parallèle
  • Transfer Acceleration : Optimisation des transferts longue distance
  • CloudFront : CDN pour la mise en cache et la distribution de contenu aux utilisateurs avec une latence minimale
  • S3 Select : Filtrage côté serveur pour réduire la quantité de données transférées
  • Requester Pays : Facturation des frais de transfert de données au demandeur plutôt qu'au propriétaire du bucket

Modèle de cohérence des données

  • Cohérence forte (Strong Read-After-Write) : S3 offre désormais une cohérence forte par défaut pour toutes les opérations GET, PUT et LIST
  • Implications pour les développeurs : Simplification du code, plus besoin d'implémenter des logiques complexes pour gérer les incoherences temporaires
Applications concrètes

Cas d'usage

Hébergement de sites statiques

S3 est parfait pour héberger des sites web statiques avec HTML, CSS et JavaScript. Combiné à Icône CloudFrontCloudFront, il offre une distribution mondiale rapide et sécurisée avec HTTPS et permet d'atteindre une haute disponibilité à moindre coût.

Data lakes et analyse de données

S3 sert de fondation pour des data lakes à grande échelle, permettant de stocker des données brutes dans leur format natif. Avec des services comme Icône AthenaAthena, Redshift Spectrum et Icône AWS GlueAWS Glue, il devient possible d'analyser ces données directement sans nécessiter d'extraction préalable.

Stockage de médias et distribution de contenu

Stockage et distribution efficace de contenus média (images, vidéos, audio) pour les applications et sites web. Avec Icône CloudFrontCloudFront, les contenus sont diffusés rapidement aux utilisateurs du monde entier, réduisant la latence et améliorant l'expérience utilisateur. Les vidéos peuvent être traitées avec Icône MediaConvertMediaConvert.

Sauvegarde et archivage

Solution rentable pour les sauvegardes et l'archivage à long terme grâce aux classes de stockage économiques comme S3 Glacier. Les politiques de cycle de vie permettent de déplacer automatiquement les données vers des stockages moins coûteux à mesure qu'elles vieillissent.

Industries utilisant S3

S3 est utilisé par des entreprises de toutes tailles et dans divers secteurs :

Médias & Divertissement
Services financiers
Soins de santé
E-commerce
Éducation
Secteur public
Biotechnologie
IoT