Aller au contenu

PD-4 — Retour d'expérience


📚 Navigation User Story | Document | | | ---------- | -- | | 📋 [Spécification](PD-4-specification.md) | | | 🛠️ [Plan d'implémentation](PD-4-plan.md) | | | ✅ [Critères d'acceptation](PD-4-acceptability.md) | | | 📝 **Retour d'expérience** | *(ce document)* | [← Retour à storage](../PD-198-epic.md) · [↑ Index User Story](index.md)

1. Résumé exécutif

La User Story PD-4 visait à provisionner l'infrastructure de stockage primaire AWS S3 avec Object Lock (WORM) pour assurer l'immutabilité des archives ProbatioVault. Trois buckets devaient être créés : documents (COMPLIANCE, 3-100 ans), audit (COMPLIANCE, 50 ans), et backups (GOVERNANCE, 30j). L'implémentation fournit un module Terraform worm_glacier avec sous-modules (paris, frankfurt, monitoring), Object Lock COMPLIANCE, versioning, et bucket policies restrictives. Cependant, 2 écarts MINEURS sont identifiés : SSE-S3 au lieu de SSE-KMS avec clé dédiée, et transition Glacier à J+1 (défaut variable) au lieu de J+90. Verdict : ACCEPTÉ AVEC RÉSERVES.


2. Points fluides

  • Object Lock COMPLIANCE : mode COMPLIANCE correctement configuré (irréversible, root ne peut pas bypass)
  • Versioning activé : prérequis Object Lock respecté sur tous les buckets
  • Bucket Policies restrictives : DenyAllDeletes + HTTPSOnly sur documents et audit
  • Public Access Block : toutes les options à true (block_public_acls, block_public_policy, etc.)
  • Bucket Ownership Controls : BucketOwnerEnforced pour désactiver ACLs
  • S3 Access Logging : activé vers bucket dédié avec préfixes séparés
  • Lifecycle abort_incomplete_multipart : nettoyage uploads incomplets après 7 jours
  • prevent_destroy : protection Terraform contre suppression accidentelle
  • Tags de conformité : NF-Z42-013, ISO-14641, RetentionMax documentés
  • Module modulaire : organisation paris/frankfurt/monitoring avec variables configurables
  • Validation variables : retention_years 1-100, environment dev/staging/prod
  • Noncurrent version transition : anciennes versions vers Glacier après 30 jours

3. Points difficiles

Difficulté Contexte
SSE-KMS non implémenté SSE-S3 (AES256) utilisé au lieu de SSE-KMS avec clé dédiée Paris
Défaut transition J+1 Variable lifecycle_transition_days défaut à 1, spec demande 90
Bucket Backups absent Spec mentionne 3 buckets, seuls documents et audit implémentés
Rétention dynamique Spec demande 3-100 ans par document, implémentation = rétention fixe par bucket
IAM roles non créés Spec demande rôles backend/auditor distincts, non implémentés dans ce module

4. Hypothèses révélées tardivement

Hypothèse initiale Réalité découverte
SSE-KMS pour séparation clés FAUX — SSE-S3 choisi car client-side encryption (K_doc) déjà appliqué
Transition J+90 par défaut FAUX — Défaut J+1 dans variables.tf, doit être override à l'instanciation
3 buckets dans un module FAUX — Bucket backups non inclus dans module worm_glacier
Rétention par objet FAUX — Default retention au niveau bucket, override par objet à l'upload
KMS Key rotation automatique NON APPLICABLE — SSE-S3 pas de clé KMS à gérer

5. Invariants complexes à implémenter

Invariant Complexité
Object Lock COMPLIANCE irréversible Une fois activé, impossible de désactiver ou réduire rétention
Versioning requis pour Object Lock Dépendance : versioning doit être Enabled avant Object Lock
DenyAllDeletes permanent Bucket policy bloque toute suppression, même après expiration rétention
prevent_destroy Terraform Empêche terraform destroy accidentel sur buckets critiques
Rétention dynamique 3-100 ans Backend doit passer headers Object Lock à chaque PUT
Purge manuelle post-rétention Aucune expiration automatique, S3 Batch Operations requis

6. Dette technique

Dette Impact Priorité
SSE-S3 au lieu SSE-KMS Pas de séparation clés Paris/Frankfurt, audit KMS non disponible BASSE
Défaut transition J+1 Coûts Glacier plus élevés si non override en prod BASSE
Bucket Backups absent Sauvegardes PostgreSQL sans WORM dédié MOYENNE
IAM roles non créés Credentials partagés ou à créer manuellement MOYENNE
Documentation purge absente docs/infra/aws/crr/purge-procedure.md référencé mais non créé BASSE

7. Risques résiduels

Risque Probabilité Impact Mitigation suggérée
Coûts long terme Élevée MOYEN Monitoring coûts CloudWatch, alertes budget
Purge post-rétention Moyenne MOYEN Documenter procédure S3 Batch Operations
Transition J+1 oubliée Moyenne FAIBLE Forcer variable en tfvars prod
Backups sans WORM Moyenne MOYEN Créer bucket backups GOVERNANCE séparément
Audit KMS indisponible Faible FAIBLE SSE-S3 suffisant avec chiffrement client

8. Améliorations processus

Amélioration Bénéfice attendu
Valider défauts variables Éviter écarts spec/défaut (J+90 vs J+1)
Checklist 3 buckets Vérifier tous les buckets spec sont implémentés
Créer IAM avec buckets Éviter dette rôles backend/auditor
Documenter choix SSE Justifier SSE-S3 vs SSE-KMS dans ADR
Tests d'acceptation Terraform Valider configuration avant apply

9. Enseignements clés

  1. Les défauts de variables Terraform peuvent diverger de la spec — La variable lifecycle_transition_days a un défaut de 1 jour alors que la spec demande 90 jours. Les défauts doivent être alignés sur la spec ou documentés explicitement.

  2. SSE-S3 peut suffire avec chiffrement client — Le choix SSE-S3 au lieu de SSE-KMS est justifiable car le backend applique déjà un chiffrement client-side (AES-256-GCM avec K_doc). Ce compromis doit être documenté dans un ADR.

  3. Object Lock COMPLIANCE est irréversible — Une fois configuré, impossible de le désactiver ou réduire la rétention. Les tests en environnement dev avec rétention courte sont critiques avant production.

  4. La purge post-rétention nécessite une procédure manuelle — Object Lock empêche toute expiration automatique. Même après expiration de la rétention, la bucket policy DenyAllDeletes bloque les suppressions. S3 Batch Operations est requis.

  5. Le module doit couvrir tous les buckets de la spec — L'absence du bucket backups GOVERNANCE crée une dette technique. Un module "WORM" devrait inclure tous les types de stockage prévus par l'architecture.