Nous avons précédemment montré que nous pouvons contacter chaque hôte et s’assurer qu’il est en mesure de répondre via un echo ICMP. Nous pouvons désormais aller plus loin.

Obtenir des informations sur les hôtes

$ ansible all -i inventory.yml -m setup
server1_lxc | SUCCESS => {
    "ansible_facts": {
        "ansible_all_ipv4_addresses": [
            "192.168.1.201"
        ],
        "ansible_all_ipv6_addresses": [
            "fe80::be24:11ff:feb4:d790"
        ],
        "ansible_apparmor": {
            "status": "enabled"
        },
        "ansible_architecture": "x86_64",
        "ansible_bios_date": "08/12/2024",
        "ansible_bios_vendor": "Dell Inc.",
        "ansible_bios_version": "1.18.0",
        "ansible_board_asset_tag": "NA",
        "ansible_board_name": "0KYWH7",
        "ansible_board_serial": "NA",
        "ansible_board_vendor": "Dell Inc.",
        "ansible_board_version": "A03",
        "ansible_chassis_asset_tag": "NA",
        "ansible_chassis_serial": "NA",
        "ansible_chassis_vendor": "Dell Inc.",
        "ansible_chassis_version": "NA",
        "ansible_cmdline": {
            "BOOT_IMAGE": "/boot/vmlinuz-6.8.12-2-pve",
            "quiet": true,
            "ro": true,
            "root": "/dev/mapper/pve-root"
        },
(...)

Exécuter une commande sur tous les hôtes

ansible all -i inventory.yml -a "cat /etc/os-release"

Notion de playbook Ansible

Un playbook Ansible est un fichier YAML qui définit un ensemble d’actions et de configurations à appliquer sur des serveurs distants.

Regardons le playbook update_servers.yml ci-dessous

---
# Description : Playbook pour la mise à jour des systèmes Ubuntu/Debian
# Ce playbook effectue :
# - La mise à jour du cache des paquets (apt update)
# - La mise à jour des paquets installés (apt upgrade)

- name: "Mise à jour des systèmes"
  # Décommenter une des lignes suivantes selon les besoins :
  #hosts: all           # Pour tous les hôtes de l'inventaire
  #hosts: vm_servers   # Pour les machines virtuelles uniquement
  #hosts: lxc_servers  # Pour les conteneurs LXC uniquement
  hosts: lxc_servers   # Dans notre cas, uniquement les conteneurs LXC
  
  # Élévation des privilèges (nécessaire pour apt)
  become: true
  
  # Variables pour le contrôle des mises à jour
  vars:
    # Durée de validité du cache en secondes (86400 = 24 heures)
    cache_valid_time: 86400
    
  tasks:
    - name: "Mise à jour du cache des paquets"
      apt:
        update_cache: yes
        cache_valid_time: "{{ cache_valid_time }}"
      register: apt_update_result
      
    - name: "Mise à jour des paquets"
      apt:
        upgrade: yes
      register: apt_upgrade_result
      
    # Optionnel : Affichage des résultats
    - name: "Affichage des paquets mis à jour"
      debug:
        var: apt_upgrade_result
      when: apt_upgrade_result.changed

    # Optionnel : Redémarrage si nécessaire
    - name: "Vérification si un redémarrage est nécessaire"
      stat:
        path: /var/run/reboot-required
      register: reboot_required

    - name: "Notification si un redémarrage est nécessaire"
      debug:
        msg: "Un redémarrage du système est recommandé"
      when: reboot_required.stat.exists

Mettre à jour nos conteneurs

Nous allons lancer ce playbook sur nos 5 serveurs.

deployer@ubuntu-deploy:~/homelab_julia_pve_tf_ansible$ ansible-playbook -i inventory.ini update_servers.yml

PLAY [Mise à jour des systèmes] ***************************************************************************************************************************************************************************

TASK [Gathering Facts] ************************************************************************************************************************************************************************************
ok: [server1_lxc]
ok: [server3_lxc]
ok: [server2_lxc]
ok: [server4_lxc]
ok: [server5_lxc]

TASK [Mise à jour du cache des paquets] *******************************************************************************************************************************************************************
ok: [server3_lxc]
ok: [server5_lxc]
ok: [server4_lxc]
ok: [server2_lxc]
ok: [server1_lxc]

TASK [Mise à jour des paquets] ****************************************************************************************************************************************************************************
ok: [server3_lxc]
ok: [server5_lxc]
ok: [server4_lxc]
ok: [server1_lxc]
ok: [server2_lxc]

TASK [Affichage des paquets mis à jour] *******************************************************************************************************************************************************************
skipping: [server1_lxc]
skipping: [server2_lxc]
skipping: [server3_lxc]
skipping: [server4_lxc]
skipping: [server5_lxc]

TASK [Vérification si un redémarrage est nécessaire] ******************************************************************************************************************************************************
ok: [server2_lxc]
ok: [server1_lxc]
ok: [server3_lxc]
ok: [server4_lxc]
ok: [server5_lxc]

TASK [Notification si un redémarrage est nécessaire] ******************************************************************************************************************************************************
ok: [server1_lxc] => {
    "msg": "Un redémarrage du système est recommandé"
}
ok: [server2_lxc] => {
    "msg": "Un redémarrage du système est recommandé"
}
ok: [server3_lxc] => {
    "msg": "Un redémarrage du système est recommandé"
}
ok: [server4_lxc] => {
    "msg": "Un redémarrage du système est recommandé"
}
ok: [server5_lxc] => {
    "msg": "Un redémarrage du système est recommandé"
}

PLAY RECAP ************************************************************************************************************************************************************************************************
server1_lxc                : ok=5    changed=0    unreachable=0    failed=0    skipped=1    rescued=0    ignored=0   
server2_lxc                : ok=5    changed=0    unreachable=0    failed=0    skipped=1    rescued=0    ignored=0   
server3_lxc                : ok=5    changed=0    unreachable=0    failed=0    skipped=1    rescued=0    ignored=0   
server4_lxc                : ok=5    changed=0    unreachable=0    failed=0    skipped=1    rescued=0    ignored=0   
server5_lxc                : ok=5    changed=0    unreachable=0    failed=0    skipped=1    rescued=0    ignored=0   

deployer@ubuntu-deploy:~/homelab_julia_pve_tf_ansible$

Nos machines semblent avoir besoin d’un redémarrage.

Il y a plusieurs façons de gérer le redémarrage via Ansible. Voici un playbook qui montre différentes approches :

reboot_servers.yml

---
# Description : Playbook pour la mise à jour et le redémarrage des systèmes
# Ce playbook effectue :
# - La mise à jour du cache et des paquets
# - Le redémarrage des serveurs si nécessaire
# - La vérification que les serveurs sont bien revenus en ligne
 
- name: "Mise à jour et redémarrage des systèmes"
  hosts: lxc_servers
  become: true
  
  tasks:
    - name: "Mise à jour du cache des paquets"
      apt:
        update_cache: yes
        cache_valid_time: 86400
 
    - name: "Mise à jour des paquets"
      apt:
        upgrade: yes
      register: apt_upgrade_result
 
    # Méthode 1 : Redémarrage immédiat
    - name: "Redémarrage des serveurs"
      reboot:
        # Délai avant de redémarrer (en secondes)
        pre_reboot_delay: 5
        # Délai maximum d'attente du redémarrage
        reboot_timeout: 600
        # Message dans les logs système
        msg: "Redémarrage déclenché par Ansible"
        # Durée d'attente après le redémarrage
        post_reboot_delay: 10
        
    # Méthode 2 : Redémarrage conditionnel (si nécessaire)
    # - name: "Vérification si redémarrage nécessaire"
    #   stat:
    #     path: /var/run/reboot-required
    #   register: reboot_required
    #
    # - name: "Redémarrage si nécessaire"
    #   reboot:
    #     msg: "Redémarrage requis après mises à jour"
    #     pre_reboot_delay: 5
    #     reboot_timeout: 600
    #     post_reboot_delay: 10
    #   when: reboot_required.stat.exists
 
    - name: "Vérification que le système est opérationnel"
      wait_for_connection:
        delay: 10
        timeout: 300
 
    - name: "Affichage de l'uptime après redémarrage"
      shell: uptime
      register: uptime_result
 
    - name: "Affichage du résultat"
      debug:
        var: uptime_result.stdout_lines

Pour utiliser ce playbook de manière sécurisée :

# Test préalable
ansible-playbook -i inventory.ini reboot_servers.yml --check
 
# Exécution avec demande de confirmation
ansible-playbook -i inventory.ini  reboot_servers.yml --ask-become-pass
 
# Exécution sur un serveur spécifique
ansible-playbook -i inventory.ini  reboot_servers.yml --limit server1_lxc
 
# Exécution avec plus de détails
ansible-playbook -i inventory.ini  reboot_servers.yml -v

Points importants :

  • Le module reboot gère proprement le cycle de redémarrage
  • Les délais sont paramétrables selon les besoins
  • La vérification post-redémarrage assure que les serveurs sont bien revenus
  • Deux méthodes proposées : redémarrage systématique ou conditionnel

Note de sécurité : Soyez prudent avec les redémarrages automatiques en production.

Arrêt des conteneurs

Nous pouvons souhaiter arrêter les conteneurs (sans les supprimer).

Le playbook Ansible suivant permet de réaliser cette opération.

stop-servers.yml

---
# Description : Playbook pour l'arrêt contrôlé des conteneurs LXC
# Ce playbook effectue :
# - La vérification de l'état des conteneurs
# - L'arrêt progressif des services
# - L'arrêt propre des conteneurs
# - La vérification de l'état final

- name: "Arrêt contrôlé des conteneurs"
  hosts: lxc_servers
  become: true
  
  tasks:
    - name: "Vérification de l'état initial des conteneurs"
      command: systemctl status
      register: container_status
      ignore_errors: true
      
    - name: "Arrêt gracieux des services en cours"
      systemd:
        state: stopped
        daemon_reload: yes
      ignore_errors: true
      
    - name: "Attente avant arrêt complet (permettre la sauvegarde des données)"
      wait_for:
        timeout: 30
        
    - name: "Arrêt des conteneurs"
      command: poweroff
      async: 0
      poll: 0
      ignore_errors: true
      
    - name: "Vérification de l'arrêt effectif"
      wait_for:
        host: "{{ inventory_hostname }}"
        port: 22
        state: stopped
        timeout: 300
      delegate_to: localhost

Nous pouvons lancer ce playbook à l’aide de la commande suivante :

$ ansible-playbook -i dynamic-inventory.proxmox.yml stop-servers.yml

Redémarrage des conteneurs

Le playbook Ansible ci-dessous permet de gérer le redémarrage des conteneurs.

restart-servers.yml

---
# Description : Playbook pour la mise à jour et le redémarrage des systèmes
# Ce playbook effectue :
# - La mise à jour du cache et des paquets
# - Le redémarrage des serveurs si nécessaire
# - La vérification que les serveurs sont bien revenus en ligne
 
- name: "Mise à jour et redémarrage des systèmes"
  hosts: lxc_servers
  become: true
 
  tasks:
    - name: "Mise à jour du cache des paquets"
      apt:
        update_cache: yes
        cache_valid_time: 86400
 
    - name: "Mise à jour des paquets"
      apt:
        upgrade: yes
      register: apt_upgrade_result
 
    # Méthode 1 : Redémarrage immédiat
    - name: "Redémarrage des serveurs"
      reboot:
        # Délai avant de redémarrer (en secondes)
        pre_reboot_delay: 5
        # Délai maximum d'attente du redémarrage
        reboot_timeout: 600
        # Message dans les logs système
        msg: "Redémarrage déclenché par Ansible"
        # Durée d'attente après le redémarrage
        post_reboot_delay: 10
 
    # Méthode 2 : Redémarrage conditionnel (si nécessaire)
    # - name: "Vérification si redémarrage nécessaire"
    #   stat:
    #     path: /var/run/reboot-required
    #   register: reboot_required
    #
    # - name: "Redémarrage si nécessaire"
    #   reboot:
    #     msg: "Redémarrage requis après mises à jour"
    #     pre_reboot_delay: 5
    #     reboot_timeout: 600
    #     post_reboot_delay: 10
    #   when: reboot_required.stat.exists
 
    - name: "Vérification que le système est opérationnel"
      wait_for_connection:
        delay: 10
        timeout: 300
 
    - name: "Affichage de l'uptime après redémarrage"
      shell: uptime
      register: uptime_result
 
    - name: "Affichage du résultat"
      debug:
        var: uptime_result.stdout_lines

Nous pouvons lancer ce playbook à l’aide de la commande suivante :

ansible-playbook -i dynamic-inventory.proxmox.yml restart-servers.yml