[infra] Bootstrap de l'état Terraform distant #67

Closed
opened 2026-09-02 09:04:18 +00:00 by gabriel · 1 comment
Member

Exigence couverte

ENF-09

Épreuve servie

EC04 · Cloud et sécurisation

Charge estimée

0,5 j.h

Ce qu'on veut obtenir

Un stockage distant versionné pour terraform.tfstate, créé hors Terraform pour sortir du problème de l'œuf et de la poule, rejouable sans erreur et documenté. C'est la première brique de « ce qui sera réellement créé » décrit dans #43, que ce ticket ne modifie pas.

Critères d'acceptation

  • infra/terraform/bootstrap.sh (az CLI) crée le compte de stockage et le conteneur tfstate dans rg-FHeuze2023_cours-projet-eadl, active le versioning, et se rejoue sans erreur ni effet de bord.
  • Le compte est en Standard_LRS, StorageV2, TLS 1.2 minimum, accès public blob désactivé.
  • Aucun secret dans le script : nom du compte et RG sont des variables en tête de fichier.
  • docs/runbooks/terraform-etat.md explique quoi lancer et pourquoi ce n'est pas géré par Terraform.

Comment on le vérifie

Commande   bash infra/terraform/bootstrap.sh puis az storage container show -n tfstate --account-name <sa>
Attendu    le conteneur existe, versioning actif, une seconde exécution ne renvoie aucune erreur
Preuve     la sortie des deux commandes, en commentaire

Manuel d'exploitation à mettre à jour

docs/runbooks/terraform-etat.md (créé)

Risque et retour arrière

Nom de compte déjà pris, l'unicité est mondiale : changer le suffixe. Suppression accidentelle : le versioning permet la récupération, sinon terraform import reconstruit l'état.

Dépendances

Aucune. Brique de base des tickets Terraform.

### Exigence couverte ENF-09 ### Épreuve servie EC04 · Cloud et sécurisation ### Charge estimée 0,5 j.h ### Ce qu'on veut obtenir Un stockage distant versionné pour `terraform.tfstate`, créé hors Terraform pour sortir du problème de l'œuf et de la poule, rejouable sans erreur et documenté. C'est la première brique de « ce qui sera réellement créé » décrit dans #43, que ce ticket ne modifie pas. ### Critères d'acceptation - [ ] `infra/terraform/bootstrap.sh` (az CLI) crée le compte de stockage et le conteneur `tfstate` dans `rg-FHeuze2023_cours-projet-eadl`, active le versioning, et se rejoue sans erreur ni effet de bord. - [ ] Le compte est en `Standard_LRS`, `StorageV2`, TLS 1.2 minimum, accès public blob désactivé. - [ ] Aucun secret dans le script : nom du compte et RG sont des variables en tête de fichier. - [ ] `docs/runbooks/terraform-etat.md` explique quoi lancer et pourquoi ce n'est pas géré par Terraform. ### Comment on le vérifie ``` Commande bash infra/terraform/bootstrap.sh puis az storage container show -n tfstate --account-name <sa> Attendu le conteneur existe, versioning actif, une seconde exécution ne renvoie aucune erreur Preuve la sortie des deux commandes, en commentaire ``` ### Manuel d'exploitation à mettre à jour `docs/runbooks/terraform-etat.md` (créé) ### Risque et retour arrière Nom de compte déjà pris, l'unicité est mondiale : changer le suffixe. Suppression accidentelle : le versioning permet la récupération, sinon `terraform import` reconstruit l'état. ### Dépendances Aucune. Brique de base des tickets Terraform.
gabriel self-assigned this 2026-09-02 09:04:18 +00:00
florian added this to the EnerVision project 2026-09-02 14:51:59 +00:00
florian self-assigned this 2026-09-03 08:04:16 +00:00
gabriel added the due date 2026-09-09 2026-09-03 09:35:53 +00:00
gabriel removed the due date 2026-09-09 2026-09-03 09:40:40 +00:00
Member

Preuves

Branche florian/67-bootstrap-etat-terraform, commit 094d961. Livrables :
infra/terraform/bootstrap.sh et docs/runbooks/terraform-etat.md.

Le script, deuxième passage — rejoué quatre fois, sortie identique, aucune erreur ni effet de bord :

$ bash infra/terraform/bootstrap.sh
== état Terraform distant : stenervisiong2tfstate/tfstate dans rg-FHeuze2023_cours-projet-eadl ==
  session   florian.heuze2023@campus-eni.fr
  groupe    rg-FHeuze2023_cours-projet-eadl (user=FHeuze2023)
  compte    stenervisiong2tfstate déjà présent
  blob      versioning actif
  conteneur tfstate déjà présent
  rôle      « Storage Blob Data Contributor » déjà attribué

== conteneur d'état prêt ==

Le conteneur et les propriétés demandées :

$ az storage container show -n tfstate --account-name stenervisiong2tfstate --auth-mode login
{ "nom": "tfstate", "public": null }

$ az storage account show -n stenervisiong2tfstate -g rg-FHeuze2023_cours-projet-eadl
{ "sku": "Standard_LRS", "kind": "StorageV2", "tls": "TLS1_2",
  "blobPublic": false, "region": "francecentral", "tags": { "user": "FHeuze2023" } }

$ az storage account blob-service-properties show --account-name stenervisiong2tfstate -g rg-FHeuze2023_cours-projet-eadl
{ "versioning": true }

enableHttpsTrafficOnly=true par ailleurs. Aucun secret dans le script : aucune
clé de compte n'est lue, tout passe par le plan de gestion et l'identité d'az login, comme le demande l'ADR 0007.

Quatre écarts avec le ticket, imposés par l'abonnement école

  1. Le groupe de ressources du ticket n'existe pas. rg-FHeuze-eadl → le
    vrai est rg-FHeuze2023_cours-projet-eadl.
  2. Le compte existait déjà (stenervisiong2tfstate, créé ce matin, déjà
    conforme). Il est adopté plutôt que doublé : l'étiquette
    storageaccountnumber du groupe plafonne le nombre de comptes, et une
    création de plus part en RequestDisallowedByPolicy.
  3. Une politique en effet deny exige une étiquette user sur toute
    ressource — c'est ce qui a fait échouer la première création. Le script la
    reprend depuis le groupe, il sert donc dans le groupe de n'importe quel membre.
  4. Le rôle Devops-cours-projet-eadl a dataActions: []. Créer le
    conteneur ne donne aucun droit d'y écrire : plan de gestion et plan données
    sont deux mondes. Le script attribue donc Storage Blob Data Contributor sur
    le seul compte de stockage — sans quoi le terraform init du #68 partirait
    en 403 avec tout en place, ce qui est le dépannage le plus coûteux du lot.
    L'attribution passe par az rest : toute sous-commande az role assignment
    échoue en MissingSubscription, l'abonnement ne donnant pas accès à Entra ID.

Ce qui est vérifié pour la suite

Écriture réelle dans le conteneur avec la seule identité az login, sans clé —
upload, list, delete en --auth-mode login, tous passés. Le #68 peut donc
poser use_azuread_auth = true, conforme à l'ADR 0007. À reporter dans
backend.tf :

resource_group_name  = "rg-FHeuze2023_cours-projet-eadl"
storage_account_name = "stenervisiong2tfstate"
container_name       = "tfstate"
key                  = "enervision/terraform.tfstate"
use_azuread_auth     = true

La récupération d'un état écrasé par le versioning a été jouée pour de vrai
avant d'être écrite dans le manuel : deux versions d'un blob d'essai, lecture de
la version antérieure, réinstallation en version courante, ménage fait.

Réserve pour #43

Le #43 demande qu'un plafond de dépense soit déclaré avant toute création.
Il n'existe pas, et le rôle ne porte aucune action Microsoft.Consumption : je
ne peux pas le poser. L'exposition est négligeable — Standard_LRS, quelques
kilo-octets d'état — mais l'ordre demandé par le #43 n'est pas tenu, et cela le
concerne.

### Preuves Branche `florian/67-bootstrap-etat-terraform`, commit `094d961`. Livrables : `infra/terraform/bootstrap.sh` et `docs/runbooks/terraform-etat.md`. **Le script, deuxième passage — rejoué quatre fois, sortie identique, aucune erreur ni effet de bord :** ``` $ bash infra/terraform/bootstrap.sh == état Terraform distant : stenervisiong2tfstate/tfstate dans rg-FHeuze2023_cours-projet-eadl == session florian.heuze2023@campus-eni.fr groupe rg-FHeuze2023_cours-projet-eadl (user=FHeuze2023) compte stenervisiong2tfstate déjà présent blob versioning actif conteneur tfstate déjà présent rôle « Storage Blob Data Contributor » déjà attribué == conteneur d'état prêt == ``` **Le conteneur et les propriétés demandées :** ``` $ az storage container show -n tfstate --account-name stenervisiong2tfstate --auth-mode login { "nom": "tfstate", "public": null } $ az storage account show -n stenervisiong2tfstate -g rg-FHeuze2023_cours-projet-eadl { "sku": "Standard_LRS", "kind": "StorageV2", "tls": "TLS1_2", "blobPublic": false, "region": "francecentral", "tags": { "user": "FHeuze2023" } } $ az storage account blob-service-properties show --account-name stenervisiong2tfstate -g rg-FHeuze2023_cours-projet-eadl { "versioning": true } ``` `enableHttpsTrafficOnly=true` par ailleurs. Aucun secret dans le script : aucune clé de compte n'est lue, tout passe par le plan de gestion et l'identité d'`az login`, comme le demande l'ADR 0007. ### Quatre écarts avec le ticket, imposés par l'abonnement école 1. **Le groupe de ressources du ticket n'existe pas.** `rg-FHeuze-eadl` → le vrai est `rg-FHeuze2023_cours-projet-eadl`. 2. **Le compte existait déjà** (`stenervisiong2tfstate`, créé ce matin, déjà conforme). Il est adopté plutôt que doublé : l'étiquette `storageaccountnumber` du groupe plafonne le nombre de comptes, et une création de plus part en `RequestDisallowedByPolicy`. 3. **Une politique en effet `deny` exige une étiquette `user`** sur toute ressource — c'est ce qui a fait échouer la première création. Le script la reprend depuis le groupe, il sert donc dans le groupe de n'importe quel membre. 4. **Le rôle `Devops-cours-projet-eadl` a `dataActions: []`.** Créer le conteneur ne donne aucun droit d'y écrire : plan de gestion et plan données sont deux mondes. Le script attribue donc `Storage Blob Data Contributor` sur le seul compte de stockage — sans quoi le `terraform init` du #68 partirait en **403 avec tout en place**, ce qui est le dépannage le plus coûteux du lot. L'attribution passe par `az rest` : toute sous-commande `az role assignment` échoue en `MissingSubscription`, l'abonnement ne donnant pas accès à Entra ID. ### Ce qui est vérifié pour la suite Écriture réelle dans le conteneur avec la seule identité `az login`, sans clé — `upload`, `list`, `delete` en `--auth-mode login`, tous passés. Le #68 peut donc poser `use_azuread_auth = true`, conforme à l'ADR 0007. À reporter dans `backend.tf` : ```hcl resource_group_name = "rg-FHeuze2023_cours-projet-eadl" storage_account_name = "stenervisiong2tfstate" container_name = "tfstate" key = "enervision/terraform.tfstate" use_azuread_auth = true ``` La récupération d'un état écrasé par le versioning a été **jouée pour de vrai** avant d'être écrite dans le manuel : deux versions d'un blob d'essai, lecture de la version antérieure, réinstallation en version courante, ménage fait. ### Réserve pour #43 Le #43 demande qu'un plafond de dépense soit déclaré **avant** toute création. Il n'existe pas, et le rôle ne porte aucune action `Microsoft.Consumption` : je ne peux pas le poser. L'exposition est négligeable — `Standard_LRS`, quelques kilo-octets d'état — mais l'ordre demandé par le #43 n'est pas tenu, et cela le concerne.
gabriel added the due date 2026-09-09 2026-09-03 12:41:00 +00:00
justine added reference florian/67-bootstrap-etat-terraform 2026-09-04 07:51:10 +00:00
Sign in to join this conversation.
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".
2026-09-09
Dependencies

No dependencies set

Reference
g2/enervision#67
No description provided.