
Une commande ad-hoc Ansible exécute un module unique sur un pattern d’hôtes, sans écrire de playbook. C’est l’outil parfait pour les opérations one-shot : tester la connectivité, vérifier la version d’un paquet, redémarrer un service sur un sous-ensemble de la fleet, copier un fichier ponctuel. Les commandes ad-hoc constituent un objectif explicite de l’examen RHCE EX294 — vous devez savoir les écrire à la volée sans hésiter. Cette page couvre la syntaxe, les modules essentiels avec sorties réelles, les patterns d’hôtes, et les critères pour basculer en playbook.
Ce que vous allez apprendre
Section intitulée « Ce que vous allez apprendre »- Comprendre la syntaxe
ansible PATTERN -m MODULE -a "ARGS"et chaque composant ; - Lancer les modules de base :
ping,setup,command,shell,dnf,service,copy,file; - Cibler des hôtes avec les patterns : groupes, wildcards, intersections, exclusions ;
- Reconnaître les trois statuts dans la sortie (
SUCCESS,CHANGED,FAILED) ; - Décider quand une opération doit basculer en playbook (idempotence stricte, multi-tâches, traçabilité).
Prérequis
Section intitulée « Prérequis »- Le lab provisionné et préparé (cf. Préparer le lab KVM) ;
- L’inventaire YAML fonctionnel et la connexion SSH validée par
ansible all -m ping(cf. Première connexion SSH).
La syntaxe générale
Section intitulée « La syntaxe générale »ansible PATTERN -m MODULE [-a "ARGS"] [OPTIONS]| Composant | Rôle | Exemple |
|---|---|---|
PATTERN | Cible un ou plusieurs hôtes | all, web1.lab, webservers, web* |
-m MODULE | Module à exécuter | ping, setup, dnf, service, copy, file |
-a "ARGS" | Arguments du module (clé=valeur) | name=nginx state=present |
OPTIONS | Options Ansible | --check, --diff, -b (become), -K (ask sudo pwd) |
Si vous omettez -m, Ansible utilise par défaut le module command (ansible all -a 'uptime' est équivalent à ansible all -m command -a 'uptime'). Mais soyez explicite — vous gagnerez en clarté.
Tour des modules essentiels
Section intitulée « Tour des modules essentiels »ping — tester la chaîne SSH + Python
Section intitulée « ping — tester la chaîne SSH + Python »ansible all -m pingweb1.lab | SUCCESS => { "changed": false, "ping": "pong"}db1.lab | SUCCESS => { "changed": false, "ping": "pong"}web2.lab | SUCCESS => { "changed": false, "ping": "pong"}control-node.lab | SUCCESS => { "changed": false, "ping": "pong"}SUCCESS + changed: false : la chaîne fonctionne et rien n’a été modifié.
setup — récupérer les facts d’un hôte
Section intitulée « setup — récupérer les facts d’un hôte »Le module setup affiche les centaines de variables que la phase gather_facts collecte au début de chaque play. Pratique pour vérifier la valeur d’un fact :
ansible web1.lab -m setup -a 'filter=ansible_distribution*'web1.lab | SUCCESS => { "ansible_facts": { "ansible_distribution": "AlmaLinux", "ansible_distribution_file_parsed": true, "ansible_distribution_file_path": "/etc/redhat-release", "ansible_distribution_file_variety": "RedHat", "ansible_distribution_major_version": "10", "ansible_distribution_release": "Heliotrope Lion", "ansible_distribution_version": "10.1" }, "changed": false}Le filter= accepte un wildcard glob. Sans filtre, vous récupérez plusieurs centaines de lignes de facts.
command — exécuter une commande sans shell
Section intitulée « command — exécuter une commande sans shell »ansible webservers -m command -a 'uptime'web1.lab | CHANGED | rc=0 >> 14:40:14 up 6 min, 2 users, load average: 0.06, 0.12, 0.06web2.lab | CHANGED | rc=0 >> 14:40:15 up 6 min, 2 users, load average: 0.06, 0.10, 0.04Statut CHANGED parce que command est non-idempotent par défaut. Le rc=0 confirme l’exit code zéro. Pas de pipe, pas de redirection (>), pas de variable d’environnement — c’est le rôle de shell.
shell — exécuter avec un shell complet
Section intitulée « shell — exécuter avec un shell complet »ansible webservers -m shell -a 'df -h / | tail -1'web1.lab | CHANGED | rc=0 >>/dev/vda4 8.8G 1.1G 7.8G 12% /web2.lab | CHANGED | rc=0 >>/dev/vda4 8.8G 1.1G 7.8G 12% /shell accepte les pipes, redirections, et variables d’environnement. À utiliser uniquement quand command ne suffit pas — shell est un vecteur d’injection si la valeur vient d’une variable mal contrôlée.
dnf — gérer les paquets RPM (idempotent)
Section intitulée « dnf — gérer les paquets RPM (idempotent) »ansible db1.lab -m dnf -a 'name=tree state=present' --checkdb1.lab | CHANGED => { "changed": true, "msg": "Check mode: No changes made, but would have if not in check mode", "rc": 0, "results": [ "Installed: tree-2.1.0-8.el10.x86_64" ]}L’option --check (dry-run) montre ce qui serait fait sans appliquer le changement. C’est la combinaison parfaite pour valider une commande risquée avant de la lancer pour de vrai.
service — gérer les services systemd (idempotent)
Section intitulée « service — gérer les services systemd (idempotent) »ansible web1.lab -m service -a 'name=firewalld state=started'web1.lab | SUCCESS => { "changed": false, "name": "firewalld", "state": "started", ...}changed: false parce que firewalld est déjà démarré (le playbook de préparation l’a fait). service est idempotent : il ne tente l’action que si l’état réel diverge de l’état désiré.
copy — copier un fichier (idempotent par checksum)
Section intitulée « copy — copier un fichier (idempotent par checksum) »echo "test ansible 2026" > /tmp/ansible-test.txtansible web1.lab -m copy -a 'src=/tmp/ansible-test.txt dest=/tmp/ansible-test.txt mode=0644'Premier run :
web1.lab | CHANGED => { "changed": true, "checksum": "6e8652783ec319763ffa93599d00443fba131901", "dest": "/tmp/ansible-test.txt", "mode": "0644", ...}Second run immédiat :
web1.lab | SUCCESS => { "changed": false, "checksum": "6e8652783ec319763ffa93599d00443fba131901", "dest": "/tmp/ansible-test.txt", "mode": "0644", ...}SUCCESS + changed: false : Ansible a comparé le checksum SHA-1 local et distant, ils sont identiques, aucun transfert n’a eu lieu. C’est l’idempotence par checksum.
file — gérer les permissions et les chemins (idempotent)
Section intitulée « file — gérer les permissions et les chemins (idempotent) »ansible web1.lab -m file -a 'path=/tmp/ansible-test.txt state=absent'web1.lab | CHANGED => { "changed": true, "path": "/tmp/ansible-test.txt", "state": "absent"}Au second run, le fichier est déjà absent → changed: false. Le module file couvre aussi les permissions (mode, owner, group), les liens symboliques (state=link) et la création de répertoires (state=directory).
Les patterns d’hôtes
Section intitulée « Les patterns d’hôtes »| Pattern | Cible |
|---|---|
all | Tous les hôtes de l’inventaire |
web1.lab | Un seul hôte par son nom exact |
webservers | Tous les hôtes du groupe webservers |
webservers:dbservers | Union : tous les hôtes des deux groupes |
webservers:&rhce_lab | Intersection : hôtes dans webservers ET dans rhce_lab |
webservers:!web1.lab | Exclusion : tous les webservers SAUF web1.lab |
web* | Wildcard : tout hôte commençant par web |
web*:!*.local | Combinaison : web* SAUF *.local |
Exemple concret — appliquer un patch sur tous les webservers sauf un :
ansible 'webservers:!web1.lab' -m dnf -a 'name=* state=latest' -bL’option -b active become (sudo). Le * côté name= met tous les paquets à jour.
Les trois statuts de sortie
Section intitulée « Les trois statuts de sortie »| Statut | Couleur | Signification |
|---|---|---|
SUCCESS | vert | Module idempotent, aucun changement |
CHANGED | jaune | Module a appliqué un changement réel |
FAILED | rouge | Module a échoué (rc != 0, exception, etc.) |
UNREACHABLE | rouge | Hôte injoignable en SSH |
SUCCESS + changed: false est le signal qu’un second passage n’aurait rien à faire — c’est la preuve d’idempotence au niveau ad-hoc.
Quand basculer en playbook
Section intitulée « Quand basculer en playbook »L’ad-hoc atteint ses limites dès que l’opération devient :
- Multi-tâches : enchaîner installation + configuration + démarrage de service. Un playbook gère la séquence et arrête tout en cas d’erreur intermédiaire.
- Conditionnelle : « installer nginx si la distribution est RedHat ». Un
when:dans un play est plus propre qu’un script qui appelleansibleplusieurs fois. - Traçable : un playbook YAML versionné dans Git documente l’opération, sa relance est reproductible. Une commande ad-hoc dans un terminal est volatile.
- Idempotente avec variables : ad-hoc accepte
-a "name={{ var }}"mais sans inventaire de variables, ça devient vite illisible. Variables, vars_files et group_vars sont la zone du playbook.
Règle pratique : plus de 3 commandes ad-hoc consécutives sur la même cible = il est temps d’écrire un playbook.
Pièges fréquents
Section intitulée « Pièges fréquents »| Symptôme | Cause | Fix |
|---|---|---|
module not found ou silence | Mauvais nom de module ou collection non installée | ansible-doc -l | grep <nom> ; ansible-galaxy collection install <fqcn> |
Pipes (|) and redirections require a shell | command reçoit un pipe alors qu’il ne supporte pas | Bascule en -m shell (et seulement si nécessaire) |
changed=true à chaque run sur command/shell | Modules non idempotents par nature | Ajouter creates: ou removes: ; mieux : utiliser le module idempotent dédié (dnf, service, file) |
--ask-pass demandé alors que la clé est OK | Ansible n’a pas trouvé la clé | Vérifier ansible.cfg (private_key_file) ou poser ansible_ssh_private_key_file dans l’inventaire |
À retenir
Section intitulée « À retenir »- La syntaxe
ansible PATTERN -m MODULE -a "ARGS"est l’outil principal pour les opérations one-shot sur une fleet. - Les modules essentiels sont
ping,setup,command,shell,dnf,service,copy,file— à connaître par cœur pour la RHCE. - Les patterns d’hôtes combinent groupes, wildcards, intersections (
&) et exclusions (!). SUCCESS + changed: false= idempotence ;CHANGED= action réelle ;FAILED= à investiguer.- Bascule en playbook dès que l’opération est multi-tâches, conditionnelle, traçable ou paramétrée.
- L’option
--checkest le mode dry-run universel pour valider sans appliquer.