Skip to content

Ad-hoc Commands

Objectif

Apprendre les bases des commandes ansible en mode ad-hoc (interactif) : exécuter des modules depuis la ligne de commande.

Durée

~20 minutes

Ad-hoc

/ˌæd ˈhɑːk/ Made or happening only for a particular purpose or need, not planned before it happens.

Une commande ad-hoc est une exécution ponctuelle d'un module sur un groupe d'hôtes depuis la ligne de commande. Les modules sont développés en python.

Mise en place du lab

cd $HOME/git/gh/formation-ansible/atelier-07
vagrant up
^up^ssh ansible

# sur le control host
cd ansible/projets/ema/playbooks/

Une commande ad-hoc suit toujours la structure :

ansible <groupe> -m <module> -a "<arguments>"
  • <groupe> : un groupe de l'inventaire (testing nom généré, all pour tout le monde...), un hôte précis, ou un motif (debian:&web).
  • -m <module> : le module à exécuter. Si -m est omis, le module command est utilisé par défaut.
  • -a ["<arguments...] : les arguments du module, sous forme de chaîne clé=valeur ou de commande brute selon le module.

command est le module par défaut

Les deux commandes qui suit sont équivalentes :

ansible testing -m command -a "df -h /"
ansible testing -a "df -h /"

L'option -o (one-line)

Par défaut, ansible imprime un bloc multi-lignes par hôte, ce qui devient vite illisible sur un gros parc. L'option -o condense la sortie sur une seule ligne par hôte :

ansible testing -m command -a "hostname" -o

command vs shell

shell != command

Le module command n'interprète pas les opérateurs shell (|, >, <, &&, $VAR…). Tout ce qui est passé via -a est traité comme une liste d'arguments. Pour les utiliser, il faut utiliser le module shell.

Exemples qui nécessitent shell :

# pipe : compter le nombre de processus
ansible testing -m shell -a "ps -ef | wc -l" -o

# variable d'environnement évaluée sur la cible
ansible testing -m shell -a 'echo $RANDOM' -o

# choisir explicitement l'interpréteur
ansible testing -m shell -a 'echo $RANDOM executable=/bin/bash' -o

Simple quotes pour les variables shell

Dans ansible testing -m shell -a "echo $RANDOM" (double quotes), $RANDOM est évalué par le shell du Control Host avant envoi : toutes les cibles reçoivent donc la même valeur. Avec des simples quotes ('echo $RANDOM'), la variable est envoyée littéralement et évaluée par le Target Host, ce qui donne une valeur différente sur chaque hôte.

Le module package

Le module générique package est agnostique à la distribution : il délègue à apt, dnf, zypper… Utile pour un parc hétérogène à condition que le nom du paquet soit identique (ex. chrony), sinon il faut factoriser par famille d'OS (cf. Workshop 13).

Je retiens

  • -m spécifie le module, -a ses arguments. Sans -m, le module command est utilisé par défaut.
  • -o condense la sortie sur une seule ligne par hôte.
  • shell interprète les pipes et variables ; command est plus sûr pour les commandes simples.
  • Le module package est agnostique avec les distributions mais attention aux noms de paquets qui diffèrent.

Cheatsheet

Symptôme Cause probable Correction
ansible testing -a "ps -ef \| wc -l"wc: command not found ou résultat absurde Le module command (par défaut) n'interprète pas les pipes tout est passé comme argument brut Utiliser -m shell : ansible testing -m shell -a "ps -ef \| wc -l"
ansible testing -m shell -a "echo $RANDOM" → valeur identique sur toutes les cibles La variable est évaluée côté Control Host avant envoi Échapper la variable : ansible testing -m shell -a 'echo $RANDOM' (single quotes)
Sortie illisible : un bloc multi-lignes par hôte Format par défaut Ajouter -o (one-line) pour condenser : ansible testing -m command -a "hostname" -o
ansible testing -m package -a "name=foo state=present" échoue sur une distro Nom de paquet différent selon la famille (ex : apache2 vs httpd) Soit utiliser un nom commun, soit passer au when: ansible_os_family == ... (cf. Workshop 13)
ansible testing ...[WARNING]: No hosts matched Groupe testing absent de l'inventaire ou mauvais ansible.cfg chargé Vérifier ansible-inventory --list ; vérifier ansible --version pointe vers le bon ansible.cfg (cf. Workshop 03)

Sources (principales)


Précédent : Basic Setup Suite : Idempotence