Skip to content
Des sauvegardes que vous n'avez jamais restaurées ne sont pas des sauvegardes. Un exercice de restauration, chronométré.
← ← Retour aux Réflexions Cloud

Des sauvegardes que vous n'avez jamais restaurées ne sont pas des sauvegardes. Un exercice de restauration, chronométré.

Chaque magasin de données AWS a des sauvegardes activées par défaut ou par une case à cocher. Aurora conserve des sauvegardes automatiques. DynamoDB a la récupération à un instant donné. S3 a le versionnage. La console affiche des coches vertes, le questionnaire de conformité reçoit un « oui », et personne n'a jamais rien restauré, donc personne ne sait combien de temps prend une restauration, si elle fonctionne, ou ce qui casse quand la copie restaurée a un autre nom.

Nous faisons un exercice de restauration chaque trimestre, dans un compte séparé, chronomètre en main. Voici l'exercice du trimestre dernier : ce que nous avons restauré, la durée de chaque étape, les quatre choses qui ont échoué, et ce que les chiffres disent de nos vrais objectifs de reprise, par opposition à ceux de la présentation.

Ce qui est sauvegardé, et comment

L'état de la plateforme vit à trois endroits : un cluster Aurora Serverless v2, six tables DynamoDB et deux buckets S3. Les sauvegardes, toutes définies en CDK :

Magasin Mécanisme Rétention Où vit la copie
Aurora Sauvegarde continue automatique, à un instant donné 35 jours Même compte, plus un snapshot quotidien copié vers le compte de sauvegarde via AWS Backup
DynamoDB Récupération à un instant donné, continue 35 jours Même compte, plus AWS Backup quotidien vers un coffre inter-comptes
S3 Versionnage + cycle de vie Anciennes versions conservées 90 jours Même bucket, plus réplication vers le compte de sauvegarde
Secrets, paramètres AWS Backup ne les couvre pas n/a Reconstruits depuis les définitions CDK et une checklist

La copie inter-comptes est la partie que les gens sautent. Une sauvegarde dans le même compte que la production protège d'une mauvaise migration ou d'une suppression maladroite. Elle ne protège pas de la compromission du compte lui-même, ni d'un cdk destroy avec le mauvais contexte qui supprime des choses avec RETAIN désactivé. AWS Backup avec un coffre dans un compte séparé, avec un verrou de coffre, c'est ce qui fait que la copie survit au pire jour. Ça coûte environ 6 $ par mois à notre taille.

compte de production Aurora · PITR 35 jours DynamoDB × 6 · PITR 35 jours S3 × 2 · versionnage 90 jours quotidien compte de sauvegarde coffre AWS Backupverrou · personne ne peut supprimer buckets répliques S3clé KMS séparée trimestriel compte de staging · l'exercice restaurer chaque magasin depuis le coffre pointer l'app de staging vers les copies lancer les smoke tests · chronométrer chaque étape jamais en production démonter à la fin · ~4 $ par exercice Les sauvegardes dans le même compte survivent à une mauvaise migration. Les sauvegardes inter-comptes survivent à une mauvaise journée.

L'exercice, chronomètre en main

Le scénario : les données de production d'hier à 14 h 00 sont corrompues ; tout restaurer à 13 h 55 et remonter l'application sur les données restaurées. En staging, depuis le compte de sauvegarde, avec la suite de smoke tests comme définition de « remontée ». Un ingénieur, sans aide, en suivant le runbook.

Étape Temps Notes
Aurora : restaurer le cluster à un instant donné depuis la copie du coffre 22 min Nouveau cluster, nouveau point de terminaison. Serverless v2, 0,5 ACU
Aurora : requête de vérification, comparer le nombre de lignes au tableau de bord de métriques 3 min Correspondance
DynamoDB : restaurer six tables depuis le coffre, en parallèle 31 min La plus grosse table, 18 Go, en a pris 28
DynamoDB : réactiver PITR et TTL sur les tables restaurées 4 min La restauration ne les conserve pas. Ni l'auto-scaling, les tags ou le stream
S3 : rien à restaurer pour ce scénario ; vérification du versionnage seulement 2 min
Repointer l'app : écrire le nouveau point de terminaison du cluster et les noms de tables dans SSM 5 min Aurait dû prendre 1 minute ; voir l'échec 3
Redémarrer les services App Runner et les Lambdas pour qu'ils lisent les nouveaux paramètres 6 min
Smoke tests verts 4 min
Total 77 min

Soixante-dix-sept minutes pour une restauration complète à un instant donné, par une seule personne suivant des instructions. C'est le vrai objectif de temps de reprise, et c'est le chiffre qui va dans le runbook, pas le « moins d'une heure » qui était sur la présentation avant le premier exercice.

Les quatre choses qui ont échoué

Le premier exercice, il y a un an, a pris quatre heures et ne s'est pas terminé. Chaque trimestre depuis a trouvé quelque chose. Les quatre du trimestre dernier :

1. La politique de la clé KMS n'autorisait pas le compte de staging à déchiffrer le snapshot Aurora. La copie du coffre est chiffrée avec une clé du compte de sauvegarde. Restaurer en staging exige que la politique de cette clé accorde kms:Decrypt et kms:CreateGrant au rôle de restauration du compte de staging. Elle les accordait à celui de la production. La restauration a échoué avec une erreur de permissions qui a pris vingt minutes à lire correctement. Corrigé en CDK : la politique de la clé liste maintenant chaque compte susceptible de restaurer.

2. La restauration DynamoDB perd les réglages de la table. Une table restaurée a les données et le schéma de clés et rien d'autre : pas de PITR, pas d'attribut TTL, pas d'auto-scaling, pas de tags, pas de stream. Notre app s'appuie sur le TTL pour expirer les sessions et sur le stream pour alimenter l'index de recherche. Sans étape de checklist pour les réactiver, l'app restaurée « fonctionnait » et avait silencieusement cessé d'expirer les sessions. C'est maintenant une étape du runbook et, mieux, un petit script qui applique les réglages depuis la définition CDK à une table nommée.

3. Une Lambda avait le nom de table codé en dur. Onze fonctions sur douze lisent leurs noms de tables depuis des paramètres SSM, donc repointer était une écriture de paramètre. Une, la plus ancienne, avait le nom de la table de production en littéral dans son environnement. Elle a continué joyeusement à écrire dans l'ancienne table pendant l'exercice, ce qui, dans une vraie reprise, aurait signifié écrire de nouvelles données dans le magasin corrompu. Trouvée parce que le smoke test de cette fonction a échoué. Corrigée en déplaçant le nom vers SSM comme les autres, et par une vérification en CI qui greppe les blocs d'environnement à la recherche de tout ce qui ressemble à un nom de ressource.

4. Le rôle de restauration en staging ne pouvait pas faire PassRole vers le rôle de service Aurora. Une omission IAM d'une ligne, découverte à la minute 30, corrigée à la minute 35, et un rappel que le chemin de restauration a son propre jeu de permissions que rien n'exerce à part l'exercice.

Aucune de ces choses n'aurait été trouvée en regardant les coches vertes. Toutes les quatre auraient transformé un vrai incident de « mauvais après-midi » en « mauvaise semaine ».

L'exercice · 77 minutes · un ingénieur · compte de staging Aurora PITR · 22 min DynamoDB × 6 · 31 min · en parallèle réglages repointage redémarrage smoke 077 min 1 · politique de clé KMS · 20 min perdues à lire l'erreur 2 · la restauration DynamoDB perd PITR, TTL, stream, auto-scaling, tags 3 · une Lambda au nom de table codé en dur a continué d'écrire dans l'ancienne table 4 · rôle de restauration sans iam:PassRole le premier exercice, il y a un an : quatre heures, non terminé chaque trimestre depuis a trouvé au moins l'un de ceux-ci

Les chiffres qui en sont sortis

Objectif de point de reprise : cinq minutes pour Aurora et DynamoDB, parce que la récupération à un instant donné est continue ; S3 est immédiat via le versionnage. Cette partie était vraie avant l'exercice.

Objectif de temps de reprise : 77 minutes pour une restauration complète, environ 30 pour une seule table DynamoDB, environ 25 pour Aurora seul. Ces chiffres étaient de la fiction avant l'exercice et sont des mesures maintenant. Ils sont dans le runbook et dans le modèle de page de statut, donc le message pendant une vraie reprise dit « restauration en cours, fin estimée à 15 h 20 » au lieu de « bientôt ».

Coût de l'exercice : environ 4 $ de ressources restaurées pour l'après-midi, plus l'après-midi d'un ingénieur. Coût de ne pas le faire : inconnu jusqu'au jour où ça compte, qui est le mauvais jour pour l'apprendre.

Le runbook, condensé

  • Déclarer l'instant cible. L'écrire avant de toucher à quoi que ce soit.
  • Restaurer dans le compte isolé. Jamais par-dessus la production ; restaurer à côté et repointer.
  • Aurora : restauration à un instant donné depuis la copie du coffre ; vérifier le nombre de lignes contre une métrique connue.
  • DynamoDB : restaurer toutes les tables en parallèle ; puis lancer le script de réglages pour PITR, TTL, streams, auto-scaling, tags.
  • S3 : identifier les versions d'objets à l'instant cible ; copier vers l'avant si nécessaire.
  • Repointer : l'application lit chaque nom de ressource depuis SSM. Écrire les nouveaux noms. Rien n'est codé en dur, et la CI l'impose.
  • Redémarrer tout ce qui met des paramètres en cache.
  • Smoke tests. Pas « ça se charge » : la suite qui exerce le checkout, la connexion et l'index de recherche.
  • Chronométrer chaque étape. Mettre à jour le RTO du runbook s'il a bougé.
  • Démonter, et écrire la note d'une page sur ce qui a échoué.

Trimestriel. Au calendrier. Avec un ingénieur différent à chaque fois, parce que le but est que le runbook fonctionne pour la personne qui ne l'a pas écrit.

Si vos sauvegardes ont des coches vertes et aucun historique de restauration, nous ferons le premier exercice avec vous. Prévoyez un après-midi et attendez-vous à trouver quelque chose.