Set-OPS-Public/playbooks/modeles_vm/debian13_proxmox_verifier.yml
Daniel Allaire 3618dfc129 gabarit recapture : copie de travail preparee, nettoyee, convertie
modeleChezlepro (99999) clone en modeleChezlepro-travail (99998). L'original
n'a pas ete touche.

Deux defauts de mon propre outillage, trouves en l'utilisant :
- l'inventaire d'un seul hote ne porte aucun group_vars, donc aucun utilisateur
  de connexion : Ansible tentait le compte local. MODELE_HOTE passe desormais
  ansible_user.
- les playbooks ciblent hosts: modeles_vm, et un inventaire d'un seul hote
  place la machine dans all. La commande etait juste et la cible introuvable
  (« skipping: no hosts matched »). J'avais verifie l'affichage, pas l'effet.
  Les trois acceptent maintenant cible_modele.

Le nettoyage vide /etc/resolv.conf (il portait l'identite du reseau de
fabrication) et supprime les CLES D HOTE SSH — le gabarit transportait une cle
privee. Sur que parce que cloud-init les recree au premier demarrage, verifie
avant de l'ecrire.

Reste a faire, et ce n'est pas a moi : basculer proxmox_clone_* sur le nouveau
une fois qu'une VM en sera nee et aura fonctionne.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-09 11:29:51 -04:00

135 lines
5.5 KiB
YAML

---
- name: Vérifier le template Debian 13 Proxmox
# 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 "<ip>,"`)
# 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
tasks:
- name: Vérifier que la cible est Debian 13
ansible.builtin.assert:
that:
- ansible_facts.distribution == "Debian"
- ansible_facts.distribution_major_version == "13"
fail_msg: "Ce template doit être une Debian 13."
- name: Afficher les partitions
ansible.builtin.command: lsblk -f
register: lsblk_output
changed_when: false
- name: Résultat lsblk
ansible.builtin.debug:
var: lsblk_output.stdout_lines
- name: Vérifier l'absence de swap actif
ansible.builtin.command: swapon --show
register: swapon_output
changed_when: false
failed_when: swapon_output.stdout | length > 0
- name: Collecter les paquets installés
ansible.builtin.package_facts:
manager: auto
- name: Valider les paquets requis du template
ansible.builtin.assert:
that:
- "'sudo' in ansible_facts.packages"
- "'openssh-server' in ansible_facts.packages"
- "'qemu-guest-agent' in ansible_facts.packages"
- "'cloud-init' in ansible_facts.packages"
- "'cloud-guest-utils' in ansible_facts.packages"
- "'chrony' in ansible_facts.packages"
- "'apparmor' in ansible_facts.packages"
- "'auditd' in ansible_facts.packages"
- "'fail2ban' in ansible_facts.packages"
- "'nftables' in ansible_facts.packages"
- "'unattended-upgrades' in ansible_facts.packages"
fail_msg: "Un paquet requis du golden template est absent."
- name: Vérifier l'absence d'environnement graphique
ansible.builtin.assert:
that:
- "'task-desktop' not in ansible_facts.packages"
- "'xserver-xorg' not in ansible_facts.packages"
- "'gdm3' not in ansible_facts.packages"
- "'sddm' not in ansible_facts.packages"
- "'lightdm' not in ansible_facts.packages"
fail_msg: "Un environnement graphique semble installé."
- name: Collecter les services
ansible.builtin.service_facts:
- name: Valider les services de base
ansible.builtin.assert:
that:
- ansible_facts.services['ssh.service'].state == 'running'
- ansible_facts.services['qemu-guest-agent.service'].state == 'running'
- ansible_facts.services['chrony.service'].state == 'running'
- ansible_facts.services['auditd.service'].state == 'running'
- ansible_facts.services['fail2ban.service'].state == 'running'
fail_msg: "Un service de base n'est pas actif."
- name: Vérifier que AppArmor est actif
ansible.builtin.command: aa-enabled
register: apparmor_state
changed_when: false
- name: Valider l'état nftables du template
ansible.builtin.assert:
that:
- ansible_facts.services['nftables.service'].state != 'running'
fail_msg: "nftables ne doit pas être actif par défaut dans le template."
- name: Vérifier cloud-init
ansible.builtin.command: cloud-init --version
register: cloud_init_version
changed_when: false
- name: Afficher cloud-init
ansible.builtin.debug:
var: cloud_init_version.stdout
- name: Vérifier sudo NOPASSWD du compte Ansible
ansible.builtin.command: sudo -n true
become: false
changed_when: false
- name: Collecter la configuration SSH effective
ansible.builtin.command: sshd -T
register: sshd_effective_config
changed_when: false
- name: Valider le hardening SSH effectif
ansible.builtin.assert:
that:
- "'passwordauthentication no' in sshd_effective_config.stdout"
- "'kbdinteractiveauthentication no' in sshd_effective_config.stdout"
- "'permitrootlogin no' in sshd_effective_config.stdout"
- "'pubkeyauthentication yes' in sshd_effective_config.stdout"
- "'authenticationmethods publickey' in sshd_effective_config.stdout"
- "'x11forwarding no' in sshd_effective_config.stdout"
- "'allowtcpforwarding no' in sshd_effective_config.stdout"
- "'allowagentforwarding no' in sshd_effective_config.stdout"
- "'allowstreamlocalforwarding no' in sshd_effective_config.stdout"
- "'permittunnel no' in sshd_effective_config.stdout"
- "'permituserenvironment no' in sshd_effective_config.stdout"
- "'maxauthtries 3' in sshd_effective_config.stdout"
- "'logingracetime 20' in sshd_effective_config.stdout"
- "'maxsessions 2' in sshd_effective_config.stdout"
fail_msg: "La configuration SSH effective ne respecte pas le hardening attendu."
- name: Vérifier les erreurs critiques du boot courant
ansible.builtin.command: journalctl -b -p err..alert --no-pager
register: boot_errors
changed_when: false
failed_when: false
- name: Afficher les erreurs du boot courant
ansible.builtin.debug:
var: boot_errors.stdout_lines