infra: déploiement Ansible et sa validation CI #61
No reviewers
Labels
No labels
Compat/Breaking
EC01
EC02
EC03
EC04
EC05
EC06
Kind/BDD
Kind/Back
Kind/Bug
Kind/CICD
Kind/Cloud
Kind/Contenu
Kind/Data
Kind/Documentation
Kind/Enhancement
Kind/Feature
Kind/Front
Kind/IA
Kind/Infra
Kind/Monitoring
Kind/Security
Kind/Testing
Portée/Post-jury
Priority
Critical
Priority
High
Priority
Low
Priority
Medium
Reviewed
Confirmed
Reviewed
Duplicate
Reviewed
Invalid
Reviewed
Won't Fix
Status
Abandoned
Status
Blocked
Status
Need More Info
ops/alerte
No milestone
No project
No assignees
2 participants
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
g2/enervision!61
Loading…
Reference in a new issue
No description provided.
Delete branch "gabriel/41-ansible-squelette"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Ce que ça change
Rend le serveur reconstructible depuis le dépôt via Ansible, pour l'épreuve EC04. La PR est menée jusqu'à la fermeture complète du #41 (les quatre critères), l'implémentation arrive par lots.
Closes #41Lots
Lot 1 — provisionnement système (fait)
base(paquets, mises à jour de sécurité, pare-feu UFW),deploy_user(compte dédié, clés nominatives, sudo),ssh_hardening(coupe root et le mot de passe SSH),docker(moteur + plugin compose, rotation des journaux).bootstrap.yml: amorçage d'une cible neuve en root, joué une fois ;site.ymlprend le relais pardeployet ferme root ensuite.group_vars/all/scindé :vars.yml(non sensible) +vault.yml.example; levault.ymlchiffré est ignoré par Git.requirements-ci.txt),yamllintajouté,ansible-lintrendu bloquant.Lot 2 — piles applicatives et sauvegarde (fait, après merge de #81 sur develop)
app: clone le dépôt dans/opt/enervision/.repo, rend/etc/enervision/{postgres,minio}.envdepuis le coffre (0640 root:deploy,no_log), produit le certificat TLS de PostgreSQL sur la machine, lance chaque pile deapp_stacks(postgresavecbuild,minio) pardocker_compose_v2en attendanthealthy.backup: posepg-backup.shetverifier-sauvegardes.shdepuis le dépôt vers/usr/local/bin(source unique, critère du #64),/var/backups/postgresql+/etc/cron.d/pg-backupà 2 h 30, premier vidage joué à la main.restore.ymlcomplet : contrôle de lisibilité, filet, coupe des connexions,pg_restore --cleanpar base viadocker exec, vérification que le serveur répond ; chronomètre parprofile_tasks.Lot 3 — les preuves (en cours)
vault.ymlrempli : clédeploymachine + une clé personnelle par membre de l'équipe (lenaic, marvin, gabriel, florian, olivier, justine), 5 mots de passe PostgreSQL, identifiants MinIO.bootstrap.yml+site.ymljoués pour de vrai, jusqu'au bout, zéro échec — mais surserveur-salle, pas sur une cible vierge du groupeneuf(aucune machine jetable disponible ; décision assumée de prouver la reconstructibilité sur le serveur partagé plutôt que d'attendre une VM). Le critère « machine vierge » du #41 reste donc non prouvé au sens strict — à rouvrir si une cible neuve devient disponible.restore.ymljoué une fois pour de vrai et chronométré → toujours à faire,reprise.mdpas encore rempli.Bugs trouvés en déployant pour de vrai (jamais exercé avant ce run)
ansible.cfg: callbackcommunity.general.yamlcassé sous Python 3.14 → basculé surresult_format=yaml(remplacement officiel, déprécié depuis ansible-core 2.13).app: écrivait la clé de déploiement dans/opt/enervision/.ssh/id_deploysans jamais créer.ssh→ ajout de la tâche manquante.docker: le DNS du campus ENI détournedownload.docker.comvers une IP interne qui refuse la connexion — dépôt officiel Docker injoignable sur ce réseau. Basculé surdocker.io+docker-compose-v2(dépôt Ubuntu, à jour dansnoble-updates, fournit biendocker compose).serveur-sallea un GPU Tesla T4 avec le toolkit nvidia déjà en place à la main etdefault-runtime: nvidia, dont dépendent implicitement tous les conteneurs qui y tournent (runners CI Forgejo compris). Le templatedaemon.jsonl'écrasait silencieusement → préservé viadocker_nvidia_runtime, activé enhost_varssur cette cible.infra/compose/minio/init-buckets.sh(#85, surdevelop) :grepabsent de l'imagequay.io/minio/mc(ubi9-micro) → les trois vérifications (versioning, rétention, purge) échouaient systématiquement. Corrigé et mergé séparément dans #90.Conséquence opérationnelle du durcissement SSH, à diffuser à l'équipe
ssh_hardeningrestreint SSH àAllowUsers deploy: les comptes personnels (lenaic,marvin,gabriel,florian,olivier,justine) qui existaient surserveur-sallesont désormais coupés, root aussi. Vérifié en conditions réelles après rechargement de sshd. Toute l'équipe doit désormais passer parssh deploy@10.105.200.41avec sa propre clé (déjà posée dans le coffre). Levault.ymllocal mis à jour avec ces 7 clés doit être repartagé à l'équipe par le canal hors dépôt habituel.Hors périmètre du #41, à ouvrir en tickets
docs/POSTGRESQL.mdécart,reprise.md) : les vidages sont sur le disque de la machine. La reprise sur machine neuve suppose pour l'instant une copie manuelle préalable de/var/backups/postgresql/. Cible de secours + décision à trancher.POSTGRESQL.mdécart n°4) : attend Prometheus.app: tourne surserveur-sallevia un compose déployé à la main (/opt/enervision/mlflow/), aucun équivalent tracké dansinfra/compose/. Reste un geste manuel non documenté au sens strict du critère #3 — à couvrir dans un ticket dédié si on veut fermer complètement ce point.Décisions à valider en relecture
deploya un sudoNOPASSWD: ALL(roles/deploy_user/defaults/main.yml), pas le « restreint à Docker » du squelette : Ansible provisionne toute la machine. Imputabilité par clés nominatives + journal sudo ; root n'a plus ni mot de passe ni login SSH.basearme UFW. Garde-fou et-e base_ufw_enabled=falsedocumentés dansdeploiement.md.ansible-vaultdevient le magasin de secrets partagé (réponse de fait à l'écart n°3 dePOSTGRESQL.md) :apprend les.envdepuis lui.genere-identifiants.shsert encore à générer les valeurs, qu'on dépose ensuite dans le coffre.Relecture précédente (Lénaïc, 2 sept.)
repo_version: main→develop✓docker_default_network_modeobsolète → variable retirée, le mode réseau se décide pile par pile (ADR 0001) ✓Closes #41gardé — la PR va jusqu'au bout des quatre critères.Ce qui suit le code
docs/runbooks/deploiement.mdetreprise.mdmis à jour et indexés dansdocs/runbooks/README.md🤖 Generated with Claude Code
https://claude.ai/code/session_01NbkbdXUvBFnQ5KuHan9y3J
infra: squelette du déploiement Ansible et sa validation CIto WIP: infra: squelette du déploiement Ansible et sa validation CILe squelette est bien posé : les cinq rôles dans l'ordre où ils doivent tourner,
become = Falsepar défaut avec l'élévation demandée tâche par tâche,host_key_checkingactif, et un contrôle de syntaxe dans la chaîne dès maintenant. Les deux manuels sont écrits avant l'implémentation, ce qui est le bon sens.Un point sur la fermeture. La description porte
Closes #41, or les critères du ticket demandent un playbook qui reconstruit le serveur sur une machine vierge, un comptedeploy, aucun geste manuel non documenté et une restauration chronométrée. Un squelette dont les rôles affichent un message ne les tient pas. Si cette demande ferme le ticket, il ne reste rien pour suivre l'implémentation.Deux options : retirer le
Closes #41et garder le ticket ouvert, ou le fermer et ouvrir un ticket par rôle. Je prendrais la première, le ticket est déjà découpé.@ -0,0 +8,4 @@compose_dir: "{{ app_root }}/infra/compose"repo_url: "ssh://git@10.105.200.41:2222/g2/enervision.git"repo_version: mainrepo_version: maindéploierait la mauvaise branche.developest la branche par défaut et porte tout le travail,maina vingt commits de retard et ne contient ni MinIO, ni la chaîne étendue, ni les manuels. Le playbook installerait un état du 1er septembre.@ -0,0 +10,4 @@repo_version: main# Contournement connu de l'hôte LXC : le réseau bridge de Docker est inopérant.docker_default_network_mode: hostCe commentaire n'est plus vrai. Le formateur a activé l'imbrication le 1er septembre et les réseaux bridge fonctionnent :
g2_forge_backetg2_forge_edgeexistent, et MinIO publie ses ports en bridge.Le réseau hôte reste peut-être le bon choix, mais pour une autre raison, qu'Olivier a documentée dans sa migration PostgreSQL : un port publié par Docker échappe à ufw, parce que la chaîne
DOCKER-USERest évaluée avant celles d'ufw. Une règleufw denyafficherait « deny » tout en laissant passer. C'est cette raison-là qu'il faut écrire ici.WIP: infra: squelette du déploiement Ansible et sa validation CIto infra: déploiement Ansible et sa validation CINew commits pushed, approval review dismissed automatically according to repository settings
community.general.yaml plante à l'exécution ("function() argument 'code' must be code, not str") sur ce venv Python 3.14 : le module patche AnsibleDumper d'une façon incompatible avec la nouvelle disposition interne des objets code. Le callback est de toute façon déprécié depuis ansible-core 2.13 au profit de result_format=yaml sur le callback par défaut, remplacement officiel adopté ici. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01NbkbdXUvBFnQ5KuHan9y3J