--- # DESTRUCTIF : supprime des VM Proxmox par VMID. Réservé à un from-zero explicite. # Sécurités : n'agit QUE sur les VMID passés en `cibles_vmid` ET présents dans le # cluster ; refuse si le modèle (proxmox_clone_vmid_modele) est dans la liste. - name: Supprimer des VM Debian du cluster Proxmox (from-zero) hosts: localhost connection: local gather_facts: false become: false vars: setops_inventaires: [lab, principal, production] # Voute Proxmox : la voute UNIQUE de l'instance (all/vault.yml) est autoritaire ; # `proxmox.vault.yml` reste accepte en compat legacy pour les instances qui en # ont encore une. all/vault.yml en dernier => il l'emporte sur les memes cles. setops_gv_proxmox: [proxmox.yml, proxmox.vault.yml, proxmox.local.yml, all/vault.yml] # cibles_vmid : liste d'entiers, passée en -e (sinon dérivée des hôtes actifs). cibles_vmid: "{{ groups['hotes_actifs'] | map('extract', hostvars, 'proxmox_vmid') | map('int') | list }}" tasks: - name: Localiser les fichiers de variables Proxmox ansible.builtin.stat: path: "{{ playbook_dir }}/../../instance/inventories/{{ item.0 }}/group_vars/{{ item.1 }}" loop: "{{ setops_inventaires | product(setops_gv_proxmox) | list }}" loop_control: label: "{{ item.0 }}/{{ item.1 }}" register: proxmox_fichiers_variables - name: Charger les variables Proxmox non sensibles ansible.builtin.include_vars: file: "{{ item.stat.path }}" loop: "{{ proxmox_fichiers_variables.results }}" when: - item.stat.exists - item.stat.path is not search('vault') - name: Charger les secrets Proxmox (Vault) ansible.builtin.include_vars: file: "{{ item.stat.path }}" loop: "{{ proxmox_fichiers_variables.results }}" when: - item.stat.exists - item.stat.path is search('vault') no_log: true - name: Résoudre les identifiants d'API ansible.builtin.set_fact: api_host: "{{ proxmox_api_host | default(lookup('env', 'PROXMOX_API_HOST'), true) }}" api_port: "{{ proxmox_api_port | default('8006', true) }}" api_user: "{{ proxmox_api_user | default(lookup('env', 'PROXMOX_API_USER'), true) }}" api_tid: "{{ proxmox_api_token_id | default(lookup('env', 'PROXMOX_API_TOKEN_ID'), true) }}" api_secret: "{{ proxmox_api_token_secret | default(lookup('env', 'PROXMOX_API_TOKEN_SECRET'), true) }}" no_log: true - name: Interroger l'inventaire du cluster ansible.builtin.uri: url: "https://{{ api_host }}:{{ api_port }}/api2/json/cluster/resources?type=vm" method: GET headers: Authorization: "PVEAPIToken={{ api_user }}!{{ api_tid }}={{ api_secret }}" validate_certs: "{{ proxmox_validate_certs | default(false) | bool }}" register: cluster_vms check_mode: false no_log: true - name: Établir la carte VMID -> nœud pour nos cibles présentes ansible.builtin.set_fact: vm_a_supprimer: >- {{ cluster_vms.json.data | selectattr('vmid', 'in', cibles_vmid | map('int') | list) | list }} - name: "SÉCURITÉ — le modèle n'est PAS ciblé (VMID {{ proxmox_clone_vmid_modele }})" ansible.builtin.assert: that: "(proxmox_clone_vmid_modele | int) not in (cibles_vmid | map('int') | list)" fail_msg: "REFUS : le VMID du modèle est dans la liste à supprimer." - name: Récapitulatif avant suppression ansible.builtin.debug: msg: >- Suppression de {{ vm_a_supprimer | length }} VM : {{ vm_a_supprimer | map(attribute='name') | list }} (VMID {{ vm_a_supprimer | map(attribute='vmid') | list }}) - name: Arrêter chaque VM (force) community.general.proxmox_kvm: api_host: "{{ api_host }}" api_port: "{{ api_port | int }}" api_user: "{{ api_user }}" api_token_id: "{{ api_tid }}" api_token_secret: "{{ api_secret }}" validate_certs: "{{ proxmox_validate_certs | default(false) | bool }}" node: "{{ item.node }}" vmid: "{{ item.vmid | int }}" state: stopped force: true timeout: 120 loop: "{{ vm_a_supprimer }}" loop_control: label: "{{ item.name }} ({{ item.vmid }})" no_log: true failed_when: false - name: Supprimer chaque VM community.general.proxmox_kvm: api_host: "{{ api_host }}" api_port: "{{ api_port | int }}" api_user: "{{ api_user }}" api_token_id: "{{ api_tid }}" api_token_secret: "{{ api_secret }}" validate_certs: "{{ proxmox_validate_certs | default(false) | bool }}" node: "{{ item.node }}" vmid: "{{ item.vmid | int }}" state: absent timeout: 120 loop: "{{ vm_a_supprimer }}" loop_control: label: "{{ item.name }} ({{ item.vmid }})" no_log: true