Aller au contenu

Sécuriser vos codes Ansible avec assert et validate_argument_spec

Mise à jour :

logo

Lors de l’automatisation des tâches avec Ansible, il est essentiel de garantir que les conditions requises sont respectées avant d’exécuter certaines actions. C’est là qu’interviennent les modules de validation, comme ansible.builtin.assert et ansible.builtin.validate_argument_spec. Ces outils permettent de vérifier que les prérequis ou les arguments fournis respectent certaines règles, améliorant ainsi la fiabilité des playbooks.

Le module ansible.builtin.assert est particulièrement utile pour s’assurer que certaines conditions dynamiques sont vraies avant d’exécuter une tâche. Par exemple, vous pouvez l’utiliser pour vérifier qu’il reste suffisamment d’espace disque avant de déployer une application. En parallèle, le module ansible.builtin.validate_argument_spec permet de valider en amont les arguments passés à un rôle ou une tâche, garantissant qu’ils respectent les bonnes valeurs ou types.

Dans ce guide, je vais vous expliquer comment utiliser efficacement ces deux modules pour renforcer vos playbooks Ansible et éviter les erreurs potentielles.

Présentation du module ansible.builtin.assert

Le module ansible.builtin.assert est un outil puissant dans Ansible qui permet de valider des conditions spécifiques pendant l’exécution d’un playbook. Il est principalement utilisé pour vérifier que certaines contraintes ou exigences sont respectées avant de poursuivre le déroulement d’une tâche. Par exemple, il peut vérifier qu’une variable possède une valeur définie, qu’un fichier existe, ou encore que l’espace disque disponible est suffisant pour continuer une installation. Si la condition échoue, l’exécution du playbook est stoppée et un message d’erreur personnalisé peut être affiché pour signaler la raison de l’échec.

Le module ansible.builtin.assert est souvent utilisé pour prévenir des erreurs inattendues, comme un manque de ressources, ou des prérequis manquants qui, sans cela, pourraient passer inaperçus jusqu’à une étape critique du déploiement. Ce module fonctionne en évaluant des conditions logiques et si celles-ci ne sont pas respectées, il lève une erreur. Cela permet de s’assurer que seules les actions valides sont exécutées, améliorant ainsi la robustesse des playbooks.

Les différentes options du module ansible.builtin.assert

Le module ansible.builtin.assert offre plusieurs options qui permettent de personnaliser les vérifications et de gérer les erreurs de manière flexible. En comprenant les différentes options disponibles, je peux adapter ce module à de nombreux scénarios dans mes playbooks, qu’il s’agisse de valider des ressources, de contrôler des paramètres système ou de vérifier la disponibilité de certains services avant de poursuivre des tâches critiques.

Les options principales de ce module sont : that, fail_msg, success_msg et quiet. Chacune a un rôle spécifique dans la définition des conditions à valider et dans la gestion des messages affichés en cas d’échec ou de succès. Dans cette section, je vais détailler ces options, avec des exemples concrets pour illustrer leur usage.

Option that

L’option that est l’élément central du module ansible.builtin.assert. Elle contient la ou les conditions à vérifier. Ces conditions sont exprimées sous forme de liste et chaque élément de la liste doit être une expression évaluée à True pour que la tâche réussisse. Si l’une des expressions est False, la tâche échoue et l’exécution du playbook s’arrête.

Voici un exemple simple où nous vérifions que la version de Python est supérieure ou égale à 3.6 sur un hôte :

- name: Vérification de la version de Python
ansible.builtin.assert:
that:
- ansible_facts['python']['version']['major'] == 3
- ansible_facts['python']['version']['minor'] >= 6

Dans cet exemple, that contient deux expressions. La première vérifie que la version majeure de Python est 3 et la seconde s’assure que la version mineure est au moins 6. Si les deux conditions sont vraies, la tâche passe avec succès.

Option fail_msg

L’option fail_msg permet de spécifier un message personnalisé à afficher si l’une des conditions définies dans that échoue. Cela améliore la compréhension des erreurs, surtout lorsqu’il s’agit de playbooks complexes. Sans cette option, Ansible renverra un message d’erreur générique, qui peut ne pas fournir suffisamment d’informations pour comprendre l’origine du problème.

Voici un exemple où un message personnalisé est affiché si l’espace disque libre est insuffisant :

- name: Vérification de l'espace disque disponible
ansible.builtin.assert:
that:
- ansible_facts['disk']['/']['free'] > 500000000
fail_msg: "Espace disque insuffisant. Veuillez libérer au moins 500 Mo."

Si la condition échoue, le message “Espace disque insuffisant. Veuillez libérer au moins 500 Mo.” sera affiché. Cela permet à l’administrateur de comprendre immédiatement la nature du problème et de prendre des mesures correctives.

Option success_msg

L’option success_msg permet de définir un message personnalisé qui sera affiché lorsque toutes les conditions dans that sont validées. Par défaut, Ansible ne produit pas de message particulier en cas de succès, mais dans certains cas, il peut être utile de recevoir une confirmation visuelle lorsque des conditions critiques sont respectées.

Voici un exemple où un message de confirmation est affiché en cas de succès de la vérification de l’utilisateur et de l’espace disque :

- name: Vérification de l'utilisateur et de l'espace disque
ansible.builtin.assert:
that:
- ansible_facts['users']['outscale'] is defined
- ansible_facts['disk']['/']['free'] > 1000000000
success_msg: "L'utilisateur 'outscale' existe et l'espace disque est suffisant."

Si toutes les conditions sont validées, le message “L’utilisateur ‘admin’ existe et l’espace disque est suffisant.” sera affiché, donnant une confirmation explicite que tout est en ordre pour continuer.

Option quiet

L’option quiet, lorsqu’elle est définie à True, supprime les messages en cas de succès. Cela peut être utile lorsque vous exécutez des vérifications fréquentes dans un playbook, mais que vous ne souhaitez pas être submergé par des messages de confirmation pour chaque validation réussie. Par défaut, quiet est réglée sur False, ce qui signifie que les messages sont affichés à chaque exécution réussie ou échouée.

Voici un exemple où l’option quiet est activée pour supprimer les messages en cas de succès :

- name: Vérification de l'état de l'interface réseau
ansible.builtin.assert:
that:
- ansible_facts['network']['interfaces']['eth0']['active'] == True
fail_msg: "L'interface réseau 'eth0' n'est pas active."
quiet: True

Dans ce cas, si l’interface réseau eth0 est active, aucun message ne sera affiché. Cependant, si l’interface n’est pas active, le message d’erreur “L’interface réseau ‘eth0’ n’est pas active.” sera affiché.

Pourquoi utiliser ansible.builtin.assert ?

Un des avantages indirects de l’utilisation de ansible.builtin.assert est qu’il permet de documenter de manière explicite dans le playbook les conditions préalables nécessaires à l’exécution d’une tâche. Cela améliore la lisibilité et la maintenabilité du code, car les conditions critiques sont clairement définies.

Le module ansible.builtin.validate_argument_spec

Le module ansible.builtin.validate_argument_spec joue un rôle essentiel dans la validation des arguments passés aux rôles et aux tâches dans Ansible. Contrairement au module assert qui vérifie les conditions d’exécution, ce module intervient en amont, avant même que le playbook ne soit exécuté, pour s’assurer que les arguments fournis respectent des critères bien définis. Cela permet de détecter rapidement les erreurs de syntaxe ou de type dans les paramètres et d’éviter que des erreurs plus profondes ne surviennent plus tard dans l’exécution.

La validation des arguments est une étape importante, notamment dans les environnements complexes ou collaboratifs où plusieurs administrateurs peuvent être amenés à travailler sur les mêmes playbooks ou rôles. En définissant des spécifications claires pour les arguments acceptés, validate_argument_spec permet de garantir que les valeurs attendues sont correctement renseignées, réduisant ainsi les risques d’erreurs et facilitant la détection des incohérences.

Utiliser validate_argument_spec permet de créer des rôles et des tâches plus robustes, tout en facilitant leur réutilisation. Voici quelques cas d’usage dans lesquels ce module peut s’avérer particulièrement utile :

  1. Validation des types : Ce module permet de s’assurer que les arguments fournis sont du bon type (entier, chaîne, booléen, etc.). Si un type incorrect est fourni, la tâche échouera avant même d’être exécutée.

  2. Contrôle des valeurs : Vous pouvez spécifier des listes d’options acceptables pour certains paramètres (par exemple, pour un argument port, vous pouvez limiter les choix à 80 ou 443).

  3. Garantir la présence d’arguments requis : Certaines tâches ou certains rôles nécessitent des arguments spécifiques. Avec validate_argument_spec, vous pouvez vous assurer que ces arguments obligatoires sont fournis, sans quoi l’exécution échoue.

  4. Définir des valeurs par défaut : Lorsque certains arguments ne sont pas fournis, il est possible de définir des valeurs par défaut, garantissant ainsi un comportement prévisible.

Exemple d’utilisation simple

Voici un exemple basique où je définis un rôle qui accepte un argument port et un argument optionnel debug_mode. Je veux m’assurer que le port soit soit 80, soit 443 et que debug_mode soit un booléen avec une valeur par défaut de false :

- name: Vérifier que les variables requises pour cette tâche sont présentes
ansible.builtin.validate_argument_spec:
spec: "{{ required_data }}"
vars:
required_data:
stuff:
description: "Un élément requis"
type: str
choices: ['who', 'knows', 'what']
default: what
but:
description: "Cet élément est obligatoire"
type: str
required: true

Cet exemple utilise le module ansible.builtin.validate_argument_spec pour vérifier que certaines variables sont correctement définies avant d’exécuter une tâche Ansible. Le but est de valider les types et valeurs des variables nécessaires à l’exécution de la tâche, en s’assurant qu’elles respectent des critères prédéfinis. Analysons en détail :

Explications sur les pramaètres

  1. L’option spec : La clé spec attend un dictionnaire qui décrit les variables à valider. Ici, le contenu de la variable required_data est passé à spec grâce à l’expression {{ required_data }}.

  2. La variable required_data : Le dictionnaire required_data contient les définitions des variables à valider. Dans cet exemple, deux variables sont définies :

    • stuff :

      • description : Un commentaire décrivant cette variable comme “Un élément requis”.
      • type : Doit être une chaîne de caractères (str).
      • choices : Les valeurs possibles pour cette variable sont limitées à 'who', 'knows' et 'what'.
      • default : Si aucune valeur n’est spécifiée pour stuff, la valeur par défaut sera 'what'.
    • but :

      • description : “Cet élément est obligatoire”.
      • type : Doit être une chaîne de caractères (str).
      • required : Cette variable est obligatoire, donc si elle n’est pas fournie, l’exécution de la tâche échouera.

Explication de la tâche

  1. La tâche valide que les variables stuff et but existent et respectent les critères spécifiés dans le dictionnaire required_data.
  2. stuff doit être une chaîne et doit prendre l’une des trois valeurs autorisées : 'who', 'knows', ou 'what'. Si cette variable n’est pas définie, la valeur 'what' sera utilisée par défaut.
  3. but est obligatoire et elle doit être une chaîne de caractères. Si cette variable n’est pas fournie, la tâche échouera.

Conclusion

La validation des arguments dans Ansible, à travers le module ansible.builtin.assert et surtout ansible.builtin.validate_argument_spec, permet de renforcer la robustesse et la fiabilité des playbooks et des rôles. En s’assurant que les variables et arguments fournis respectent des critères définis avant même l’exécution d’une tâche, ces modules permettent d’éviter des erreurs coûteuses qui pourraient survenir plus tard dans le déploiement.

En combinant ces deux modules, on obtient un contrôle plus fin et plus strict de l’exécution des tâches dans Ansible. Cela permet de renforcer la sécurité et la stabilité des opérations automatisées tout en réduisant considérablement les risques d’échecs imprévus. Utiliser assert et validate_argument_spec de manière proactive dans vos playbooks permet de s’assurer que seules les bonnes actions sont entreprises, avec les bonnes valeurs, dans les bonnes conditions.