Aller au contenu
Réussir mon BTS SIO

Tape une notion, une commande ou le nom d'une épreuve.

Par exemple

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.cfg de 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 :

PaquetContenuVersion en novembre 2026
ansible-coreLe moteur et les commandes (ansible, ansible-playbook, ansible-galaxy, ansible-vault, ansible-doc, ansible-inventory, ansible-config), plus la collection ansible.builtin2.22.0, sorti le 2 novembre 2026 ; la branche 2.21 reste maintenue
ansibleansible-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.

MachineAdresseVLANSystèmeRôleGéré par Ansible en
Bastion192.168.10.21099 ADMINDebian 13Nœud de contrôle Ansible, point d'entrée de l'administration—
srv-journaux192.168.10.18020 SERVEURSLinuxJournaux, supervisionSSH
srv-web192.168.10.22560 DMZDebian 13, ApacheSite de suivi des livraisonsSSH
srv-ad, srv-ad2192.168.10.177, .18120 SERVEURSWindows Server 2025Contrôleurs de domaine ad.sorbier.example, DNS, DHCPWinRM ou SSH
srv-fichiers192.168.10.17820 SERVEURSWindows Server 2025Partages des servicesWinRM ou SSH
sw-etage1, sw-etage2192.168.10.211, .21299 ADMINCisco IOS XESwitchs d'étageSSH (network_cli)
pve1 à pve3192.168.10.213 à .21599 ADMINProxmox VE 9Hyperviseurs en clusterAPI 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.

VLAN 99 ADMIN, 192.168.10.208/28Bastion 192.168.10.210nœud de contrôle AnsibleSwitchssw-etage1 .211sw-etage2 .212SSHProxmox VEpve1 à pve3.213 à .215API, port 8006même VLAN :pas de pare-feuPoste d'administration .209Pare-feupfSenseVLAN 20 SERVEURSsrv-journaux .180SSH, TCP 22srv-ad .177srv-ad2 .181srv-fichiers .178WinRM HTTPS,TCP 5986VLAN 60 DMZsrv-web .225SSH, TCP 22Règle à ajouter au pare-feu : bastion vers serveurs Windows, TCP 5986
Le bastion, nœud de contrôle : les flux d'Ansible vers chaque zone du réseau de Sorbier

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) :

bash
# 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 :

text
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 :

yaml
---
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"
bash
# 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
text
# /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) :

bash
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 :

bash
# 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 :

bash
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 :

bash
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 :

  1. le fichier désigné par la variable d'environnement ANSIBLE_CONFIG ;
  2. ansible.cfg dans le dossier courant ;
  3. ~/.ansible.cfg dans ton dossier personnel ;
  4. /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 :

ini
[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églageEffet
inventoryL'inventaire utilisé par défaut, sans avoir à taper -i
roles_path, collections_pathOù chercher les rôles et les collections du projet
remote_userLe compte utilisé pour se connecter en SSH
private_key_fileLa clé privée à présenter ; elle peut aussi venir de l'agent SSH
forksLe nombre d'hôtes traités en parallèle (5 par défaut)
interpreter_python = auto_silentAnsible trouve seul le Python de chaque hôte, sans avertissement
become_methodLa méthode d'élévation de privilèges : sudo sous Linux
pipeliningPasse 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 :

bash
# 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 :

yaml
---
all:
  children:
    linux:
      hosts:
        srv-journaux:
          ansible_host: 192.168.10.180

Puis, depuis le dossier du projet :

bash
ansible linux -m ansible.builtin.ping
text
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) :

bash
ansible linux -b -m ansible.builtin.command -a "whoami"
text
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 :

MessageCause probableCorrection
UNREACHABLE! … Connection timed outPas de route ou flux bloqué par un pare-feuTester ssh à la main ; vérifier les règles du pare-feu
UNREACHABLE! … Permission denied (publickey)Clé absente, mauvais compte ou mauvais fichier authorized_keysVérifier remote_user, la clé chargée (ssh-add -l), les droits de ~/.ssh (700) et du fichier (600)
Host key verification failedEmpreinte inconnue ou changéeSe connecter une fois à la main ; si l'empreinte a changé sans raison, enquêter avant tout
Missing sudo passwordLe compte n'a pas NOPASSWDAjouter -K pour saisir le mot de passe, ou corriger sudoers.d
config file = None et inventaire introuvableCommande lancée hors du dossier du projet, ou dossier en 777Se 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 :

bash
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 :

bash
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 :

bash
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.

  1. Quel fichier de configuration est utilisé ?
  2. Combien d'hôtes sont traités en parallèle ?
  3. 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
  1. ~/sorbier-infra/ansible.cfg : le fichier du dossier courant passe avant celui du dossier personnel.
  2. 5, la valeur par défaut. Ansible ne fusionne pas les fichiers : ~/.ansible.cfg n'est pas lu du tout, son forks = 20 est ignoré.
  3. 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'option from="192.168.10.210" : seules les connexions venant du bastion sont acceptées ;
  • surtout, la clé de Moussa n'est pas dans authorized_keys du compte ansible : 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é ?

Chapitre terminé !

Fais les 3 exercices avant de passer à la suite : c'est en t'entraînant que tout se fixe.

chapitres
–
de série
–
du cours
–
Chapitre suivant : L'inventaire Ansible : hôtes, groupes et variablesRevoir le sommaire du cours