Niveau : Débutant Ansible / Intermédiaire Linux
Durée estimée : 3h à 4h
Distributions : Debian 13 (Trixie) · Rocky Linux 10 (Red Quartz)
Outil de virtualisation : VirtualBox (mode réseau Bridge)
Ce TP va te faire travailler sur deux machines virtuelles en même temps. L'objectif est double :
- Comprendre que mettre à jour un Linux, c'est pas la même commande selon la distro — et savoir lire ce qui s'est passé dans les logs.
- Automatiser tout ça avec Ansible, pour qu'une seule commande mette à jour tes deux machines d'un coup.
Tu vas travailler proprement, comme en vrai. Ça veut dire : on ne bricole pas sur la VM d'origine, on travaille toujours sur un clone.
Voici quelque chose que tout bon sysadmin finit par apprendre à la dure : ne jamais travailler directement sur une VM fraîchement installée.
Le principe est simple :
- Tu installes ta VM proprement (mises à jour de base, SSH activé, connexion root opérationnelle).
- Tu éteins la machine complètement.
- Tu crées un clone dans VirtualBox (clic droit sur la VM → Cloner → Clone complet).
- À partir de là, tu ne touches plus jamais à l'originale. Elle devient ton master, ta sauvegarde. Si tu plantes ton clone, tu en recrées un nouveau en 30 secondes.
C'est l'équivalent d'un snapshot, mais en plus propre : le clone est une vraie VM indépendante, et tu peux en faire autant que tu veux sans jamais réinstaller.
Conseil : nomme ton master clairement, par exemple
debian13-masteretrocky10-master, et mets-les dans un groupe VirtualBox "Masters". Tes clones de travail s'appellerontdebian13-tpetrocky10-tp.
Tu vas avoir besoin de deux machines virtuelles pour ce TP :
| VM | Distro | RAM | Disque | Rôle |
|---|---|---|---|---|
debian13-tp |
Debian 13 (Trixie) | 1 Go | 10 Go | Cible Ansible |
rocky10-tp |
Rocky Linux 10 (Red Quartz) | 1 Go | 10 Go | Cible Ansible |
Et tu vas aussi utiliser ta machine physique (ou une troisième VM si tu préfères) comme control node Ansible — c'est depuis là qu'Ansible sera lancé.
Si tu veux tout faire en VMs, tu peux aussi installer Ansible directement sur
debian13-tpet l'utiliser comme control node pour les deux.
Le mode Bridge permet à tes VMs d'apparaître comme de vraies machines sur ton réseau local. Elles auront leur propre adresse IP attribuée par ta box/ton DHCP, et tu pourras les joindre en SSH exactement comme une machine distante.
Dans VirtualBox, pour chaque VM :
- Va dans Paramètres → Réseau.
- Change "NAT" par "Accès par pont" (Bridge).
- Sélectionne ta carte réseau physique dans la liste déroulante.
- Démarre la VM et récupère son IP avec :
ip aNote les adresses IP de tes deux VMs, tu en auras besoin pour la suite.
Note lab vs production : dans ce TP, on se connecte directement en
rootvia SSH. C'est simple et ça te permet de te concentrer sur l'essentiel. En production réelle, on utiliserait un compte nominatif dédié avec des droits limités — mais pour apprendre les mécanismes de mise à jour et d'automatisation, c'est parfait comme ça.
Sur Debian 13, la connexion SSH root est désactivée par défaut. Il faut l'activer :
apt install -y openssh-server
# Autoriser root à se connecter en SSH
sed -i 's/^#PermitRootLogin.*/PermitRootLogin yes/' /etc/ssh/sshd_config
systemctl restart sshSur Rocky Linux 10, SSH est généralement déjà installé. Autorise root :
dnf install -y openssh-server
systemctl enable --now sshd
# Autoriser root à se connecter en SSH
sed -i 's/^#PermitRootLogin.*/PermitRootLogin yes/' /etc/ssh/sshd_config
systemctl restart sshdDepuis ta machine de contrôle, teste la connexion :
ssh root@IP_DEBIAN
ssh root@IP_ROCKYSi tu te connectes sans erreur, ton lab est prêt.
Une mise à jour Linux, c'est pas juste "avoir la dernière version". C'est avant tout une question de sécurité. Chaque paquet installé sur ton système peut contenir des failles. Les éditeurs publient régulièrement des correctifs, et si tu ne les appliques pas, ton serveur reste exposé.
L'ANSSI recommande d'ailleurs d'appliquer les mises à jour de sécurité rapidement, idéalement de manière automatisée et traçée. C'est exactement ce qu'on va construire dans ce TP.
Il y a deux grandes familles de gestionnaires de paquets Linux :
- APT (
apt) — utilisé par Debian, Ubuntu et leurs dérivés - DNF (
dnf) — utilisé par Red Hat, Rocky Linux, AlmaLinux, Fedora
Même objectif, syntaxe différente. Voyons ça en pratique.
Connecte-toi sur ta VM Debian 13 en SSH en root, puis exécute les commandes suivantes dans l'ordre.
apt updateCette commande ne met rien à jour. Elle interroge les serveurs de dépôts pour savoir si de nouvelles versions sont disponibles. C'est indispensable avant toute mise à jour.
Observe la sortie : tu vois les dépôts contactés, et à la fin un résumé du type :
X packages can be upgraded. Run 'apt list --upgradable' to see them.
apt list --upgradablePrends le temps de regarder la liste. Tu verras le nom du paquet, sa version actuelle et la version disponible.
apt upgrade -yLe -y répond automatiquement "oui" à toutes les confirmations. Sans lui, apt te demandera une validation. En production, tu peux vouloir retirer ce flag pour garder la main.
Remarque :
apt upgrademet à jour les paquets existants sans en supprimer ni en ajouter. Il existe aussiapt full-upgradequi peut supprimer des paquets obsolètes pour résoudre des conflits de dépendances — à utiliser avec précaution.
Certaines mises à jour (notamment le kernel) nécessitent un redémarrage pour être actives. Pour le savoir :
ls /var/run/reboot-required 2>/dev/null && echo "Redémarrage nécessaire" || echo "Pas besoin de redémarrer"Connecte-toi maintenant sur ta VM Rocky Linux 10 en root.
dnf check-updateCette commande liste les paquets qui ont une mise à jour disponible, avec leur version actuelle et la version cible. Le code retour est 100 si des mises à jour existent, 0 si tout est à jour — utile dans les scripts.
dnf upgrade -yPourquoi
upgradeet pasupdate? Les deux fonctionnent sur DNF, maisupgradepeut aussi supprimer des paquets obsolètes si nécessaire. C'est l'équivalent deapt full-upgrade. Par habitude et par sécurité, préfèreupgrade.
DNF garde un historique complet de toutes les opérations. C'est très pratique pour savoir ce qui a été fait et quand :
dnf historyTu verras la liste des transactions avec leur ID, la date, l'action effectuée et le nombre de paquets concernés. Pour voir le détail d'une transaction :
dnf history info <ID>Remplace <ID> par le numéro de la dernière transaction.
dnf needs-restarting -rSi la commande retourne un message et un code 1, un redémarrage est requis (souvent à cause d'une mise à jour du kernel).
Chaque action sur ton système laisse une trace dans les logs. Quand tu mets à jour des paquets, quand un service démarre ou plante, quand quelqu'un se connecte en SSH — tout est enregistré quelque part.
Savoir lire les logs, c'est une compétence fondamentale. En cas d'incident, c'est souvent la première chose qu'on te demandera de consulter.
Il y a deux approches pour lire les logs :
- Les fichiers texte dans
/var/log/— historique persistant, lisible aveccat,less,grep,tail - Journald via
journalctl— le journal systemd, centralisé et filtrable
Debian enregistre chaque opération APT dans deux fichiers :
/var/log/apt/history.log— résumé lisible des opérations (date, action, paquets)/var/log/dpkg.log— journal bas niveau de toutes les opérations dpkg (installation, configuration, suppression)
tail -50 /var/log/apt/history.logTu verras quelque chose comme :
Start-Date: 2026-03-30 10:15:42
Commandline: apt upgrade -y
Upgrade: openssh-server:amd64 (9.3p2-1, 9.6p1-1), ...
End-Date: 2026-03-30 10:16:05
C'est très lisible : tu vois exactement ce qui a été mis à jour, de quelle version vers quelle version, et à quelle heure.
grep "upgrade" /var/log/dpkg.log | tail -20Ce log est plus verbeux, avec l'état de chaque paquet à chaque étape (half-installed, unpacked, installed...).
journalctl -u apt-daily.service --since today
journalctl -u apt-daily-upgrade.service --since todayCes deux services systemd gèrent les mises à jour automatiques. Même si tu n'as pas activé les mises à jour auto, ces logs te donnent une idée de ce qui se passe en arrière-plan.
DNF produit plusieurs fichiers de log dans /var/log/ :
/var/log/dnf.log— résumé des opérations DNF (ce que DNF a fait, les repos interrogés)/var/log/dnf.rpm.log— le détail au niveau RPM : quel paquet installé, supprimé, mis à jour et dans quel ordre
tail -50 /var/log/dnf.logTu verras les opérations de mise à jour avec leur horodatage et leur résultat.
tail -100 /var/log/dnf.rpm.logCe fichier est précieux : il te montre chaque paquet traité, les scripts pré/post-installation exécutés, et les éventuels fichiers .rpmnew ou .rpmsave créés quand une mise à jour touche un fichier de configuration.
grep -i "upgraded" /var/log/dnf.rpm.log | tail -20journalctl --since "1 hour ago" | grep -i dnfjournalctl est ton meilleur ami pour explorer les logs systemd, disponible sur les deux distros.
Voici les commandes les plus utiles :
# Voir les logs depuis le dernier démarrage
journalctl -b
# Voir les logs du kernel uniquement
journalctl -k
# Suivre les logs en temps réel (comme tail -f)
journalctl -f
# Filtrer par priorité (err = erreurs uniquement)
journalctl -p err
# Voir les logs d'un service précis
journalctl -u ssh.service # Debian
journalctl -u sshd.service # Rocky
# Voir les logs des dernières 2 heures
journalctl --since "2 hours ago"
# Voir les logs entre deux dates
journalctl --since "2026-03-30 09:00" --until "2026-03-30 11:00"Exercice rapide : sur chacune de tes VMs, utilise
journalctlpour retrouver dans les logs la trace de la mise à jour que tu viens d'effectuer. Filtre par heure pour ne voir que ce qui s'est passé pendant la mise à jour.
Tu viens de mettre à jour deux machines à la main. Deux commandes différentes, deux connexions SSH, deux vérifications. Maintenant imagine que tu as 20 serveurs, ou 200. C'est là qu'Ansible entre en jeu.
Ansible, c'est un outil d'automatisation sans agent. Ça veut dire qu'il n'y a rien à installer sur les machines cibles — Ansible se connecte en SSH, pousse ses instructions, les exécute, et repart. Simple et sécurisé.
Le vocabulaire de base à retenir :
| Terme | Définition |
|---|---|
| Control node | La machine sur laquelle Ansible est installé et depuis laquelle tu lances les commandes |
| Managed nodes | Les machines cibles (tes VMs Debian et Rocky) |
| Inventaire | Le fichier qui liste tes machines cibles |
| Playbook | Le fichier YAML qui décrit les tâches à exécuter |
| Module | Une brique fonctionnelle d'Ansible (installer un paquet, copier un fichier, redémarrer un service...) |
Tu es connecté en root sur ta machine de contrôle. L'installation est directe.
apt update
apt install -y ansible
ansible --versiondnf install -y ansible-core
ansible --versionNote :
ansible-corec'est Ansible sans les collections de modules communautaires. Pour ce TP, c'est largement suffisant — on n'utilise que des modules built-in. Si plus tard tu as besoin de modules spécifiques, tu pourras les ajouter avecansible-galaxy collection install.
Ansible se connecte en SSH en root. Pour éviter de saisir le mot de passe root à chaque exécution de playbook, tu vas configurer une authentification par clé SSH.
ssh-keygen -t ed25519 -C "ansible-tp"Appuie sur Entrée pour accepter le chemin par défaut (/root/.ssh/id_ed25519). Laisse la passphrase vide pour ce TP.
ssh-copy-id root@IP_DEBIAN
ssh-copy-id root@IP_ROCKYssh root@IP_DEBIAN "echo Connexion OK"
ssh root@IP_ROCKY "echo Connexion OK"Si tu vois Connexion OK sans qu'on te demande de mot de passe, c'est bon.
Travaille dans un répertoire dédié, c'est une bonne habitude :
mkdir ~/tp-ansible
cd ~/tp-ansibleL'inventaire, c'est le fichier qui dit à Ansible "voici tes cibles". Crée le fichier inventory.ini :
[debian]
debian13-tp ansible_host=IP_DEBIAN ansible_user=root
[rocky]
rocky10-tp ansible_host=IP_ROCKY ansible_user=root
[linux:children]
debian
rockyExplications :
[debian]et[rocky]sont deux groupes de machines.[linux:children]est un groupe parent qui contient les deux — pratique pour cibler toutes les machines en même temps.ansible_hostprécise l'IP,ansible_user=rootdit à Ansible de se connecter directement en root.
Remplace IP_DEBIAN et IP_ROCKY par tes vraies adresses IP.
Crée un fichier ansible.cfg dans le même répertoire :
[defaults]
inventory = ./inventory.ini
host_key_checking = False
remote_user = rootOn se connecte en root, donc pas besoin de la section [privilege_escalation] — Ansible a déjà tous les droits. host_key_checking = False évite les confirmations SSH lors de la première connexion (acceptable en lab).
Avant d'écrire un playbook, vérifie qu'Ansible peut bien joindre tes machines avec le module ping :
ansible linux -m pingTu dois voir quelque chose comme :
debian13-tp | SUCCESS => {
"changed": false,
"ping": "pong"
}
rocky10-tp | SUCCESS => {
"changed": false,
"ping": "pong"
}
Ce
pingn'est pas un ping réseau ICMP — c'est un module Ansible qui vérifie la connexion SSH et que Python est disponible sur la cible.
Si tu as une erreur, vérifie :
- L'IP dans l'inventaire
- Que
PermitRootLogin yesest bien dans/etc/ssh/sshd_configsur les cibles - Que la clé SSH est bien copiée (
ssh-copy-idfait bien son travail)
C'est le cœur du TP. Tu vas écrire un playbook qui met à jour les deux distros en détectant automatiquement laquelle il traite.
Crée le fichier update.yml :
---
- name: Mise à jour de tous les serveurs Linux
hosts: linux
tasks:
- name: "[Debian] Mise à jour du cache APT"
ansible.builtin.apt:
update_cache: true
cache_valid_time: 3600
when: ansible_facts['os_family'] == "Debian"
- name: "[Debian] Mise à jour de tous les paquets"
ansible.builtin.apt:
upgrade: dist
autoremove: true
when: ansible_facts['os_family'] == "Debian"
- name: "[Rocky] Mise à jour de tous les paquets"
ansible.builtin.dnf:
name: "*"
state: latest
update_cache: true
when: ansible_facts['os_family'] == "RedHat"
- name: "Vérifier si un redémarrage est nécessaire (Debian)"
ansible.builtin.stat:
path: /var/run/reboot-required
register: reboot_required_debian
when: ansible_facts['os_family'] == "Debian"
- name: "Afficher si redémarrage nécessaire (Debian)"
ansible.builtin.debug:
msg: "⚠️ Redémarrage requis sur {{ inventory_hostname }}"
when:
- ansible_facts['os_family'] == "Debian"
- reboot_required_debian.stat.exists
- name: "Vérifier si un redémarrage est nécessaire (Rocky)"
ansible.builtin.command: dnf needs-restarting -r
register: reboot_required_rocky
failed_when: false
changed_when: false
when: ansible_facts['os_family'] == "RedHat"
- name: "Afficher si redémarrage nécessaire (Rocky)"
ansible.builtin.debug:
msg: "⚠️ Redémarrage requis sur {{ inventory_hostname }}"
when:
- ansible_facts['os_family'] == "RedHat"
- reboot_required_rocky.rc == 1Explications ligne par ligne :
hosts: linux— on cible le groupe parent, donc les deux machines.- Pas de
become— on est connecté en root, Ansible a déjà tous les droits. when: ansible_facts['os_family'] == "Debian"— cette condition fait qu'Ansible saute automatiquement la tâche si la machine n'est pas une Debian. C'est comme ça qu'on gère le multi-distro.ansible_facts['os_family']vaut"Debian"pour Debian/Ubuntu, et"RedHat"pour Rocky/RHEL/AlmaLinux.registerpermet de stocker le résultat d'une tâche dans une variable pour la réutiliser ensuite.failed_when: falseempêche Ansible de considérer la tâche comme échouée si la commande retourne un code non nul (ce que faitdnf needs-restartingquand un redémarrage est requis).
Avant d'appliquer quoi que ce soit, utilise le mode --check qui simule l'exécution sans rien modifier :
ansible-playbook update.yml --checkLis attentivement la sortie. Tu verras les tâches qui auraient été changed (modifiées) et celles qui seraient ok (déjà dans l'état attendu).
ansible-playbook update.ymlObserve la sortie. Ansible affiche pour chaque tâche son état :
ok— la tâche n'a rien changé (le système était déjà à jour)changed— la tâche a effectué une modificationskipping— la tâche a été ignorée (conditionwhennon remplie)failed— une erreur s'est produite
À la fin, tu as un PLAY RECAP qui résume tout. Si tu ne vois que du ok et du changed, sans failed, tout s'est bien passé.
Maintenant, reconnecte-toi sur chacune de tes VMs et vérifie que les logs reflètent bien la mise à jour effectuée par Ansible :
Sur Debian :
tail -30 /var/log/apt/history.logSur Rocky :
tail -50 /var/log/dnf.rpm.logTu dois voir les timestamps correspondant au moment où tu as lancé ton playbook. C'est la preuve que tout s'est bien passé — et c'est exactement ce qu'on te demandera de montrer lors d'un audit.
| Action | Debian 13 | Rocky Linux 10 |
|---|---|---|
| Rafraîchir les dépôts | apt update |
dnf check-update |
| Mettre à jour | apt upgrade -y |
dnf upgrade -y |
| Voir les logs de maj | tail /var/log/apt/history.log |
tail /var/log/dnf.rpm.log |
| Besoin de redémarrage ? | ls /var/run/reboot-required |
dnf needs-restarting -r |
| Logs systemd | journalctl -u apt-daily.service |
journalctl -u dnf-makecache.service |
Si tu veux enrichir ce playbook, voici quelques pistes :
- Ajouter un handler de redémarrage automatique : si un redémarrage est requis, déclencher automatiquement un
rebootvia le moduleansible.builtin.reboot. - Générer un rapport de mise à jour : utiliser le module
templatepour créer un fichier de rapport sur chaque machine avec la liste des paquets mis à jour. - Envoyer une notification : envoyer un email ou un message Slack en fin de playbook pour informer qu'une mise à jour a été effectuée.
- Planifier le playbook : utiliser
cronousystemd timersur le control node pour exécuter ce playbook chaque semaine automatiquement. - Limiter aux mises à jour de sécurité :
- Debian :
apt-get upgrade --with-new-pkgs $(apt-get --just-print upgrade 2>&1 | grep security | awk '{print $2}') - Rocky :
dnf upgrade --security -y
- Debian :
TP rédigé le 30/03/2026 — Debian 13 Trixie · Rocky Linux 10.1 Red Quartz · Ansible Core