Récupérer un fichier supprimé dans S3 : restauration via le versioning

Vous venez de supprimer un objet S3 par erreur — une commande aws s3 rm lancée sur le mauvais préfixe, ou un script de nettoyage trop agressif. Si le versioning était activé sur le bucket au moment de la suppression, l'objet n'est pas vraiment parti : S3 a simplement posé un delete marker par-dessus. Ce guide explique comment localiser la version précédente et la restaurer sans perte de données.

TL;DR — Récupération rapide d'un fichier supprimé dans S3

ÉtapeActionCommande clé
1Vérifier que le versioning est actifaws s3api get-bucket-versioning
2Lister toutes les versions de l'objetaws s3api list-object-versions
3Identifier le delete markerChercher "IsDeleteMarker": true dans la sortie
4Supprimer le delete markeraws s3api delete-object --version-id <marker-id>
5Vérifier la restaurationaws s3api head-object

Comment fonctionne le versioning S3 et la suppression d'objets

Avant de toucher au CLI, il faut comprendre ce que S3 fait réellement quand vous supprimez un objet dans un bucket versionné. Ce n'est pas une suppression physique — c'est une opération d'écriture déguisée.

Quand vous exécutez aws s3 rm s3://mon-bucket/mon-fichier.csv sans spécifier de --version-id, S3 ne supprime aucune donnée. Il crée un objet spécial appelé delete marker : une nouvelle version de l'objet, sans contenu, qui devient la version courante. Toutes les requêtes GET ultérieures retournent un 404 NoSuchKey — l'objet semble disparu, mais les versions précédentes sont intactes.

Pour restaurer l'objet, il suffit de retirer ce delete marker. S3 fera alors remonter la version précédente comme version courante.

stateDiagram-v2 state "Objet accessible (v1)" as V1 state "Objet inaccessible (DELETE MARKER actif)" as DM state "Objet restauré (v1 courante)" as RESTORED [*] --> V1 : Objet créé avec versioning actif V1 --> DM : aws s3 rm (sans --version-id) S3 crée delete marker dm1 DM --> RESTORED : aws s3api delete-object --version-id dm1 Delete marker supprimé RESTORED --> [*] : GET retourne v1 normalement
  1. État initial : l'objet existe avec une version ID v1.
  2. Après suppression sans version-id : S3 crée un delete marker (dm1) qui devient la version courante. Les GET retournent 404.
  3. Après suppression du delete marker : la version v1 redevient courante. L'objet est accessible normalement.

Étape 1 — Confirmer que le versioning est activé sur le bucket

Avant tout, vérifiez l'état du versioning. Si le versioning n'était pas actif au moment de la suppression, les étapes suivantes ne s'appliquent pas — l'objet est définitivement perdu.

aws s3api get-bucket-versioning \
  --bucket mon-bucket-production \
  --region us-east-1

La réponse attendue pour un bucket versionné :

{
    "Status": "Enabled"
}

Si la réponse est vide ({}) ou contient "Status": "Suspended", le versioning était inactif ou suspendu. Dans ce cas, les versions précédentes ne sont pas disponibles pour les objets supprimés après la suspension.

Étape 2 — Lister toutes les versions de l'objet supprimé

Cette étape est celle que la plupart des gens ratent en allant directement dans la console. La commande list-object-versions retourne à la fois les versions réelles et les delete markers — c'est la seule façon de voir l'état complet de l'objet.

aws s3api list-object-versions \
  --bucket mon-bucket-production \
  --prefix mon-dossier/mon-fichier.csv \
  --region us-east-1

Exemple de sortie :

🔽 Afficher la sortie complète
{
    "Versions": [
        {
            "ETag": "\"d41d8cd98f00b204e9800998ecf8427e\"",
            "Size": 204800,
            "StorageClass": "STANDARD",
            "Key": "mon-dossier/mon-fichier.csv",
            "VersionId": "abc123XYZ789",
            "IsLatest": false,
            "LastModified": "2024-03-10T14:22:31.000Z"
        }
    ],
    "DeleteMarkers": [
        {
            "Owner": {
                "DisplayName": "mon-compte",
                "ID": "a1b2c3d4e5f6..."
            },
            "Key": "mon-dossier/mon-fichier.csv",
            "VersionId": "dm456DEF012",
            "IsLatest": true,
            "LastModified": "2024-03-15T09:11:05.000Z"
        }
    ]
}

Deux éléments à noter dans cette sortie : le delete marker a "IsLatest": true et une date postérieure à la dernière version réelle — c'est la confirmation visuelle que l'objet a été supprimé après cette version.

Étape 3 — Identifier le delete marker et la version à restaurer

Dans la sortie précédente, repérez deux identifiants :

  • VersionId du delete marker : c'est celui que vous allez supprimer (dm456DEF012 dans l'exemple).
  • VersionId de la version à restaurer : la version avec "IsLatest": false et la date la plus récente avant la suppression (abc123XYZ789).

Si plusieurs versions existent, choisissez celle dont le LastModified correspond à l'état que vous souhaitez récupérer.

Le delete marker fonctionne comme un post-it 'ne pas lire' collé sur le dossier. Retirer le post-it ne recrée pas le fichier — il était là depuis le début.

Étape 4 — Supprimer le delete marker pour restaurer l'objet

C'est l'opération de restauration elle-même. En supprimant le delete marker avec son version-id explicite, vous demandez à S3 de retirer cette version spécifique — et la version précédente redevient courante automatiquement.

aws s3api delete-object \
  --bucket mon-bucket-production \
  --key mon-dossier/mon-fichier.csv \
  --version-id dm456DEF012 \
  --region us-east-1

La commande retourne le VersionId supprimé et un champ DeleteMarker: true confirmant que vous avez bien supprimé un marker et non une version réelle.

{
    "DeleteMarker": true,
    "VersionId": "dm456DEF012"
}

Étape 5 — Vérifier la restauration de l'objet S3

Ne supposez pas que ça a fonctionné. Un head-object sans --version-id interroge la version courante — si la restauration a réussi, vous obtenez les métadonnées de l'objet au lieu d'un 404.

aws s3api head-object \
  --bucket mon-bucket-production \
  --key mon-dossier/mon-fichier.csv \
  --region us-east-1

Réponse attendue après restauration réussie :

{
    "LastModified": "2024-03-10T14:22:31.000Z",
    "ContentLength": 204800,
    "ETag": "\"d41d8cd98f00b204e9800998ecf8427e\"",
    "VersionId": "abc123XYZ789",
    "ContentType": "text/csv",
    "Metadata": {}
}

Le VersionId retourné doit correspondre à la version que vous souhaitiez restaurer — pas au delete marker supprimé.

Cas alternatif : restaurer une version spécifique sans supprimer les autres

Si vous ne voulez pas simplement annuler une suppression mais revenir à une version précise parmi plusieurs (par exemple, récupérer l'état d'il y a 3 jours alors que des modifications ont eu lieu depuis), la méthode est différente : copiez la version cible sur elle-même. Cette opération crée une nouvelle version courante avec le contenu de la version choisie.

aws s3api copy-object \
  --bucket mon-bucket-production \
  --copy-source mon-bucket-production/mon-dossier/mon-fichier.csv?versionId=abc123XYZ789 \
  --key mon-dossier/mon-fichier.csv \
  --region us-east-1

Cette approche préserve l'historique complet des versions et est préférable quand l'audit trail est important.

Expérience terrain : le piège du versioning suspendu

Voici un scénario réel qui arrive plus souvent qu'on ne le pense. Un bucket a le versioning activé depuis des mois. Un jour, une équipe infra suspend temporairement le versioning pour optimiser les coûts de stockage, puis le réactive quelques semaines plus tard. Entre-temps, des objets sont modifiés et supprimés.

Le symptôme : list-object-versions retourne bien des versions pour certains objets, mais pas pour ceux supprimés pendant la période de suspension. La console S3 affiche le bucket comme 'versionné' — ce qui est techniquement vrai pour l'état actuel.

Le diagnostic erroné : 'le versioning ne fonctionne pas sur ce bucket'. En réalité, le versioning fonctionnait parfaitement — mais les objets supprimés pendant la suspension n'ont pas de delete marker récupérable. Ils ont été supprimés comme dans un bucket non versionné.

Le vrai diagnostic : vérifier les dates. Si LastModified du delete marker tombe dans la fenêtre de suspension, la version est irrécupérable via cette méthode. La seule issue est une restauration depuis une sauvegarde externe (AWS Backup, réplication cross-region, ou snapshot applicatif).

Un détail que la documentation ne met pas en avant : quand le versioning passe de Suspended à Enabled, les objets écrits pendant la suspension ont un VersionId nul (null). Ces objets apparaissent dans list-object-versions avec "VersionId": "null" — ce qui peut prêter à confusion lors d'une restauration.

Permissions IAM requises pour la restauration

Les opérations de restauration nécessitent des permissions spécifiques. Voici la politique minimale pour exécuter les étapes décrites dans ce guide :

🔽 Afficher la politique IAM minimale
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "ListerVersionsObjets",
      "Effect": "Allow",
      "Action": [
        "s3:ListBucketVersions",
        "s3:GetBucketVersioning"
      ],
      "Resource": "arn:aws:s3:::mon-bucket-production"
    },
    {
      "Sid": "RestaurerObjets",
      "Effect": "Allow",
      "Action": [
        "s3:GetObject",
        "s3:GetObjectVersion",
        "s3:DeleteObjectVersion",
        "s3:PutObject"
      ],
      "Resource": "arn:aws:s3:::mon-bucket-production/*"
    }
  ]
}

Note importante : s3:DeleteObjectVersion est distinct de s3:DeleteObject. Sans cette permission, la suppression du delete marker échouera avec une erreur AccessDenied — même si l'utilisateur a le droit de supprimer des objets normaux. C'est une distinction que beaucoup de politiques IAM existantes ratent.

Récupérer un fichier supprimé dans S3 : prévention et bonnes pratiques

La restauration après coup fonctionne, mais la vraie protection vient de la configuration préventive.

  • MFA Delete : activez MFA Delete sur les buckets critiques pour exiger une authentification multi-facteur avant toute suppression de version ou désactivation du versioning. Cela bloque les suppressions accidentelles et les scripts mal configurés.
  • S3 Object Lock : pour les données réglementaires ou les sauvegardes, Object Lock en mode COMPLIANCE empêche toute suppression, y compris par le compte root, pendant la période de rétention définie.
  • Réplication cross-region (CRR) : une copie dans une autre région avec versioning indépendant protège contre les suppressions en masse et les incidents régionaux.
  • Surveillance via CloudTrail : activez CloudTrail avec journalisation des événements de données S3 pour auditer toutes les opérations DeleteObject et identifier rapidement l'origine d'une suppression.

Conclusion et prochaines étapes

La récupération d'un fichier supprimé dans S3 avec le versioning activé se résume à une opération : supprimer le delete marker. Mais la fiabilité de cette récupération dépend entièrement de l'état du versioning au moment de la suppression — pas au moment de la restauration.

Pour aller plus loin :

Glossaire

TermeDéfinition
Delete MarkerVersion spéciale sans contenu créée par S3 lors d'une suppression dans un bucket versionné. Rend l'objet inaccessible sans le supprimer physiquement.
Version IDIdentifiant unique assigné par S3 à chaque version d'un objet dans un bucket versionné.
Versioning suspenduÉtat d'un bucket où le versioning a été désactivé après avoir été actif. Les nouvelles écritures ne créent plus de versions, mais les versions existantes sont conservées.
MFA DeleteProtection supplémentaire exigeant une authentification multi-facteur pour supprimer des versions d'objets ou modifier l'état du versioning.
S3 Object LockMécanisme WORM (Write Once Read Many) empêchant la suppression ou modification d'objets pendant une période définie.

Related Posts

Commentaires

Posts les plus consultés de ce blog

Groupes IAM AWS : Pourquoi Attacher les Politiques aux Groupes Plutôt qu'aux Utilisateurs

LSI vs GSI dans DynamoDB : choisir le bon index secondaire

NAT Gateway vs NAT Instance : Quelle solution choisir pour vos instances privées ?