diff --git a/CHANGELOG.md b/CHANGELOG.md index e3fae52..b0095fa 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,41 @@ # CHANGELOG — Set-OPS +## 2026-08-09 — Gabarit recapturé sur copie de travail, sans toucher à l'original + +`modeleChezlepro` (99999) cloné en `modeleChezlepro-travail` (99998), préparé, vérifié, +nettoyé, converti. **L'original n'a pas été touché** — il reste le gabarit en service tant +que le nouveau n'a pas produit une VM qui fonctionne. + +**Deux défauts de mon propre outillage, trouvés en l'utilisant pour de vrai** — et c'est +tout l'intérêt de s'en servir plutôt que de le déclarer prêt : + +- l'inventaire d'un seul hôte (`-i ","`) ne porte **aucun `group_vars`**, donc aucun + utilisateur de connexion : Ansible tentait le compte local de l'opérateur. `MODELE_HOTE` + passe maintenant `ansible_user` (défaut `ansible`, le `ciuser` du gabarit) ; +- les playbooks ciblent `hosts: modeles_vm`, et un inventaire d'un seul hôte place la + machine dans `all` — **pas** dans ce groupe. La commande était juste et la cible + introuvable : « skipping: no hosts matched », qui n'est pas une erreur. J'avais vérifié + l'affichage de la commande, pas son effet. Les trois playbooks acceptent désormais + `cible_modele`. + +**Le nettoyage a gagné deux choses :** + +`/etc/resolv.conf` est vidé — il portait `search chezlepro.ca` et +`nameserver 192.168.12.254`, l'identité du réseau de fabrication. + +Et les **clés d'hôte SSH** sont supprimées. Le gabarit transportait une clé **privée** : +quiconque détient l'image détient de quoi se faire passer pour une VM qui n'aurait pas +régénéré la sienne. La suppression n'est sûre que parce que cloud-init les recrée au +premier démarrage — vérifié avant de l'écrire : les hôtes de la flotte portent des +empreintes toutes différentes. + +L'exploitant a par ailleurs retiré `mtu=9000` des deux gabarits — le réglage mort relevé +plus tôt, qui ne se propageait pas aux clones. + +**Ce qui reste à faire, et qui n'est pas à moi** : faire pointer +`proxmox_clone_source_nom` / `proxmox_clone_vmid_modele` sur le nouveau, une fois qu'une VM +en sera née et aura fonctionné. Tant que ce n'est pas fait, rien n'a changé pour la flotte. + ## 2026-08-09 — `modeles_vm` : trois commandes qui ne pouvaient rien faire Le groupe était **toujours vide**, et rien ne le signalait. `instancier` l'émet comme diff --git a/Makefile b/Makefile index e24ea9c..5618522 100644 --- a/Makefile +++ b/Makefile @@ -187,10 +187,10 @@ lint: ansible-runtime ## Passe ansible-lint sur tout le depot syntaxe: syntaxe-modele syntaxe-verification-modele syntaxe-nettoyage syntaxe-verification-hote syntaxe-groupes syntaxe-proxmox ## Verifie la syntaxe de TOUS les playbooks (modele, hote, groupes, proxmox) syntaxe-modele: ansible-runtime ## Verifie la syntaxe du playbook de preparation du gabarit dore - ansible-playbook -i $(INVENTAIRE_MODELE) $(PLAYBOOK_PREPARER_MODELE) --syntax-check + ansible-playbook -i $(INVENTAIRE_MODELE) $(UTILISATEUR_MODELE) $(PLAYBOOK_PREPARER_MODELE) --syntax-check syntaxe-verification-modele: ansible-runtime ## Verifie la syntaxe du playbook de verification du gabarit - ansible-playbook -i $(INVENTAIRE_MODELE) $(PLAYBOOK_VERIFIER_MODELE) --syntax-check + ansible-playbook -i $(INVENTAIRE_MODELE) $(UTILISATEUR_MODELE) $(PLAYBOOK_VERIFIER_MODELE) --syntax-check syntaxe-nettoyage: ansible-runtime ## Verifie la syntaxe du playbook de nettoyage du gabarit ansible-playbook -i $(INVENTAIRE_MODELE) $(PLAYBOOK_NETTOYER_MODELE) --syntax-check @@ -842,10 +842,10 @@ inventaire-production: ## Affiche le graphe de l'inventaire de production .PHONY: _verifier-acces-modele _verifier-privileges-modele preparer-modele verifier-modele nettoyer-modele _verifier-acces-modele: ansible-runtime _modele-requis - ansible -i $(INVENTAIRE_MODELE) $(CIBLE_MODELE) -m ping -e ansible_become=false + ansible -i $(INVENTAIRE_MODELE) $(CIBLE_MODELE) $(UTILISATEUR_MODELE) -m ping -e ansible_become=false _verifier-privileges-modele: ansible-runtime _modele-requis - ansible -i $(INVENTAIRE_MODELE) $(CIBLE_MODELE) -b -m command -a "whoami" + ansible -i $(INVENTAIRE_MODELE) $(CIBLE_MODELE) $(UTILISATEUR_MODELE) -b -m command -a "whoami" # Le gabarit dore n'est PAS un hote du tenant : sa configuration Proxmox le place sur le # reseau de fabrication (192.168.12.x), pas dans le supernet. `instancier` emet donc @@ -877,18 +877,24 @@ INVENTAIRE_MODELE = $(if $(MODELE_HOTE),"$(MODELE_HOTE)$(,)",$(INVENTAIRE_LAB)) # Cible : la machine designee, ou le groupe si l'inventaire en contient un. CIBLE_MODELE = $(if $(MODELE_HOTE),$(MODELE_HOTE),$(GROUPE_MODELE)) +# Un inventaire d'UN SEUL HOTE (`-i ","`) ne porte aucun `group_vars` : il faut donc +# lui donner l'utilisateur de connexion, sinon Ansible tente le compte local de +# l'operateur. Defaut `ansible`, qui est le `ciuser` du gabarit. +MODELE_UTILISATEUR ?= ansible +UTILISATEUR_MODELE = $(if $(MODELE_HOTE),-e ansible_user=$(MODELE_UTILISATEUR) -e cible_modele=$(MODELE_HOTE),) + preparer-modele: ansible-runtime _modele-requis _verifier-acces-modele _verifier-privileges-modele ## Prepare le gabarit dore (VM de reference clonee pour chaque hote) - ansible-playbook -i $(INVENTAIRE_MODELE) $(PLAYBOOK_PREPARER_MODELE) + ansible-playbook -i $(INVENTAIRE_MODELE) $(UTILISATEUR_MODELE) $(PLAYBOOK_PREPARER_MODELE) verifier-modele: ansible-runtime _modele-requis ## Verifie le gabarit dore - ansible-playbook -i $(INVENTAIRE_MODELE) $(PLAYBOOK_VERIFIER_MODELE) + ansible-playbook -i $(INVENTAIRE_MODELE) $(UTILISATEUR_MODELE) $(PLAYBOOK_VERIFIER_MODELE) nettoyer-modele: ansible-runtime _modele-requis ## Nettoie le gabarit avant capture — exige CONFIRMER=true @if [[ "$(CONFIRMER)" != "true" ]]; then \ printf '%s\n' 'Refus: relancer avec CONFIRMER=true pour le nettoyage final du modele.'; \ exit 2; \ fi - ansible-playbook -i $(INVENTAIRE_MODELE) $(PLAYBOOK_NETTOYER_MODELE) -e template_cleanup_confirm=true + ansible-playbook -i $(INVENTAIRE_MODELE) $(UTILISATEUR_MODELE) $(PLAYBOOK_NETTOYER_MODELE) -e template_cleanup_confirm=true .PHONY: _verifier-acces-hote _verifier-privileges-hote _attendre-hote faits verifier-hote diff --git a/playbooks/modeles_vm/debian13_proxmox_nettoyer.yml b/playbooks/modeles_vm/debian13_proxmox_nettoyer.yml index 79c4cf1..92cdc3c 100644 --- a/playbooks/modeles_vm/debian13_proxmox_nettoyer.yml +++ b/playbooks/modeles_vm/debian13_proxmox_nettoyer.yml @@ -1,6 +1,11 @@ --- - name: Nettoyage final avant conversion en template Proxmox - hosts: modeles_vm + # Le gabarit n'est pas un hote du tenant : son adresse vit sur le reseau de + # fabrication, donc il ne peut pas venir du plan et le groupe `modeles_vm` reste vide. + # `MODELE_HOTE` passe alors `cible_modele`, et l'inventaire d'un seul hote (`-i ","`) + # place la machine dans `all` — PAS dans `modeles_vm`. Sans cette indirection, la + # commande etait juste et la cible introuvable : « skipping: no hosts matched ». + hosts: "{{ cible_modele | default('modeles_vm') }}" become: true gather_facts: true diff --git a/playbooks/modeles_vm/debian13_proxmox_preparer.yml b/playbooks/modeles_vm/debian13_proxmox_preparer.yml index 1919504..00360aa 100644 --- a/playbooks/modeles_vm/debian13_proxmox_preparer.yml +++ b/playbooks/modeles_vm/debian13_proxmox_preparer.yml @@ -1,6 +1,11 @@ --- - name: Préparer le template Debian 13 Proxmox - hosts: modeles_vm + # Le gabarit n'est pas un hote du tenant : son adresse vit sur le reseau de + # fabrication, donc il ne peut pas venir du plan et le groupe `modeles_vm` reste vide. + # `MODELE_HOTE` passe alors `cible_modele`, et l'inventaire d'un seul hote (`-i ","`) + # place la machine dans `all` — PAS dans `modeles_vm`. Sans cette indirection, la + # commande etait juste et la cible introuvable : « skipping: no hosts matched ». + hosts: "{{ cible_modele | default('modeles_vm') }}" become: true gather_facts: true diff --git a/playbooks/modeles_vm/debian13_proxmox_verifier.yml b/playbooks/modeles_vm/debian13_proxmox_verifier.yml index 2a96c64..c50928b 100644 --- a/playbooks/modeles_vm/debian13_proxmox_verifier.yml +++ b/playbooks/modeles_vm/debian13_proxmox_verifier.yml @@ -1,6 +1,11 @@ --- - name: Vérifier le template Debian 13 Proxmox - hosts: modeles_vm + # Le gabarit n'est pas un hote du tenant : son adresse vit sur le reseau de + # fabrication, donc il ne peut pas venir du plan et le groupe `modeles_vm` reste vide. + # `MODELE_HOTE` passe alors `cible_modele`, et l'inventaire d'un seul hote (`-i ","`) + # place la machine dans `all` — PAS dans `modeles_vm`. Sans cette indirection, la + # commande etait juste et la cible introuvable : « skipping: no hosts matched ». + hosts: "{{ cible_modele | default('modeles_vm') }}" become: true gather_facts: true diff --git a/roles/template_cleanup/tasks/main.yml b/roles/template_cleanup/tasks/main.yml index efd2a3c..f72bb27 100644 --- a/roles/template_cleanup/tasks/main.yml +++ b/roles/template_cleanup/tasks/main.yml @@ -69,6 +69,19 @@ # (playbooks/groupes/serveur_debian.yml, avant le premier apt). # Un gabarit ne transporte aucune identite de reseau. +# Un gabarit ne doit transporter AUCUNE cle privee. Sans ce nettoyage, l'image porte la +# cle d'hote SSH de la machine de fabrication : quiconque detient l'image detient de quoi +# se faire passer pour n'importe quelle VM qui n'aurait pas regenere la sienne. +# +# La regeneration est faite par cloud-init au premier demarrage (module `ssh`, qui +# recree les cles absentes) — verifie le 2026-08-09 : les hotes de la flotte portent des +# empreintes toutes differentes. C'est cette regeneration qui rend la suppression sure ; +# la desactiver rendrait les VM sans cle d'hote, donc sans sshd. +- name: Supprimer les cles d hote SSH (regenerees par cloud-init au premier demarrage) + ansible.builtin.shell: + cmd: rm -f /etc/ssh/ssh_host_* + removes: /etc/ssh/ssh_host_ed25519_key + - name: Supprimer les historiques shell ansible.builtin.file: path: "{{ item }}"