Excel dirige le monde : histoires terrifiantes qui se répètent

Cet article vous a aidé ?

Le pager sonne, le tableau de bord est rouge, et la question exécutive arrive dans votre boîte mail avec la subtilité d’une brique : « Pourquoi avons‑nous des clients à qui l’on paie de l’argent négatif ? »

Vous suivez le « pipeline de données » et découvrez que le dernier kilomètre n’est ni Kafka ni Snowflake. C’est un tableur nommé final_FINAL_reallyfinal_v7.xlsx sur le bureau de quelqu’un, exporté en CSV le vendredi, puis téléversé manuellement en production. Le plus effrayant n’est pas que cela existe. Le plus effrayant, c’est que ça marche — jusqu’à ce que ça ne marche plus.

Pourquoi Excel continue de gagner (même en 2026)

Excel est la plateforme de programmation orientée utilisateur la plus réussie jamais distribuée. Pas parce qu’elle est « facile », mais parce qu’elle est disponible, rapide pour itérer, et qu’elle permet aux experts métier d’agir sans attendre la capacité d’ingénierie. Un tableur est une interface utilisateur, un magasin de données, un moteur de calcul et un générateur de rapports. Dans un seul fichier. Avec copier/coller.

C’est aussi pourquoi c’est dangereux. Il effondre des frontières sur lesquelles reposent les systèmes de production : contrôle de version, schémas typés, builds déterministes, contrôles d’accès, environnements reproductibles, tests automatisés et responsabilité claire. La superpuissance d’Excel, c’est de contourner la gouvernance en étant « juste un fichier ».

En termes SRE, les tableurs deviennent de la production quand :

  • Ils sont la source de vérité pour des décisions impactant les clients (tarification, éligibilité, paiements, inventaire).
  • Ils se situent sur le chemin critique (run de facturation hebdomadaire, clôture de fin de mois, rapports de conformité).
  • Ils n’ont aucun SLO documenté mais peuvent absolument ruiner votre semaine s’ils sont erronés.
  • Ils ont deux responsables (ce qui veut dire : zéro responsable).

Les gens n’utilisent pas Excel parce qu’ils sont imprudents. Ils l’utilisent parce que c’est le chemin le plus court de la question à la réponse. Votre travail est d’empêcher que ce chemin ne mène à une falaise.

Une citation à garder sur votre bureau

Werner Vogels, parlant de fiabilité à grande échelle, l’a dit sans détour : « Everything fails, all the time. »

Traduit dans la réalité des tableurs : tout se corrompt, tout le temps. Pas toujours bruyamment. Parfois par un changement silencieux de format qui transforme des identifiants en notation scientifique et ruine vos clés de jointure.

Blague n°1 : Excel est une base de données merveilleuse tant que votre base de données n’a besoin que d’un seul utilisateur, d’une seule table et d’une seule crise de nerfs.

Faits et histoire : comment on en est arrivé là

L’horreur Excel n’est pas nouvelle. Ce qui est nouveau, c’est combien de systèmes modernes se terminent encore dedans. Voici des faits concrets et des points de contexte qui expliquent pourquoi les tableurs continuent d’apparaître dans des endroits sérieux :

  1. VisiCalc (1979) est souvent crédité comme l’« application killer » qui a vendu les premiers ordinateurs personnels aux entreprises — les tableurs étaient fondamentaux, pas une fonctionnalité secondaire.
  2. Excel a fait ses débuts en 1985 (d’abord pour Macintosh), et il est rapidement devenu le choix par défaut pour la modélisation métier parce qu’il combinait calcul et interface en grille flexible.
  3. Excel a introduit les tableaux croisés dynamiques dans les années 1990, rendant l’analyse ad hoc accessible aux non‑programmeurs — excellent pour les insights, catastrophique pour la gouvernance.
  4. Les langages de « macro » pour tableur (comme VBA) ont transformé les fichiers en programmes exécutables avec de mauvaises pratiques de déploiement : copiez un fichier, vous avez déployé du code.
  5. Le CSV est devenu l’échange de données universel non pas parce qu’il est bon, mais parce qu’il est omniprésent ; Excel a rendu le CSV « standard » même quand les règles de quoting et les encodages ne le sont pas.
  6. L’inférence de type automatique d’Excel (dates, nombres, notation scientifique) est un choix de conception optimisé pour la convivialité interactive, pas pour l’intégrité des données.
  7. Les limites de lignes ont compté historiquement (65 536 lignes dans les anciennes versions d’Excel) ; les gens ont appris à scinder les données en plusieurs feuilles/fichiers, puis à les recoller manuellement.
  8. Les industries régulées ont adopté les tableurs parce que les équipes d’audit pouvaient « voir » la logique dans une feuille ; la visibilité a remplacé la correction comme contrôle perçu.
  9. Les exports SaaS modernes sont encore « pensés pour Excel » parce que les parties prenantes veulent des téléchargements qui s’ouvrent dans Excel, pas dans un notebook ou un outil BI.

Si vous essayez d’éradiquer Excel de votre organisation, commencez par reconnaître une vérité dure : Excel n’est pas un outil ; c’est un traité entre l’ingénierie et le métier. Le rompre sans offrir d’alternative et vous le verrez simplement continuer en secret.

Les véritables modes de défaillance : pas une « erreur humaine », mais un comportement système prévisible

Quand un incident est imputé à « quelqu’un a modifié un tableur », c’est généralement parce que personne n’a voulu décrire le système honnêtement. Le système, c’est : workflows manuels, schémas implicites, exports fragiles et approbations basées sur l’intuition.

1) Coercition de type silencieuse (Excel « vous aide »)

Excel devine. Il devine agressivement. Il se trompe de façons qui semblent correctes.

  • Des identifiants numériques longs deviennent de la notation scientifique ; les zéros initiaux disparaissent.
  • Des chaînes qui ressemblent à des dates deviennent de vraies dates ; « 03-04 » devient le 3 avril ou le 4 mars selon la locale.
  • Des entiers larges perdent de la précision lorsqu’ils sont traités comme flottants.

Résultat opérationnel : les jointures échouent, la déduplication échoue et des « enregistrements manquants » apparaissent dans les systèmes en aval. Vous n’obtenez pas une exception ; vous obtenez de l’argent faux.

2) Schémas implicites et dérive des colonnes

Les tableurs incitent à la dérive des colonnes : quelqu’un insère une colonne « Notes », un autre renomme « SKU » en « Sku », quelqu’un fusionne des cellules pour « rendre joli ». Les outils en aval se moquent que ce soit joli. Ils veulent que la colonne 7 soit price.

3) La chaîne d’approvisionnement copy/paste

Le « pipeline » le plus courant est : export → coller dans un autre classeur → filtrer → copier les lignes visibles → coller les valeurs → exporter. À chaque étape, vous pouvez perdre des lignes, les réordonner, conserver des formules obsolètes ou n’exporter que ce qui est visible.

Le filtrage est particulièrement brutal : il crée un état d’interface qui n’est pas évident dans la sortie exportée. Votre « ensemble de données complet » peut être « tout ce qui était visible lors de l’export ».

4) Concurrence sans verrous

Les fichiers ne se fusionnent pas proprement. Les gens envoient des pièces jointes par e‑mail. Ils gardent deux versions ouvertes. Ils font « enregistrer sous » pour résoudre des conflits. C’est du système distribué sans aucune des parties agréables.

5) Macros et liens externes : le graphe de dépendances caché

Des classeurs qui référencent d’autres classeurs, des partages réseau ou des sources ODBC se comportent comme des programmes avec des dépendances au moment de l’exécution. Un changement de permission sur un partage de fichiers ou un dossier déplacé peut casser la logique silencieusement. Parfois ça « se répare » tout seul parce qu’une valeur en cache est utilisée, ce qui est pire.

6) Tableur comme base de données : falaises de performance

Les gens trient 200k lignes, utilisent des formules volatiles, et se demandent pourquoi Excel gèle. Ensuite ils « optimisent » en scindant le fichier, ce qui crée des problèmes de réconciliation. Ou ils désactivent le calcul, ce qui crée des totaux obsolètes. Ou ils exportent en CSV et importent ailleurs, ce qui introduit des problèmes d’encodage et de quoting.

Blague n°2 : Un tableur n’est qu’un programme où chaque variable s’appelle « Column F » et chaque rapport de bug commence par « Ça marchait avant. »

Trois mini‑histoires d’entreprise issues du front des tableurs

Mini‑histoire n°1 : L’incident causé par une fausse hypothèse

Dans une entreprise de taille moyenne, l’équipe tarification maintenait un tableur qui générait des paliers de remise pour les renouvellements enterprise. Sales ops exportait la feuille chaque semaine en CSV et la téléversait dans un outil d’administration interne, qui poussait les paliers dans un service de tarification. Le workflow était ancien, ennuyeux, et tout le monde supposait que c’était « ok ».

Une nouvelle région a été lancée. Quelqu’un a ajouté une colonne au tableur nommée Region et l’a insérée vers le début pour garder la feuille « lisible ». L’export a toujours produit un CSV, le téléversement a réussi, et l’outil d’administration a renvoyé un joli « Import complete ». L’importeur était positionnel, pas basé sur les en‑têtes. Il a pris la nouvelle colonne pour CustomerSegment, décalant tout d’une colonne.

Le service de tarification n’a pas planté. Il a accepté des données pourries. Soudain, certains clients ont obtenu des remises destinées à un autre segment, tandis que d’autres ont perdu leurs paliers négociés. L’astreinte a été appelée pour une « chute de conversion » et une « hausse de tickets support », pas pour une défaillance d’intégrité des données.

La cause racine n’était pas « quelqu’un a ajouté une colonne ». La fausse hypothèse était qu’un job d’import qui dit « complete » signifie « correct » et que les humains ne réorganiseraient jamais un tableur. La correction n’a pas été « dites aux gens d’arrêter ». Ils ont modifié l’importeur pour faire la correspondance par nom d’en‑tête, valider les champs requis, rejeter les colonnes inconnues et produire un rapport de diff. Le tableur pouvait changer de forme, mais le système n’accepterait plus silencieusement ces changements.

Mini‑histoire n°2 : L’optimisation qui s’est retournée contre eux

Une équipe logistique avait un classeur qui calculait les quantités de réapprovisionnement pour des entrepôts. Il récupérait des données d’un rapport exporté et utilisait une jungle de formules. Le classeur est devenu lent. Pour « l’accélérer », un analyste a remplacé des formules par des valeurs codées en dur après la mise à jour hebdomadaire — copier, coller les valeurs, fini. Ça a marché. C’était aussi une bombe à retardement.

Des mois plus tard, un nouvel entrepôt a été ajouté. Le classeur utilisait des plages nommées et quelques formules censées s’étendre automatiquement. Elles ne l’ont pas fait. Parce que la feuille était désormais principalement des valeurs collées, le nouvel entrepôt n’a jamais été inclus dans le calcul. Le tableau de bord avait toujours l’air sain parce que les totaux étaient assez proches. Personne n’a remarqué qu’une installation entière était réapprovisionnée selon le modèle du mois dernier et des ajustements manuels.

Quand la précision d’inventaire a finalement chuté au point de déclencher des alarmes, l’ingénierie est intervenue. Ils ont trouvé un classeur « rapide » dont la logique avait été amputée pour le rendre réactif. L’optimisation n’était pas mauvaise en soi — elle résolvait un vrai problème de performance — mais elle a détruit la capacité du classeur à s’adapter aux entrées changeantes.

La solution a été de déplacer les calculs dans un pipeline approprié : extraire les données du rapport, valider le schéma, calculer le réapprovisionnement en code, stocker les sorties, et laisser Excel devenir une couche de vue si besoin. Les performances se sont améliorées et la logique n’était plus modifiable par une chirurgie accidentelle de copier/coller.

Mini‑histoire n°3 : La pratique ennuyeuse mais correcte qui a sauvé la mise

Une équipe finance opérations effectuait des paiements mensuels à des partenaires. Leurs données sources arrivaient sous forme de tableurs depuis plusieurs canaux. Le processus avait la réputation d’être fragile, alors un ingénieur ops a insisté sur quelque chose de profondément inintéressant : sommes de contrôle, entrées brutes immuables et une étape de transformation reproductible.

Ils exigeaient que chaque fichier entrant soit stocké inchangé dans un répertoire « incoming » avec un horodatage, puis converti en CSV normalisé via un processus scripté. Le script validait les en‑têtes de colonnes, les comptes et des invariants basiques (pas de montants négatifs sauf signalés, les IDs partenaires correspondent aux motifs attendus). Il produisait aussi un rapport sommaire et un diff par partenaire contre le mois précédent.

Un mois, le fichier d’un partenaire est arrivé avec un problème subtil : la colonne « Amount » contenait des valeurs avec des virgules au format local, et Excel les affichait correctement. Le script de transformation a rejeté le fichier car l’analyse numérique a échoué. Au lieu de « corriger » silencieusement, le processus a forcé une décision humaine : demander un fichier corrigé ou utiliser une configuration de parseur explicite pour ce partenaire.

Le paiement a été retardé de quelques heures. C’était le « coût ». Le coût évité était un paiement erroné à sept chiffres et un événement de conformité. La pratique ennuyeuse a gagné : traiter les tableurs comme des entrées non fiables, stocker les artefacts bruts de façon immuable, valider agressivement et provoquer les échecs tôt quand ils sont peu coûteux.

Guide de diagnostic rapide : trouver le goulot d’étranglement vite

Quand Excel est impliqué dans des résultats de production, votre triage d’incident doit couvrir à la fois l’infrastructure et le pipeline humain en boucle. Le chemin le plus rapide consiste à déterminer si vous avez un problème de correction des données, de fraîcheur des données ou de disponibilité du système.

Premier : classer l’incident en 5 minutes

  1. Correction : les chiffres sont erronés, mais les jobs ont « réussi ». Cherchez le parsing, la coercition, la dérive de colonnes, les uploads en double, les formules obsolètes.
  2. Fraîcheur : les chiffres sont anciens. Cherchez des uploads manqués, des échecs cron, des files d’attente bloquées, une étape manuelle non exécutée, une confusion de fuseau horaire.
  3. Disponibilité : les jobs du pipeline échouent bruyamment. Cherchez stockage plein, permissions, partage réseau down, pannes d’API, erreurs de contraintes DB.

Second : identifier la « frontière de transfert »

Il y a toujours un moment où le « système » devient « tableur » (export) et un autre où le « tableur » devient « système » (import). La plupart des défaillances se regroupent à ces frontières :

  • L’encodage/la locale d’export a changé (UTF-8 vs Windows-1252, virgule décimale vs point).
  • La ligne d’en‑tête manque ou est dupliquée.
  • Seules les lignes visibles ont été exportées à cause d’un filtrage.
  • Excel a auto‑converti des identifiants.
  • Le script d’import suppose des positions de colonnes.

Troisième : vérifier des invariants, pas seulement les logs

Les logs vous disent si le job a tourné. Les invariants vous disent s’il a fait la bonne chose. Vous voulez des « tests de fumée » rapides :

  • Nombre de lignes dans la plage attendue.
  • Les clés uniques sont réellement uniques.
  • Les totaux se réconcilient avec la baseline dans une tolérance.
  • Le schéma correspond aux en‑têtes et aux types attendus.

Quatrième : décider d’arrêter la chaîne

Si de l’argent circule, arrêtez la chaîne quand les invariants échouent. Ne « corrigez » pas en éditant le tableur sur place. C’est ainsi que vous perdez l’auditabilité et finissez par vous disputer sur ce qui a changé et quand. Geler les entrées, relancer les transformations et seulement ensuite réimporter.

Tâches pratiques : commandes, sorties et décisions (édition SRE)

Ci‑dessous des tâches réelles à exécuter pendant un incident ou comme hygiène préventive. Chacune inclut une commande, une sortie d’exemple, ce que cela signifie et la décision à prendre.

Task 1: Confirm the file you’re about to process is immutable (hash it)

cr0x@server:~$ sha256sum /data/incoming/pricing_tiers.xlsx
a3f2c1d8bb9c2d2bb1e0e1e2b72f16c4d6b3a2a0c3c1ad4f1c9c0b7a3d8e2f11  /data/incoming/pricing_tiers.xlsx

Signification : C’est l’empreinte du fichier exact utilisé pour le traitement.

Décision : Stockez le hash avec les métadonnées d’exécution. Si quelqu’un « corrige le tableur », exigez un nouveau fichier et un nouveau hash ; ne jamais écraser.

Task 2: See when the file changed (catch last-minute edits)

cr0x@server:~$ stat /data/incoming/pricing_tiers.xlsx
  File: /data/incoming/pricing_tiers.xlsx
  Size: 4821932    Blocks: 9424       IO Block: 4096   regular file
Device: 0,42   Inode: 1311042     Links: 1
Access: (0640/-rw-r-----)  Uid: ( 1001/  ingest)   Gid: ( 1001/  ingest)
Access: 2026-01-22 08:11:17.000000000 +0000
Modify: 2026-01-22 08:10:59.000000000 +0000
Change: 2026-01-22 08:10:59.000000000 +0000

Signification : L’heure de modification proche du temps d’exécution peut indiquer qu’un éditeur a modifié et retéléversé en plein run.

Décision : Si un fichier a changé pendant la fenêtre d’exécution, mettez‑le en quarantaine et relancez depuis un snapshot stable.

Task 3: Convert XLSX to CSV in a deterministic way (avoid Excel export)

cr0x@server:~$ ssconvert --export-type=Gnumeric_stf:stf_csv /data/incoming/pricing_tiers.xlsx /data/staging/pricing_tiers.csv
Importing file `/data/incoming/pricing_tiers.xlsx'
Saving file `/data/staging/pricing_tiers.csv'

Signification : Conversion réalisée avec un outil côté serveur ; la sortie est reproductible et scriptable.

Décision : Standardisez la conversion dans CI/CD ou un job contrôlé. Ne comptez pas sur « Enregistrer sous CSV » fait par un humain.

Task 4: Detect non-UTF8 encodings (silent corruption source)

cr0x@server:~$ file -bi /data/staging/pricing_tiers.csv
text/plain; charset=utf-8

Signification : Confirme que le fichier est en UTF-8 ; s’il était Windows-1252 vous auriez un autre charset.

Décision : Si ce n’est pas UTF-8, convertissez explicitement avant le parsing et documentez l’encodage du système source.

Task 5: Check for weird delimiter/quote behavior fast

cr0x@server:~$ head -n 3 /data/staging/pricing_tiers.csv
customer_id,segment,region,discount_pct
001234,enterprise,EU,12.5
009876,midmarket,US,7.0

Signification : Vérification rapide : en‑tête attendu, virgules présentes, décimales avec points.

Décision : Si vous voyez des points‑virgules, des quotes incohérentes ou des retours chariot intégrés, ajustez les paramètres du parseur ou rejetez et demandez un export corrigé.

Task 6: Validate row count against expectation (freshness/correctness smoke test)

cr0x@server:~$ wc -l /data/staging/pricing_tiers.csv
4821 /data/staging/pricing_tiers.csv

Signification : 4 821 lignes incluent l’en‑tête ; comparez à la plage typique des runs précédents.

Décision : Si le compte chute ou explose, arrêtez l’import et examinez les filtres, feuilles manquantes ou sections dupliquées.

Task 7: Confirm headers exactly match the contract (kill column drift)

cr0x@server:~$ head -n 1 /data/staging/pricing_tiers.csv | tr ',' '\n' | nl -ba
     1	customer_id
     2	segment
     3	region
     4	discount_pct

Signification : Vous avez une liste ordonnée de colonnes ; c’est votre interface de schéma.

Décision : Si une colonne manque, est renommée ou ajoutée, échouez bruyamment le pipeline. Ne tentez pas de deviner.

Task 8: Detect duplicate keys (a classic spreadsheet “paste twice”)

cr0x@server:~$ awk -F, 'NR>1{print $1}' /data/staging/pricing_tiers.csv | sort | uniq -d | head
001234
004455

Signification : Ces IDs client apparaissent plus d’une fois.

Décision : Décidez la politique : rejeter les doublons, ou exiger une colonne « effective_date » et des règles de résolution déterministes.

Task 9: Detect “scientific notation” damage in identifiers

cr0x@server:~$ awk -F, 'NR>1 && $1 ~ /E\+/ {print NR ":" $1; exit}' /data/staging/pricing_tiers.csv
129:1.23457E+11

Signification : Un ID a été converti en notation scientifique quelque part dans le processus.

Décision : Rejetez le fichier et corrigez le chemin d’export. Les IDs doivent être traités comme des chaînes de bout en bout.

Task 10: Check numeric sanity (negative values, impossible percentages)

cr0x@server:~$ awk -F, 'NR>1 && ($4<0 || $4>100){print NR ":" $0}' /data/staging/pricing_tiers.csv | head
77:008812,enterprise,US,150

Signification : 150% de remise n’est probablement pas une stratégie ; c’est une erreur de parsing ou de saisie.

Décision : Définissez des invariants et appliquez‑les comme portes. Si des exceptions existent, exigez une colonne d’override explicite et des approbations.

Task 11: Compare today’s totals to a baseline (catch silent shifts)

cr0x@server:~$ awk -F, 'NR>1{sum+=$4} END{printf "%.2f\n", sum}' /data/staging/pricing_tiers.csv
39210.50

Signification : Un agrégat grossier. Il ne prouve pas la correction, mais il détecte de grosses déviations.

Décision : Si la somme s’écarte au‑delà d’une tolérance par rapport aux runs précédents, bloquez l’import et ouvrez une enquête.

Task 12: Validate freshness by checking pipeline logs for last successful run

cr0x@server:~$ journalctl -u pricing-importer --since "2 days ago" | tail -n 8
Jan 22 08:12:03 server pricing-importer[24911]: Starting import: /data/staging/pricing_tiers.csv
Jan 22 08:12:04 server pricing-importer[24911]: Parsed rows=4820 rejected=0
Jan 22 08:12:05 server pricing-importer[24911]: Upsert complete
Jan 22 08:12:05 server pricing-importer[24911]: Import success run_id=7b3d2c

Signification : Confirme que l’importeur a tourné récemment, et combien de lignes ont été parsées/rejetées.

Décision : Si le dernier succès est trop ancien, traitez‑le comme un incident de fraîcheur et cherchez des handoffs bloqués.

Task 13: Check DB for the latest data timestamp (don’t trust the job log)

cr0x@server:~$ psql -d pricing -c "select max(updated_at) from discount_tiers;"
         max
---------------------
 2026-01-22 08:12:05
(1 row)

Signification : Confirme que l’état aval a bien changé quand vous le pensez.

Décision : Si les horodatages sont en retard, l’import a peut‑être réussi mais n’a rien écrit (contraintes, règles de déduplication, mauvais mapping de clé).

Task 14: Confirm storage isn’t full (because “import failed” is often “disk full”)

cr0x@server:~$ df -h /data
Filesystem      Size  Used Avail Use% Mounted on
/dev/sdb1       500G  496G  4.0G  100% /data

Signification : Vous vivez sur la réserve. Les fichiers temporaires et conversions échoueront de façon imprévisible.

Décision : Libérez de l’espace immédiatement et ajoutez de l’alerte sur l’utilisation du système de fichiers avec estimation du temps avant saturation.

Task 15: Find the biggest offenders in the staging area

cr0x@server:~$ du -sh /data/staging/* | sort -h | tail -n 5
3.2G  /data/staging/archive
5.8G  /data/staging/tmp
7.1G  /data/staging/exports

Signification : L’espace est consommé par archive/tmp ; la politique de nettoyage peut être cassée.

Décision : Implémentez une rétention (ex : garder les N dernières versions) et déplacez le stockage long terme vers un objet storage avec règles de cycle de vie.

Task 16: Verify the cron/systemd timer actually fired (the “nobody pressed the button” check)

cr0x@server:~$ systemctl list-timers --all | grep pricing
Thu 2026-01-22 08:12:00 UTC  2min ago Thu 2026-01-22 08:12:00 UTC  2min ago pricing-import.timer  pricing-import.service

Signification : Le timer s’est déclenché ; si le service n’a pas tourné, regardez les échecs de service ou les dépendances.

Décision : Si les timers ne se déclenchent pas, vous avez un problème d’ordonnancement/hôte. S’ils se déclenchent mais que les données sont fausses, concentrez‑vous sur les entrées/parsing.

Task 17: Catch schema drift by diffing headers against a pinned contract

cr0x@server:~$ diff -u /etc/pricing/header_contract.txt <(head -n 1 /data/staging/pricing_tiers.csv)
--- /etc/pricing/header_contract.txt
+++ /dev/fd/63
@@ -1 +1 @@
-customer_id,segment,region,discount_pct
+customer_id,segment,Region,discount_pct

Signification : Un changement de casse (« Region » vs « region ») peut casser des parseurs stricts ou des mappings en aval.

Décision : Décidez si les en‑têtes sont sensibles à la casse ; appliquez‑les ensuite de façon cohérente. Mon conseil : soyez strict et faites se conformer les producteurs.

Task 18: Verify permissions on shared drop location (ingest failures that look like “no data”)

cr0x@server:~$ namei -l /data/incoming
f: /data/incoming
drwxr-xr-x root   root   /
drwxr-xr-x root   root   data
drwxrwx--- ingest ingest incoming

Signification : Seul le groupe ingest peut écrire. Si un téléverseur humain n’appartient pas au groupe, il « upload » ailleurs ou échoue silencieusement.

Décision : Corrigez l’appartenance aux groupes et documentez le chemin de téléversement ; envisagez une interface web authentifiée plutôt qu’un dossier partagé.

Erreurs courantes : symptôme → cause racine → correctif

Cela revient encore et encore. Traitez‑les comme des vulnérabilités connues.

1) « Import completed » mais les valeurs aval sont absurdes

Symptôme : Les logs de job indiquent un succès ; les tableaux de bord basculent ; aucune exception n’est levée.

Cause racine : Parsing CSV positionnel avec dérive de colonnes, ou export Excel ayant réordonné les colonnes.

Correctif : Parser par nom d’en‑tête, valider les colonnes requises/autorisées et échouer sur les champs inconnus. Produire un rapport de diff lisible par un humain avant d’appliquer les changements.

2) Enregistrements manquants après une mise à jour de tableur

Symptôme : Un sous‑ensemble de clients/produits disparaît après une « modification mineure ».

Cause racine : Des filtres Excel laissés actifs ; seules les lignes visibles ont été exportées. Ou un onglet n’a pas été inclus dans l’export.

Correctif : Conversion côté serveur depuis le XLSX brut ; rejeter les fichiers avec plages filtrées (si détectable) et valider le nombre de lignes et la couverture des clés.

3) Les IDs ne correspondent plus entre systèmes

Symptôme : Les jointures échouent ; des entités « nouvelles » ressemblent à des doublons.

Cause racine : IDs auto‑coercés (zéros initiaux supprimés, notation scientifique, arrondis numériques).

Correctif : Forcer le traitement des IDs comme chaînes dès l’étape d’ingestion ; valider les motifs (longueur/regex). N’acceptez jamais des IDs numériques issus d’un tableur sans formatage explicite.

4) La clôture de mois « prend juste plus de temps maintenant »

Symptôme : Le temps de traitement du tableur augmente jusqu’à devenir une gestion de crise.

Cause racine : Le tableur est devenu un moteur de calcul ; formules volatiles, plages énormes, multiples recherches inter‑feuilles.

Correctif : Déplacez les calculs dans un pipeline ou une base de données ; gardez Excel comme front‑end ou artefact de reporting. Fixez une limite dure de lignes/complexité.

5) Deux équipes jurent qu’elles ont utilisé « le même fichier »

Symptôme : Résultats contradictoires, accusations, résultats non reproductibles.

Cause racine : Pas d’immuabilité, pas de rétention d’artefacts, pas de checksums ; fichiers écrasés ou envoyés par mail.

Correctif : Stockez les entrées brutes de façon immuable avec hash et horodatage. Exigez des run IDs et joignez les artefacts à l’exécution.

6) « On a réparé » mais ça casse de nouveau la semaine suivante

Symptôme : Incidents répétés avec de petites variations nouvelles.

Cause racine : La correction était un patch manuel dans le tableur ; le pipeline accepte tout ce qui arrive ; pas de tests ni de contrats.

Correctif : Écrivez un contrat de schéma, appliquez des invariants, ajoutez des validations avant import et définissez une responsabilité avec contrôle de changement.

7) Problèmes de devises/décimales entre régions

Symptôme : Valeurs erronées par facteur 10/100 ; décimales prises comme séparateurs de milliers.

Cause racine : Incompatibilité de locale (virgule vs point), formatage Excel vs valeur brute, ou CSV exporté avec séparateurs localisés.

Correctif : Normalisez les formats numériques dans la couche d’ingestion. Exigez des codes ISO de devise et des séparateurs décimaux explicites. Rejetez les formats ambigus.

8) L’import commence à échouer « au hasard » après des mises à jour OS

Symptôme : Le même tableur « marche sur ma machine », échoue sur le serveur, ou vice versa.

Cause racine : Dérive des dépendances : versions de convertisseurs, différences de bibliothèques de parsing ou paramètres de sécurité des macros.

Correctif : Conteneurisez les outils de conversion/parsing ; figez les versions ; créez des fixtures de test golden et exécutez‑les à chaque déploiement.

Listes de contrôle / plan pas à pas

Ce ne sont pas des aspirations. Ce sont le minimum pour empêcher que des opérations pilotées par tableurs deviennent une catégorie d’incidents récurrente.

Checklist A: Si Excel est source de vérité, traitez‑le comme du code de production

  1. Définir la responsabilité : un propriétaire redevable (pas un comité), avec un suppléant.
  2. Définir un contrat de schéma : colonnes requises, colonnes autorisées, types et invariants.
  3. Arrêter les réécritures : stocker chaque fichier entrant de façon immuable avec horodatage + hash.
  4. Automatiser la conversion : XLSX → CSV normalisé via des outils côté serveur, pas l’UI Excel.
  5. Valider avant import : plages de comptes de lignes, clés uniques, contrôles de type, invariants et agrégats de sanity.
  6. Rendre les imports idempotents : relancer le même fichier produit le même état DB.
  7. Produire un diff d’approbation : « Voici ce qui changera » résumé pour révision humaine.
  8. Logger les run IDs : chaque changement en aval lié à un run ID et un hash d’entrée.

Checklist B: Plan d’intervention pas à pas quand le tableur est suspecté

  1. Geler la chaîne : pausez les imports ou désactivez le job pour arrêter l’aggravation.
  2. Identifier le dernier run connu bon : trouvez run ID, hash d’entrée et horodatage aval.
  3. Collecter les artefacts : XLSX brut, CSV normalisé, rapports de validation, logs de l’importeur.
  4. Exécuter les invariants : compte de lignes, doublons, diff de schéma, contrôles numériques.
  5. Comparer à la baseline : totaux et distribution des clés vs le run précédent.
  6. Décider d’une stratégie de rollback : revert DB à l’état connu bon ou réimporter le fichier connu bon.
  7. Corriger à la frontière : ne « corrigez » pas le tableur en place ; corrigez le contrat d’ingestion ou demandez un nouveau fichier.
  8. Post‑incident : ajoutez une porte qui aurait empêché la même classe de défaillance.

Checklist C: Plan de migration (Excel → solution plus sûre) sans guerre civile

  1. Inventorier les tableurs critiques : lesquels déplacent de l’argent, changent des droits clients ou affectent la conformité ?
  2. Choisir la première cible par rayon d’impact : impact le plus élevé × fréquence de changement la plus élevée.
  3. Extraire le modèle : identifier entrées, sorties et dépendances cachées (autres feuilles, liens externes, macros).
  4. Écrire une implémentation de référence : code qui reproduit les sorties à partir des mêmes entrées.
  5. Exécuter en parallèle : tableur et nouveau système produisent côte à côte jusqu’à ce que les deltas soient compris.
  6. Conserver Excel comme UI si nécessaire : autoriser export/import mais sous contrat, avec validation et approbations.
  7. Basculer avec garde‑fous : feature flag, plan de rollback et monitoring des invariants.
  8. Verrouiller l’ancien chemin : supprimer le « téléversement manuel » ou le rendre workflow d’urgence uniquement avec approbations explicites.

FAQ

1) Excel est‑il « mauvais » ?

Non. Excel est fantastique pour l’exploration, le prototypage et l’analyse ponctuelle. Il devient dangereux lorsqu’il est le système de référence sans contrôles de niveau production.

2) Quel est le contrôle le plus efficace à ajouter ?

Le stockage immuable des entrées brutes avec sommes de contrôle et run ID. Si vous ne pouvez pas prouver quel fichier a produit quelle sortie, vous n’avez pas des opérations — vous avez du folklore.

3) Pourquoi ne pas juste dire aux gens d’arrêter d’utiliser des tableurs ?

Parce qu’ils ne le feront pas. Ou ils s’y conformeront en public et continueront en privé. Remplacez le workflow : proposez un outil plus sûr aussi rapide qu’Excel pour leur tâche.

4) Le CSV semble simple. Pourquoi cause‑t‑il tant d’incidents ?

Parce que « CSV » n’est pas un format unique. Délimiteurs, règles de quoting, encodages, retours chariot intégrés et nombres dépendant de la locale transforment le « simple » en « ambigu ». Les exports Excel amplifient souvent cette ambiguïté.

5) Nous avons déjà un entrepôt de données. Pourquoi Excel importe encore ?

Parce que les décisions se prennent souvent en dehors de l’entrepôt : quelqu’un télécharge, édite et retéléverse. L’entrepôt peut être propre tandis que le fichier opérationnel du dernier kilomètre est le chaos.

6) Comment détecter plus tôt les incidents liés aux tableurs ?

Surveillez les invariants : compte de lignes, unicité des clés, variations de distribution et totaux de réconciliation. Alarmez sur les déviations, pas sur le « job failed », car les échecs liés aux tableurs réussissent souvent silencieusement.

7) Quelle doit être la frontière entre Excel et les systèmes de production ?

Excel peut être une entrée, mais uniquement via un chemin d’ingestion contrôlé qui normalise les formats, valide le schéma et produit un diff d’approbation. Excel ne doit pas écrire directement l’état de production sans garde‑fous.

8) Les macros sont‑elles toujours inacceptables ?

Dans les workflows régulés ou à fort impact, traitez les macros comme du code non revu s’exécutant sur des endpoints aléatoires — parce que c’est ce qu’elles sont. Si vous devez les garder, versionnez‑les, signez‑les et déplacez leur exécution côté serveur.

9) Comment gérer « mais le tableur contient une logique métier qu’on ne peut pas perdre » ?

Extraire et encoder cette logique. Commencez par écrire des tests à partir d’entrées/sorties historiques connues, puis réimplémentez la logique en code. Gardez Excel comme vue pendant la transition, pas comme moteur.

10) Quel est un premier objectif de migration pragmatique ?

N’importe quel tableur qui alimente un job d’import. Remplacez « export/import manuel » par : capture d’artefact brut → conversion déterministe → validation → import idempotent → piste d’audit.

Conclusion : que faire lundi

Si Excel est dans votre chaîne de production, vous n’êtes pas condamné. Vous devez simplement le traiter comme une interface non fiable et à forte variance — comme l’internet public, mais avec plus de cellules fusionnées.

Prochaines étapes qui réduisent vraiment les incidents :

  1. Trouvez les cinq principaux tableurs qui déplacent de l’argent ou des permissions. Notez les propriétaires, la cadence et les dépendances en aval.
  2. Installez des garde‑fous aux frontières : stockage immuable, hashes, conversion déterministe, contrats de schéma, vérifications d’invariants.
  3. Rendez l’échec bruyant et précoce : rejetez les fichiers ambigus, bloquez les imports en cas de dérive et exigez un nouvel artefact pour toute « correction ».
  4. Sortez le calcul d’Excel : si un classeur fait de sérieuses transformations, il a sa place dans du code et une base de données.
  5. Arrêtez de compter sur des héros : construisez le pipeline ennuyeux qui rend la bonne action facile.

Excel continuera de diriger le monde. Votre travail est d’empêcher qu’il ne dirige votre file d’incidents.

← Précédent
Ceph sur Proxmox : quand ça vaut le coup, quand c’est un piège et comment bien le dimensionner
Suivant →
Debian/Ubuntu « Fonctionne en LAN, échoue en WAN » : vérifications de routage et NAT qui révèlent la cause (cas n°25)

Laisser un commentaire