Chapitre 221 minIntermédiaire
Installer Ansible et préparer les serveurs
Par Josselyn C., prof de BTS SIO. Mis à jour le .
À la fin de ce chapitre, tu sauras
- choisir entre ansible-core et le paquet ansible, et la bonne méthode d'installation ;
- installer Ansible et ses collections sur le nœud de contrôle ;
- préparer un serveur Linux : compte dédié, clé SSH, sudo ;
- écrire un fichier
ansible.cfgde projet ; - vérifier la connexion avec le module
ping.
3 exercices corrigés1 schéma
Installer Ansible, c'est installer ansible-core et ses collections sur une seule machine, le nœud de contrôle, puis préparer chaque serveur à recevoir ses connexions : un compte dédié, une clé SSH, des droits sudo. Ce chapitre présente le laboratoire de Sorbier, installe Ansible sur Debian 13, écrit le fichier ansible.cfg du projet et termine par la première commande, le ping.
ansible-core ou ansible : deux paquets
Deux paquets portent le nom d'Ansible, et la différence compte :
| Paquet | Contenu | Version en novembre 2026 |
|---|---|---|
ansible-core | Le moteur et les commandes (ansible, ansible-playbook, ansible-galaxy, ansible-vault, ansible-doc, ansible-inventory, ansible-config), plus la collection ansible.builtin | 2.22.0, sorti le 2 novembre 2026 ; la branche 2.21 reste maintenue |
ansible | ansible-core plus une sélection d'environ une centaine de collections de la communauté | 14.5, qui embarque ansible-core 2.21 ; la version 15, construite sur 2.22, est en préversion |
Le paquet ansible est pratique pour découvrir : tout est déjà là. En production, on préfère ansible-core et un fichier requirements.yml qui liste exactement les collections dont le projet a besoin, avec leur version : chaque administrateur et chaque pipeline obtient alors le même environnement.
Le laboratoire de Sorbier
Les machines de ce cours sont celles de Sorbier Logistique ; leur plan d'adressage vient du cours Routage et commutation (le réseau 192.168.10.0/24 découpé en VLAN) et du cours Cybersécurité des infrastructures (la DMZ, le VLAN d'administration et son bastion). Tu n'en as pas besoin de toutes pour suivre : un nœud de contrôle et une VM Debian suffisent pour les chapitres 2 à 9.
| Machine | Adresse | VLAN | Système | Rôle | Géré par Ansible en |
|---|---|---|---|---|---|
| Bastion | 192.168.10.210 | 99 ADMIN | Debian 13 | Nœud de contrôle Ansible, point d'entrée de l'administration | — |
srv-journaux | 192.168.10.180 | 20 SERVEURS | Linux | Journaux, supervision | SSH |
srv-web | 192.168.10.225 | 60 DMZ | Debian 13, Apache | Site de suivi des livraisons | SSH |
srv-ad, srv-ad2 | 192.168.10.177, .181 | 20 SERVEURS | Windows Server 2025 | Contrôleurs de domaine ad.sorbier.example, DNS, DHCP | WinRM ou SSH |
srv-fichiers | 192.168.10.178 | 20 SERVEURS | Windows Server 2025 | Partages des services | WinRM ou SSH |
sw-etage1, sw-etage2 | 192.168.10.211, .212 | 99 ADMIN | Cisco IOS XE | Switchs d'étage | SSH (network_cli) |
pve1 à pve3 | 192.168.10.213 à .215 | 99 ADMIN | Proxmox VE 9 | Hyperviseurs en cluster | API HTTPS |
Pourquoi le bastion ? Chez Sorbier, le pare-feu n'autorise les ports d'administration des serveurs (SSH, RDP, HTTPS d'administration) que depuis le bastion : c'est l'endroit naturel pour Ansible, qui en a besoin pour tout le parc. Chaque administrateur s'y connecte avec son compte nominatif et y garde sa clé ; le dépôt Git du projet est cloné dans son dossier personnel.
Les règles existantes du pare-feu autorisent déjà le bastion vers les serveurs en TCP 22. Pour gérer les serveurs Windows en WinRM, il faut ajouter une règle : source 192.168.10.210, destination les serveurs Windows, TCP 5986. Les switchs et les hyperviseurs sont dans le même VLAN que le bastion : leurs échanges ne traversent pas le pare-feu.
Installer Ansible sur Debian 13
Debian 13 propose un paquet ansible-core, mais en version 2.19, dont la maintenance s'arrête fin novembre 2026. Pour avoir une version à jour, la méthode recommandée par la documentation d'Ansible est pipx : il installe une application Python dans son propre environnement virtuel, sans toucher au Python du système, et met ses commandes dans ton PATH.
Sur le bastion, avec ton compte (pas root) :
# pipx et git viennent des paquets Debian
sudo apt update
sudo apt install pipx git
# Ajoute ~/.local/bin au PATH (ouvre un nouveau terminal ensuite)
pipx ensurepath
# Installe ansible-core dans son environnement
pipx install ansible-core
# Bibliothèques Python dont auront besoin certaines connexions et collections
pipx inject ansible-core pywinrm proxmoxer requests
ansible --version
pipx inject ajoute des bibliothèques dans l'environnement d'Ansible : pywinrm pour la connexion WinRM aux serveurs Windows (chapitre 10), proxmoxer et requests pour les modules Proxmox (chapitre 13). Tu peux les ajouter plus tard, au moment où tu en as besoin.
La sortie de ansible --version, lancée depuis le dossier du projet :
ansible [core 2.22.0]
config file = /home/clambert/sorbier-infra/ansible.cfg
configured module search path = ['/home/clambert/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
ansible python module location = /home/clambert/.local/share/pipx/venvs/ansible-core/lib/python3.13/site-packages/ansible
ansible collection location = /home/clambert/sorbier-infra/collections
executable location = /home/clambert/.local/bin/ansible
python version = 3.13.5 (…) (/home/clambert/.local/share/pipx/venvs/ansible-core/bin/python)
jinja version = 3.1.6
pyyaml version = 6.0.3 (with libyaml v0.2.5)
Lis les deux lignes qui te sauveront souvent : config file dit quel ansible.cfg est utilisé (s'il affiche None, ton fichier n'est pas lu), et ansible collection location dit où Ansible cherche les collections.
Pour mettre à jour plus tard : pipx upgrade ansible-core. Pour installer le paquet complet à la place : pipx install --include-deps ansible (l'option est nécessaire, car les commandes appartiennent à la dépendance ansible-core).
Installer les collections
Les modules qui ne sont pas dans ansible.builtin viennent de collections, téléchargées depuis Ansible Galaxy (galaxy.ansible.com). Le projet les déclare dans un fichier requirements.yml :
---
collections:
- name: ansible.posix
version: ">=2.2.0"
- name: community.general
version: ">=14.0.0"
- name: ansible.windows
version: ">=3.9.0"
- name: microsoft.ad
version: ">=1.12.0"
- name: cisco.ios
version: ">=11.6.0"
- name: community.proxmox
version: ">=2.1.0"
# Installe les collections dans le dossier collections/ du projet
ansible-galaxy collection install -r requirements.yml -p collections
# Liste ce qui est installé, et où
ansible-galaxy collection list
# /home/clambert/sorbier-infra/collections/ansible_collections
Collection Version
---------------------------------------- -------
ansible.netcommon 8.7.1
ansible.posix 2.2.2
ansible.utils 6.1.1
ansible.windows 3.9.2
cisco.ios 11.6.0
community.general 14.0.0
community.proxmox 2.1.0
microsoft.ad 1.12.1
ansible.netcommon et ansible.utils n'étaient pas demandées : ce sont des dépendances de cisco.ios, installées automatiquement. Garder les collections dans le dossier du projet (et non dans ~/.ansible/collections) permet d'avoir des versions différentes d'un projet à l'autre ; ce dossier ne va pas dans Git, puisque requirements.yml suffit à le reconstruire.
Préparer un serveur Linux
Ansible se connecte aux serveurs Linux en SSH, avec un compte qui doit pouvoir devenir root par sudo. Chez Sorbier, ce compte s'appelle ansible sur tous les serveurs ; il n'a pas de mot de passe et n'accepte que des clés, et seulement depuis le bastion.
1. Sur le bastion, crée ta paire de clés (une par administrateur, protégée par une phrase de passe) :
ssh-keygen -t ed25519 -C "clambert@bastion" -f ~/.ssh/ansible_ed25519
2. Sur le serveur à gérer (ici srv-journaux), avec ton compte d'administrateur, crée le compte et ses droits :
# Compte sans mot de passe : la connexion se fera uniquement par clé
sudo adduser --disabled-password --comment "Compte Ansible" ansible
# Droit d'utiliser sudo sans mot de passe, dans un fichier à part
echo 'ansible ALL=(ALL:ALL) NOPASSWD: ALL' | sudo tee /etc/sudoers.d/ansible
sudo chmod 0440 /etc/sudoers.d/ansible
sudo visudo -cf /etc/sudoers.d/ansible
# Clé publique de l'administrateur, utilisable seulement depuis le bastion
sudo install -d -m 0700 -o ansible -g ansible /home/ansible/.ssh
echo 'from="192.168.10.210" ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIF3pQ8rT1mZ6sV0yK4nD9cW2xJ7hB5eL8aG1uR3tN6oP clambert@bastion' \
| sudo tee /home/ansible/.ssh/authorized_keys
sudo chown ansible:ansible /home/ansible/.ssh/authorized_keys
sudo chmod 0600 /home/ansible/.ssh/authorized_keys
visudo -cf vérifie la syntaxe du fichier : une erreur dans un fichier de sudoers.d peut bloquer sudo pour tout le monde. L'option from="192.168.10.210" devant la clé refuse cette clé si la connexion vient d'ailleurs que du bastion : une clé volée ne sert à rien depuis un autre poste.
3. Depuis le bastion, connecte-toi une première fois à la main, pour vérifier la clé et enregistrer l'empreinte du serveur :
ssh -i ~/.ssh/ansible_ed25519 ansible@192.168.10.180
SSH affiche l'empreinte de la clé du serveur et demande confirmation. Compare-la avec celle affichée sur le serveur par ssh-keygen -lf /etc/ssh/ssh_host_ed25519_key.pub avant de répondre yes : c'est ce qui te protège d'une usurpation. L'empreinte est ensuite enregistrée dans ~/.ssh/known_hosts, et Ansible la vérifiera à chaque connexion.
4. Charge ta clé dans l'agent SSH pour ne pas taper ta phrase de passe à chaque connexion :
eval "$(ssh-agent -s)"
ssh-add ~/.ssh/ansible_ed25519
Préparer chaque serveur ainsi à la main est fastidieux. Deux façons d'éviter la corvée : les VM créées depuis un modèle cloud-init reçoivent le compte et la clé à leur premier démarrage (chapitre 13), et un petit playbook de démarrage peut faire ces étapes avec un compte existant (exercices du chapitre 5).
Le fichier ansible.cfg
Le comportement d'Ansible se règle dans un fichier ansible.cfg au format INI. Ansible prend le premier qu'il trouve dans cet ordre, sans fusionner les autres :
- le fichier désigné par la variable d'environnement
ANSIBLE_CONFIG; ansible.cfgdans le dossier courant ;~/.ansible.cfgdans ton dossier personnel ;/etc/ansible/ansible.cfg.
On place donc un ansible.cfg à la racine du projet, versionné avec lui, et on lance toujours les commandes depuis ce dossier. Celui de Sorbier :
[defaults]
inventory = inventaire/hosts.yml
roles_path = roles
collections_path = collections
remote_user = ansible
private_key_file = ~/.ssh/ansible_ed25519
forks = 10
interpreter_python = auto_silent
[privilege_escalation]
become_method = sudo
[ssh_connection]
pipelining = True
| Réglage | Effet |
|---|---|
inventory | L'inventaire utilisé par défaut, sans avoir à taper -i |
roles_path, collections_path | Où chercher les rôles et les collections du projet |
remote_user | Le compte utilisé pour se connecter en SSH |
private_key_file | La clé privée à présenter ; elle peut aussi venir de l'agent SSH |
forks | Le nombre d'hôtes traités en parallèle (5 par défaut) |
interpreter_python = auto_silent | Ansible trouve seul le Python de chaque hôte, sans avertissement |
become_method | La méthode d'élévation de privilèges : sudo sous Linux |
pipelining | Passe le module à Python par le canal SSH au lieu de copier un fichier : beaucoup moins de connexions, donc des playbooks nettement plus rapides. Désactivé par défaut ; il exige que sudo n'impose pas de terminal (requiretty), ce qui est le cas sur Debian |
Deux commandes pour vérifier ce qui est réellement pris en compte :
# Seulement les réglages modifiés, avec le fichier d'où ils viennent
ansible-config dump --only-changed
# Un fichier d'exemple avec tous les réglages, commentés
ansible-config init --disabled > ansible.cfg.exemple
Le premier ping
Il reste à dire à Ansible quelles machines gérer. Le chapitre 3 détaille l'inventaire ; pour le premier test, un fichier inventaire/hosts.yml minimal suffit :
---
all:
children:
linux:
hosts:
srv-journaux:
ansible_host: 192.168.10.180
Puis, depuis le dossier du projet :
ansible linux -m ansible.builtin.ping
srv-journaux | SUCCESS => {
"changed": false,
"ping": "pong"
}
Le module ping n'envoie pas de ping ICMP. Il vérifie toute la chaîne : connexion SSH, authentification par clé, présence d'un Python utilisable, exécution d'un module. pong signifie qu'Ansible peut travailler sur cet hôte.
Vérifie aussi l'élévation de privilèges, avec -b (become) :
ansible linux -b -m ansible.builtin.command -a "whoami"
srv-journaux | CHANGED | rc=0 >>
root
CHANGED apparaît parce qu'Ansible ne sait pas ce que fait une commande arbitraire : il suppose qu'elle a modifié quelque chose. L'essentiel est la réponse root : sudo fonctionne.
Les échecs du premier contact, et leur cause :
| Message | Cause probable | Correction |
|---|---|---|
UNREACHABLE! … Connection timed out | Pas de route ou flux bloqué par un pare-feu | Tester ssh à la main ; vérifier les règles du pare-feu |
UNREACHABLE! … Permission denied (publickey) | Clé absente, mauvais compte ou mauvais fichier authorized_keys | Vérifier remote_user, la clé chargée (ssh-add -l), les droits de ~/.ssh (700) et du fichier (600) |
Host key verification failed | Empreinte inconnue ou changée | Se connecter une fois à la main ; si l'empreinte a changé sans raison, enquêter avant tout |
Missing sudo password | Le compte n'a pas NOPASSWD | Ajouter -K pour saisir le mot de passe, ou corriger sudoers.d |
config file = None et inventaire introuvable | Commande lancée hors du dossier du projet, ou dossier en 777 | Se placer dans le projet ; corriger les droits |
Exercices
Exercice 1 sur 3 Préparer srv-web Réussi À revoir
Écris les commandes à taper pour que le bastion puisse gérer srv-web (192.168.10.225, Debian 13, dans la DMZ) avec Ansible, en partant d'un compte d'administrateur clambert qui a déjà sudo sur ce serveur. La clé publique de Chloé est dans le fichier ~/.ssh/ansible_ed25519.pub du bastion. Termine par la commande de test, lancée depuis le bastion.
Voir la réponseMasquer la réponse de l'exercice 1
Sur srv-web :
sudo adduser --disabled-password --comment "Compte Ansible" ansible
echo 'ansible ALL=(ALL:ALL) NOPASSWD: ALL' | sudo tee /etc/sudoers.d/ansible
sudo chmod 0440 /etc/sudoers.d/ansible
sudo visudo -cf /etc/sudoers.d/ansible
sudo install -d -m 0700 -o ansible -g ansible /home/ansible/.ssh
Puis copie la clé publique, précédée de from="192.168.10.210" , dans /home/ansible/.ssh/authorized_keys (propriétaire ansible, droits 0600). Depuis le bastion, prépare la ligne et envoie-la dans ton dossier sur le serveur :
echo "from=\"192.168.10.210\" $(cat ~/.ssh/ansible_ed25519.pub)" > /tmp/cle-ansible.pub
scp /tmp/cle-ansible.pub clambert@192.168.10.225:
puis, sur srv-web :
sudo install -m 0600 -o ansible -g ansible ~/cle-ansible.pub /home/ansible/.ssh/authorized_keys
rm ~/cle-ansible.pub
Passer par un fichier évite le piège du tube : sudo demande le mot de passe de clambert, et il ne peut pas le lire dans une commande ssh non interactive dont l'entrée standard est déjà occupée par la clé.
Ensuite : ssh -i ~/.ssh/ansible_ed25519 ansible@192.168.10.225 une fois, en vérifiant l'empreinte, puis, après avoir ajouté srv-web à l'inventaire, ansible srv-web -m ansible.builtin.ping. Dans la DMZ, le flux bastion vers srv-web en TCP 22 doit être autorisé par le pare-feu, ce que prévoit déjà la matrice des flux de Sorbier.
Tu avais trouvé ?
Exercice 2 sur 3 Quel ansible.cfg ? Réussi À revoir
Chloé a un fichier ~/.ansible.cfg qui contient forks = 20. Le projet ~/sorbier-infra contient un ansible.cfg sans réglage forks. Elle lance ansible-playbook site.yml depuis ~/sorbier-infra.
- Quel fichier de configuration est utilisé ?
- Combien d'hôtes sont traités en parallèle ?
- Que se passe-t-il si elle lance la même commande depuis son dossier personnel, en écrivant
ansible-playbook sorbier-infra/site.yml?
Voir la réponseMasquer la réponse de l'exercice 2
~/sorbier-infra/ansible.cfg: le fichier du dossier courant passe avant celui du dossier personnel.- 5, la valeur par défaut. Ansible ne fusionne pas les fichiers :
~/.ansible.cfgn'est pas lu du tout, sonforks = 20est ignoré. - Le dossier courant est alors
~, qui ne contient pas d'ansible.cfg: Ansible prend~/.ansible.cfg. L'inventaire, le chemin des rôles et le compte distant du projet ne sont plus définis : le playbook ne trouve pas ses hôtes (« provided hosts list is empty ») ou pas ses rôles. Il faut lancer les commandes depuis le dossier du projet.
Tu avais trouvé ?
Exercice 3 sur 3 Lire une erreur Réussi À revoir
Moussa lance ansible linux -m ansible.builtin.ping et obtient pour srv-journaux : UNREACHABLE! => {"changed": false, "msg": "Failed to connect to the host via ssh: ansible@192.168.10.180: Permission denied (publickey).", "unreachable": true}. La commande ssh ansible@192.168.10.180 lancée depuis le poste d'administration 192.168.10.209 donne la même erreur, alors que Chloé, depuis le bastion, se connecte sans problème. Explique les deux échecs et dis comment Moussa doit procéder.
Voir la réponseMasquer la réponse de l'exercice 3
Le serveur refuse la clé présentée. Deux causes se cumulent :
- depuis le poste
.209, la clé de Chloé serait de toute façon refusée à cause de l'optionfrom="192.168.10.210": seules les connexions venant du bastion sont acceptées ; - surtout, la clé de Moussa n'est pas dans
authorized_keysdu compteansible: seule celle de Chloé y a été déposée.
Moussa doit créer sa propre paire de clés sur le bastion, faire ajouter sa clé publique (précédée de from="192.168.10.210") dans authorized_keys du compte ansible, puis lancer Ansible depuis le bastion. Le rôle socle du chapitre 8 gérera ensuite ces clés pour tous les serveurs d'un coup.
Tu avais trouvé ?