Utilisation correct des modules Ansible raw, command et shell
Mise à jour :
Pour garantir des opérations stables et fiables, Ansible repose sur un principe fondamental : l’idempotence. Cela signifie qu’une tâche exécutée plusieurs fois doit produire le même résultat, sans modifier l’état du système si celui-ci est déjà conforme.
L’outil
Ansible
propose une large palette de modules dédiés pour gérer les paquets,
configurer des services, manipuler des fichiers, … Ces modules, comme
apt
pour installer des logiciels sur un système basé sur Debian ou
copy
pour transférer des fichiers, sont conçus pour assurer l’idempotence. Cela
signifie que si vous demandez d’installer un paquet déjà présent sur un serveur,
Ansible ne tentera pas de le réinstaller, évitant ainsi des changements
superflus ou des comportements indésirables.
Cependant, il arrive que vous deviez exécuter des commandes personnalisées
sur un hôte distant, notamment dans des cas spécifiques où aucun module Ansible
dédié n’existe. C’est là qu’interviennent les modules raw
, command
,
et shell
, qui permettent d’exécuter des commandes directement sur les
systèmes cibles. Bien qu’efficaces, ces modules ne garantissent pas
l’idempotence. Ils exécutent simplement la commande demandée, peu importe
l’état initial du système. De ce fait, ils doivent être utilisés avec
précaution et en dernier recours.
Dans ce guide, je vais détailler l’utilisation des modules raw
,
command
et shell
, en expliquant leurs différences, leurs cas
d’usage et leurs limites. Vous comprendrez dans quels scénarios ils sont
nécessaires et comment les utiliser efficacement pour éviter les mauvaises
pratiques dans vos codes Ansible.
Le module raw
: L’exécution brute sans interprétation Python
Le module raw
est le plus basique et le plus direct des trois modules que
nous allons explorer. Contrairement aux modules command
et shell
,
qui font appel à des interpréteurs , le module raw
exécute des commandes
brutes sur l’hôte cible. Il envoie directement la commande via SSH, sans
aucune transformation ou interprétation par Ansible. C’est donc le module de
dernier recours, souvent utilisé lorsque l’infrastructure ne dispose pas encore
des prérequis nécessaires au bon fonctionnement des autres modules, notamment
Python.
Par exemple, si vous administrez un routeur ou un système embarqué où
Python n’est pas disponible et que vous souhaitez exécuter une commande basique,
le module raw
vous permet d’envoyer directement cette commande sans vous
soucier de l’installation de dépendances.
Malgré sa flexibilité, le module raw
présente plusieurs inconvénients
importants qui limitent son utilisation à des scénarios très spécifiques :
-
Absence de structuration des résultats : Contrairement aux autres modules Ansible, qui renvoient des résultats sous forme de dictionnaires structurés, le module
raw
renvoie simplement la sortie brute de la commande exécutée. Cela peut rendre l’analyse des résultats plus complexe, surtout si vous devez gérer les erreurs ou interpréter des données complexes. -
Sécurité limitée : Le module
raw
exécute des commandes directement sur le système sans passer par le shell, ce qui peut comporter des risques. Il n’y a pas de contrôle spécifique sur la commande envoyée, ni de protection contre des attaques d’injection de commandes. Il est donc primordial de bien valider les commandes exécutées pour éviter tout comportement imprévu ou dangereux.
Le module command
: Exécution simple sans shell
Le module command
est l’un des modules les plus simples d’Ansible. Il
permet d’exécuter des commandes basiques directement sur un hôte distant,
mais sans utiliser de shell. Contrairement au module shell
, qui exécute
des commandes via un interpréteur de shell (comme Bash), command
ne prend
pas en charge des fonctionnalités avancées comme les redirections (>
), les
pipes (|
), ou les chaînes de commandes multiples (&&
). Cette simplicité en
fait un module plus sûr, car il évite les risques associés à l’exécution de
commandes complexes via un shell.
Le module command
est particulièrement adapté pour les tâches qui
nécessitent l’exécution de commandes simples et non interactives. Par
exemple, il peut être utilisé pour exécuter des scripts. Comme il n’utilise pas
de shell, il est à privilégier lorsque vous avez besoin d’exécuter une commande
sans manipulation avancée et que la sécurité est une préoccupation, car il ne
permet pas l’exécution de scripts complexes ni l’utilisation de caractères
spéciaux pouvant représenter un risque d’injection.
Limites du module command
Bien que le module command
soit simple et sûr, il présente également
certaines limitations :
- Pas de gestion des redirections et pipes : Comme mentionné précédemment,
command
ne permet pas l’utilisation de redirections (>
,>>
), de pipes (|
), ou de chaînes de commandes (&&
). Si vous avez besoin de combiner plusieurs commandes ou de rediriger les sorties vers un fichier, vous devrez utiliser le moduleshell
.
Le module shell
: Exécution de commandes via un shell
Le module shell
d’Ansible est le plus flexible des trois modules que nous
explorons. Contrairement à command
, qui se limite à l’exécution de
commandes simples sans shell, shell
permet d’exécuter des commandes via
l’interpréteur de commandes natif de l’hôte distant (comme Bash ou sh).
Cela signifie que vous pouvez utiliser des fonctionnalités avancées du shell,
telles que les redirections de sortie, les pipes et la chaîne de
commandes avec des opérateurs logiques comme &&
ou ||
.
Le module shell
est particulièrement adapté aux situations où vous devez
exécuter des commandes complexes nécessitant un shell pour interpréter des
symboles spécifiques comme les pipes (|
), les redirections (>
, >>
), ou
pour exécuter plusieurs commandes en séquence avec des opérateurs comme &&
(si
la première commande réussit, la seconde est exécutée). Cela le rend très utile
pour des scripts complexes ou des commandes qui manipulent plusieurs flux de
données ou fichiers simultanément.
Limites du module shell
Malgré sa puissance, le module shell
comporte des risques et des
limitations qu’il est important de bien comprendre avant de l’utiliser dans
vos playbooks Ansible.
-
Risques de sécurité : En utilisant le module
shell
, vous ouvrez la porte à des risques de sécurité supplémentaires, notamment les injections de commandes. Comme le shell interprète directement les commandes que vous envoyez, des variables ou des entrées non contrôlées peuvent mener à des exécutions inattendues ou dangereuses. Il est donc indispensable de bien valider et de limiter les commandes passées viashell
. -
Performance : L’utilisation du shell pour chaque commande peut entraîner une légère perte de performance, car le système doit lancer une nouvelle instance de shell à chaque exécution. Dans des environnements à grande échelle, cette surcharge peut s’accumuler, surtout si le module est utilisé de manière répétée.
Gérer l’idempotence avec creates
et removes
Pour pallier l’absence d’idempotence, les modules command
permet de
spécifier des conditions sous forme de fichiers ou de répertoires existants avec
les options creates
et removes
. Par exemple, vous pouvez utiliser l’option
creates
pour indiquer qu’une commande ne doit être exécutée que si un certain
fichier n’existe pas encore.
Exemple avec creates
:
Dans cet exemple, la commande tar
sera exécutée uniquement si le fichier
/path/to/extracted/file
n’existe pas encore. Cela permet de rendre la tâche
plus idempotente, en évitant d’extraire l’archive plusieurs fois.
De même, l’option removes
peut être utilisée pour indiquer qu’une commande
doit être exécutée seulement si un fichier ou un répertoire spécifique est
présent et qu’il doit être supprimé après l’exécution de la commande.
Exemple avec removes
:
Dans cet exemple, Ansible exécutera la commande rm
pour supprimer le fichier
/tmp/tempfile
uniquement si ce fichier existe, ce qui ajoute une condition
simple mais efficace à l’exécution de la tâche.
Gestion des status changed
et failed
Un point important, les modules shell
et command
s’il ne plante pas retourne
toujours le status changed. Pour définir réellement quand une commande échoue ou
change quelque chose sur le système, vous devez utiliser les instructions
changed_when
et failed_when
.
Exemple de gestion des erreurs avec register
et failed_when
:
Dans cet exemple, la commande cat
est utilisée pour lire le fichier de
logs système et le résultat est capturé dans la variable result
. Si la
commande échoue (par exemple, si le fichier n’existe pas), Ansible affiche le
message d’erreur renvoyé par la commande via result.stderr
.
Conclusion
Dans ce guide, nous avons exploré en détail les modules Ansible raw
,
command
et shell
, en mettant en lumière leurs cas d’utilisation,
leurs avantages, ainsi que leurs limites. Ces modules permettent d’exécuter des
commandes sur des hôtes distants, mais ils ne garantissent pas
l’idempotence, une propriété clé pour maintenir la stabilité et la
répétabilité des actions dans un environnement automatisé.
Le module raw
est à utiliser en dernier recours, principalement sur des
systèmes dépourvus de Python. Le module command
est idéal pour des tâches
simples et sûres, mais sans la flexibilité des commandes shell. Enfin, le module
shell
offre une grande liberté, avec la possibilité de manipuler des flux
complexes et de chaîner des commandes, mais il introduit des risques accrus en
termes de sécurité et d’absence d’idempotence.
En maîtrisant l’utilisation de raw
, command
et shell
, vous
pourrez gérer des tâches spécifiques et complexes dans vos playbooks Ansible,
tout en veillant à maintenir un environnement sécurisé et stable.