infra: publie le plan de migration cloud chiffré et le plafond #163

Merged
justine merged 4 commits from florian/43-plan-migration-cloud into develop 2026-09-07 09:57:41 +00:00
Member

Le plan compare le coût technique local (11,73 €/mois, hypothèses déclarées)
aux deux scénarios hébergés chiffrés au catalogue public Azure du 04/09 :
reprise à l'identique 127,55 €/mois, services managés 119,58 €/mois. Un ordre
de grandeur d'écart, donc une bascule qui ne se justifie pas par le prix : les
quatre conditions qui la déclencheraient sont posées et vérifiables.

Trois droits manquent au rôle « Devops-cours-projet-eadl », mesurés à la portée
du groupe avec des corps volontairement invalides pour ne rien créer :
Microsoft.Consumption (budget), managementPolicies/write (cycle de vie), et un
second compte de stockage que « storageaccountnumber = 1 » refuse. Le conteneur
blob, lui, passe.

Le plafond est donc déclaré et non provisionné — 5 €/mois, posé en métadonnée
du conteneur pour être lisible dans l'état Terraform comme le ticket le demande.
Rien ne se déclenchera seul, et l'ADR 0012 le dit en clair plutôt que de laisser
le mot « alerte » le suggérer.

Closes #43

Ce que ça change

le chiffrage local (11,73 €) contre les deux scénarios hébergés (127,55 € et 119,58 €), et le fait qu'une seule ressource sorte de tout ça.
Closes #43.

Preuve

Les trois verdicts de permission bruts (403 sur Microsoft.Consumption/budgets, 403 sur managementPolicies, 400 sur le conteneur donc autorisé) avec l'explication du 403-avant-corps / 400-après, qui est ce qui rend le test concluant sans rien créer. Et une ligne qui dit franchement que la « capture du budget » demandée par le ticket n'existera pas.

Si ça touche infra/terraform/

 conservée, avec le plan complet dans le <details>, 1 to add, 0 to change, 0 to destroy. J'ai raccourci le storage_account_id en .../storageAccounts/stenervisiong2tfstate pour ne pas semer l'identifiant d'abonnement dans un fil de MR ; si tu préfères la sortie strictement intégrale, dis-le, je remets la ligne entière. La case apply reste décochée : elle revient à Gabriel après fusion, ADR 0007.

Relecture

  • Un pair a relu et laissé un commentaire, même court
  • Ses remarques sont traitées, ou une réponse explique pourquoi elles ne le sont pas

Ce qui suit le code

  • docs/runbooks/ mis à jour, un geste d'exploitation a changé
  • docs/adr/ complété, une décision structurante a été prise

Où regarder en priorité

quatre points, dont les deux qui méritent vraiment un second avis : le §7 / ADR 0012 (là où le ticket n'est pas rempli comme écrit),
et le prevent_destroy sur archive, qui contrairement à tfstate tombe dans le périmètre d'un destroy.

Le plan compare le coût technique local (11,73 €/mois, hypothèses déclarées) aux deux scénarios hébergés chiffrés au catalogue public Azure du 04/09 : reprise à l'identique 127,55 €/mois, services managés 119,58 €/mois. Un ordre de grandeur d'écart, donc une bascule qui ne se justifie pas par le prix : les quatre conditions qui la déclencheraient sont posées et vérifiables. Trois droits manquent au rôle « Devops-cours-projet-eadl », mesurés à la portée du groupe avec des corps volontairement invalides pour ne rien créer : Microsoft.Consumption (budget), managementPolicies/write (cycle de vie), et un second compte de stockage que « storageaccountnumber = 1 » refuse. Le conteneur blob, lui, passe. Le plafond est donc déclaré et non provisionné — 5 €/mois, posé en métadonnée du conteneur pour être lisible dans l'état Terraform comme le ticket le demande. Rien ne se déclenchera seul, et l'ADR 0012 le dit en clair plutôt que de laisser le mot « alerte » le suggérer. Closes #43 ## Ce que ça change le chiffrage local (11,73 €) contre les deux scénarios hébergés (127,55 € et 119,58 €), et le fait qu'une seule ressource sorte de tout ça. Closes #43. ## Preuve ``` Les trois verdicts de permission bruts (403 sur Microsoft.Consumption/budgets, 403 sur managementPolicies, 400 sur le conteneur donc autorisé) avec l'explication du 403-avant-corps / 400-après, qui est ce qui rend le test concluant sans rien créer. Et une ligne qui dit franchement que la « capture du budget » demandée par le ticket n'existera pas. ``` ## Si ça touche `infra/terraform/` ``` conservée, avec le plan complet dans le <details>, 1 to add, 0 to change, 0 to destroy. J'ai raccourci le storage_account_id en .../storageAccounts/stenervisiong2tfstate pour ne pas semer l'identifiant d'abonnement dans un fil de MR ; si tu préfères la sortie strictement intégrale, dis-le, je remets la ligne entière. La case apply reste décochée : elle revient à Gabriel après fusion, ADR 0007. ``` </details> ## Relecture - [ ] Un pair a relu et laissé un commentaire, même court - [ ] Ses remarques sont traitées, ou une réponse explique pourquoi elles ne le sont pas ## Ce qui suit le code <!-- Ne cocher que ce qui s'applique, supprimer le reste. --> - [x] `docs/runbooks/` mis à jour, un geste d'exploitation a changé - [x] `docs/adr/` complété, une décision structurante a été prise ## Où regarder en priorité quatre points, dont les deux qui méritent vraiment un second avis : le §7 / ADR 0012 (là où le ticket n'est pas rempli comme écrit), et le prevent_destroy sur archive, qui contrairement à tfstate tombe dans le périmètre d'un destroy.
infra: publie le plan de migration cloud chiffré et le plafond
All checks were successful
Intégration / Contrôles statiques du dépôt (pull_request) Successful in 6s
Intégration / Aucun secret commité (pull_request) Successful in 3s
Intégration / Tableau de bord — dépendances, tests et construction (pull_request) Successful in 20s
Intégration / Python — qualité, tests et dépendances (pull_request) Successful in 3m24s
21b64e88d9
Le plan compare le coût technique local (11,73 €/mois, hypothèses déclarées)
aux deux scénarios hébergés chiffrés au catalogue public Azure du 04/09 :
reprise à l'identique 127,55 €/mois, services managés 119,58 €/mois. Un ordre
de grandeur d'écart, donc une bascule qui ne se justifie pas par le prix : les
quatre conditions qui la déclencheraient sont posées et vérifiables.

Trois droits manquent au rôle « Devops-cours-projet-eadl », mesurés à la portée
du groupe avec des corps volontairement invalides pour ne rien créer :
Microsoft.Consumption (budget), managementPolicies/write (cycle de vie), et un
second compte de stockage que « storageaccountnumber = 1 » refuse. Le conteneur
blob, lui, passe.

Le plafond est donc déclaré et non provisionné — 5 €/mois, posé en métadonnée
du conteneur pour être lisible dans l'état Terraform comme le ticket le demande.
Rien ne se déclenchera seul, et l'ADR 0012 le dit en clair plutôt que de laisser
le mot « alerte » le suggérer.

Closes #43
florian self-assigned this 2026-09-07 07:34:52 +00:00
Merge branch 'develop' into florian/43-plan-migration-cloud
All checks were successful
Intégration / Contrôles statiques du dépôt (pull_request) Successful in 5s
Intégration / Aucun secret commité (pull_request) Successful in 4s
Intégration / Tableau de bord — dépendances, tests et construction (pull_request) Successful in 20s
Intégration / Python — qualité, tests et dépendances (pull_request) Successful in 3m24s
15db2139aa
Member

Bon travail. La quasi totalité des critères de la #43 sont validés, seul reste le critère de l'alerte n'est pas tenu mais tu l'explique dans ta PR.

Quelques retours :

  1. Le trou de recette est réel, et il n'a pas de suite tracée. « L'alerte de dépense active » et « capture du budget » ne seront pas fournies, jamais, tant que le rôle est ce qu'il est. L'ADR 0012 le pose honnêtement. Mais la PR ferme #43 alors que le plan §7 dit « demande à formuler au propriétaire de l'abonnement » — et cette demande n'est portée par aucun ticket. Soit on ouvre le ticket de suivi, soit on amende les critères de #43 avant fermeture. Fermer sur un critère non tenu sans trace de suite, n'est pas ce qu'on veut.

  2. Contradiction interne sur la rétention. Le §6 chiffre l'archive à « 3,3 Mio/j × 30 j de rétention », alors que le §5 et l'ADR disent que la politique de cycle de vie est refusée et que « l'archive n'est pas purgée tant que le #71 n'est pas fait ». L'hypothèse de calcul contredit la conclusion de la même page. L'impact en euros est nul (1,2 Gio/an ≈ 0,01 €/mois), donc la conclusion tient — mais la ligne doit dire « croissance non purgée » et non « 30 j de rétention ».

  3. L'extrapolation de la zone bronze est le chiffre le plus fragile du document. Le §1 donne deux partitions : 43 Mio le 03/09 et 60 Mio le 04/09 à 13 h 44 — soit une journée pleine et une journée partielle, et 103 Mio de bronze au total, c'est-à-dire tout l'historique. En tirer « ≈ 50 Mio/jour » puis « 18 Gio/an » puis « ≈ 26 mois » pour la condition 2 — la seule qui porte une date — repose sur deux points dont un incomplet. Ça ne change pas la décision, mais je marquerais explicitement ce 18 Gio/an comme estimé sur deux jours, au même titre que les hypothèses du §2 le sont. Le document est justement bâti sur la distinction mesuré / déclaré ; celui-ci est du deuxième type et se présente comme du premier.

  4. Trois valeurs pour le même B2ms. §3 : « 68,27 €/mois ». variables.tf : « une VM B2ms à 59 €/mois ». ADR 0012 : « une machine virtuelle oubliée à 118 €/mois » (c'est le B4ms). L'écart 68,27 / 59 s'explique par le disque, mais il faut le dire dans le commentaire, sinon un relecteur croit à une coquille.

  5. Le tarif Blob mérite sa référence. 20 Gio Cool LRS à 0,18 €/mois implique 0,009 €/Gio, qui est le même taux qu'au §6. Le catalogue francecentral est plutôt autour de 0,015 €/Gio pour Cool. C'est la seule ligne « relevée » que je n'arrive pas à reconstituer depuis le document. Sans conséquence sur le total (0,18 € sur 119,58 €), mais dans un document qui affiche « ce sont des prix relevés, pas estimés », autant que la ligne soit rejouable comme les autres.

  6. plafond_lu_sur_azure promet un peu plus qu'il ne tient. La description dit qu'une divergence révèle une métadonnée modifiée au portail. En pratique la sortie ne rend la valeur d'Azure qu'après un refresh ; juste après un apply elle est identique par construction. Et la comparaison porte sur 5 (nombre) contre "5" (chaîne). Je préciserais « après terraform plan -refresh-only » dans la description — sinon la sortie donne l'apparence d'un contrôle continu, exactement le reproche que l'ADR fait au script écarté.

  7. prevent_destroy sur archive : le raisonnement est juste, et la distinction avec tfstate (hors d'atteinte par construction / protégé parce qu'on y a pensé) est bien vue. Un effet de bord à documenter : prevent_destroy bloque aussi tout renommage de nom_conteneur_archive, qui force un remplacement et échouera en erreur dure plutôt qu'en refus lisible. Une ligne dans la description de la variable suffit.

  8. docs/BACKLOG.md n'a pas suivi. Le PRD passe ENF-13 à « Fait, avec réserve », mais la ligne 72 du backlog liste toujours #43 dans « Pas démarré », et la ligne 123 le garde dans la liste jury. À aligner dans cette PR, sinon les deux documents se contredisent dès la fusion.

Sur les deux points où tu demandais un second avis
§7 / ADR 0012 -> c'est traité correctement. Le point fort n'est pas le plafond en métadonnée (qui ne fait rien), c'est la phrase « aucun contrôle automatique ne vient compenser l'alerte manquante ». Et l'argument des deux propriétés structurelles — storageaccountnumber = "1" qu'on n'administre pas, et l'absence de toute ressource de calcul dans le dépôt — est plus solide qu'un budget, parce qu'il empêche au lieu d'alerter. La seule chose qui manque est le point 1 ci-dessus : la sortie de secours (demander à l'école) est nommée mais pas tracée.

prevent_destroy sur archive — pas d'objection sur le fond, voir le point 7 pour la seule réserve. La mise à jour du runbook terraform-etat.md sur les deux conteneurs est le bon réflexe et couvre le vrai risque.

Pour moi à minima il faut revoir les points 1, 2 et 8

Bon travail. La quasi totalité des critères de la #43 sont validés, seul reste le critère de l'alerte n'est pas tenu mais tu l'explique dans ta PR. **Quelques retours :** 1. Le trou de recette est réel, et il n'a pas de suite tracée. « L'alerte de dépense active » et « capture du budget » ne seront pas fournies, jamais, tant que le rôle est ce qu'il est. L'ADR 0012 le pose honnêtement. Mais la PR ferme #43 alors que le plan §7 dit « demande à formuler au propriétaire de l'abonnement » — et cette demande n'est portée par aucun ticket. Soit on ouvre le ticket de suivi, soit on amende les critères de #43 avant fermeture. Fermer sur un critère non tenu sans trace de suite, n'est pas ce qu'on veut. 2. Contradiction interne sur la rétention. Le §6 chiffre l'archive à « 3,3 Mio/j × 30 j de rétention », alors que le §5 et l'ADR disent que la politique de cycle de vie est refusée et que « l'archive n'est pas purgée tant que le #71 n'est pas fait ». L'hypothèse de calcul contredit la conclusion de la même page. L'impact en euros est nul (1,2 Gio/an ≈ 0,01 €/mois), donc la conclusion tient — mais la ligne doit dire « croissance non purgée » et non « 30 j de rétention ». 3. L'extrapolation de la zone bronze est le chiffre le plus fragile du document. Le §1 donne deux partitions : 43 Mio le 03/09 et 60 Mio le 04/09 à 13 h 44 — soit une journée pleine et une journée partielle, et 103 Mio de bronze au total, c'est-à-dire tout l'historique. En tirer « ≈ 50 Mio/jour » puis « 18 Gio/an » puis « ≈ 26 mois » pour la condition 2 — la seule qui porte une date — repose sur deux points dont un incomplet. Ça ne change pas la décision, mais je marquerais explicitement ce 18 Gio/an comme estimé sur deux jours, au même titre que les hypothèses du §2 le sont. Le document est justement bâti sur la distinction mesuré / déclaré ; celui-ci est du deuxième type et se présente comme du premier. 4. Trois valeurs pour le même B2ms. §3 : « 68,27 €/mois ». variables.tf : « une VM B2ms à 59 €/mois ». ADR 0012 : « une machine virtuelle oubliée à 118 €/mois » (c'est le B4ms). L'écart 68,27 / 59 s'explique par le disque, mais il faut le dire dans le commentaire, sinon un relecteur croit à une coquille. 5. Le tarif Blob mérite sa référence. 20 Gio Cool LRS à 0,18 €/mois implique 0,009 €/Gio, qui est le même taux qu'au §6. Le catalogue francecentral est plutôt autour de 0,015 €/Gio pour Cool. C'est la seule ligne « relevée » que je n'arrive pas à reconstituer depuis le document. Sans conséquence sur le total (0,18 € sur 119,58 €), mais dans un document qui affiche « ce sont des prix relevés, pas estimés », autant que la ligne soit rejouable comme les autres. 6. plafond_lu_sur_azure promet un peu plus qu'il ne tient. La description dit qu'une divergence révèle une métadonnée modifiée au portail. En pratique la sortie ne rend la valeur d'Azure qu'après un refresh ; juste après un apply elle est identique par construction. Et la comparaison porte sur 5 (nombre) contre "5" (chaîne). Je préciserais « après terraform plan -refresh-only » dans la description — sinon la sortie donne l'apparence d'un contrôle continu, exactement le reproche que l'ADR fait au script écarté. 7. prevent_destroy sur archive : le raisonnement est juste, et la distinction avec tfstate (hors d'atteinte par construction / protégé parce qu'on y a pensé) est bien vue. Un effet de bord à documenter : prevent_destroy bloque aussi tout renommage de nom_conteneur_archive, qui force un remplacement et échouera en erreur dure plutôt qu'en refus lisible. Une ligne dans la description de la variable suffit. 8. docs/BACKLOG.md n'a pas suivi. Le PRD passe ENF-13 à « Fait, avec réserve », mais la ligne 72 du backlog liste toujours #43 dans « Pas démarré », et la ligne 123 le garde dans la liste jury. À aligner dans cette PR, sinon les deux documents se contredisent dès la fusion. **Sur les deux points où tu demandais un second avis** §7 / ADR 0012 -> c'est traité correctement. Le point fort n'est pas le plafond en métadonnée (qui ne fait rien), c'est la phrase « aucun contrôle automatique ne vient compenser l'alerte manquante ». Et l'argument des deux propriétés structurelles — storageaccountnumber = "1" qu'on n'administre pas, et l'absence de toute ressource de calcul dans le dépôt — est plus solide qu'un budget, parce qu'il empêche au lieu d'alerter. La seule chose qui manque est le point 1 ci-dessus : la sortie de secours (demander à l'école) est nommée mais pas tracée. prevent_destroy sur archive — pas d'objection sur le fond, voir le point 7 pour la seule réserve. La mise à jour du runbook terraform-etat.md sur les deux conteneurs est le bon réflexe et couvre le vrai risque. Pour moi à minima il faut revoir les points 1, 2 et 8
Merge branch 'develop' into florian/43-plan-migration-cloud
All checks were successful
Intégration / Contrôles statiques du dépôt (pull_request) Successful in 6s
Intégration / Aucun secret commité (pull_request) Successful in 3s
Intégration / Tableau de bord — dépendances, tests et construction (pull_request) Successful in 29s
Intégration / Python — qualité, tests et dépendances (pull_request) Successful in 3m23s
c4e1e61fe5
docs: traite la relecture de Justine sur le plan de migration
All checks were successful
Intégration / Tableau de bord — dépendances, tests et construction (pull_request) Successful in 33s
Intégration / Contrôles statiques du dépôt (pull_request) Successful in 4s
Intégration / Aucun secret commité (pull_request) Successful in 3s
Intégration / Python — qualité, tests et dépendances (pull_request) Successful in 3m26s
93ebc76046
Deux corrections de fond. Le §6 chiffrait l'archive sur « 30 j de rétention »
alors que le §5 et l'ADR 0012 disent la politique de cycle de vie refusée :
l'hypothèse de calcul contredisait la conclusion de la même page. La ligne dit
désormais « croissance non purgée », 1,2 Gio par an, un centime de plus par mois
chaque année — le total ne bouge pas d'un ordre de grandeur. Et les 18 Gio/an de
la zone bronze sont extrapolés sur deux jours dont un partiel : ils se
présentaient comme mesurés dans un document bâti sur cette distinction. Ils sont
marqués, et la condition 2 devient un ordre de grandeur, pas une échéance.

Le reste lève des ambiguïtés. Le B2ms portait trois valeurs selon l'endroit —
59,20 € de calcul, 68,27 € avec son disque, et 118 € qui était en fait le B4ms :
le SKU et le périmètre sont nommés partout. Le tarif Blob est rejouable, le
catalogue portant trois compteurs « Cool LRS Data Stored » dont un qui n'est pas
du blob. « plafond_lu_sur_azure » ne coïncide par construction qu'après un
apply : sa description exige maintenant « plan -refresh-only » plutôt que de
laisser croire à un contrôle continu. Et prevent_destroy bloque aussi tout
renommage du conteneur, en erreur dure au plan — le runbook porte la manœuvre.

Le backlog suit enfin le PRD : #43 n'est plus « pas démarré ».
Author
Member

Corrigé

Corrigé
justine approved these changes 2026-09-07 09:57:33 +00:00
justine merged commit 56ff4c4952 into develop 2026-09-07 09:57:41 +00:00
justine deleted branch florian/43-plan-migration-cloud 2026-09-07 09:57:41 +00:00
Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
2 participants
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
g2/enervision!163
No description provided.