Ansible -Contrôler vos playbooks avec Ansible-Lint
Publié le : 4 octobre 2021 | Mis à jour le : 11 décembre 2022Lorsqu’on écrit des playbooks et des rôles Ansible, comme pour tous les langages de programmation, il y a un certain nombre de bonnes pratiques et de règles à respecter pour obtenir un code de qualité. A moins de faire toujours la même chose, il est difficile de connaître toutes ces règles. C’est là qu’intervient les outils de linting. Ansible-Lint va vous permettre de contrôler le respect de toutes ces règles et d’éviter les pièges courants sur vos playbooks, vos rôles et même les collections. Ansible-lint va également vous aider à mettre à niveau votre code pour qu’il continue de fonctionner lors des sorties des nouvelles versions d’Ansible.
Le projet Ansible Galaxy utilise Ansible-Lint pour calculer les scores de qualité des codes déposés dans le Galaxy Hub.
Installation d’Ansible Lint
Comme Ansible, l’outil ansible-lint est écrit en python, et donc son installation se fait via pip.
On va l’installer avec yamllint.
pip3 install "ansible-lint[yamllint]"
Dans le cas où vous utilisez encore d’anciennes versions d’Ansible, il est possible de choisir une version du linter compatible avec celle-ci.
pip3 install ansible-lint "ansible>=2.9,<2.10"
Que contrôle ansible lint?
Par défaut cet outil permet de contrôler en autre :
- l’utilisation
command
oushell
plutôt qu’un module existant prenant en charge cette commande - l’utilisation
command
plutôt queshell
(si le module équivalent n’existe pas) - le bon respect des espaces dans les noms de variables : {{ my_variable }} et non {{my_variable}}
- la présence de
local_action
qui doit être remplacé pardelegate_to: localhost
- l’utilisation de modules dépréciés
- les tests de chaînes de caractères de longueur nulle: when:
var|length > 0
- l’utilisation du nom complet pour les modules
ansible.builtin
(depuis la version 3.0 d’ansible) - l’utilisation de
failed_when
avec ses conditions d’erreurs plutôt queignore_errors
- …
La liste complète avec leurs explications
Pour afficher toutes les règles utilisées par défaut il suffit de taper la commande suivante :
ansible-lint -v -T
command-shell: # Specific to use of command and shell modules
- command-instead-of-module
- command-instead-of-shell
- deprecated-command-syntax
- inline-env-var
- no-changed-when
- risky-shell-pipe
Pour limiter les tests sur certaines règles, il suffit d’utiliser l’option -p
.
Par exemple pour lancer un contrôle sur juste l’idempotence :
ansible-lint -t idempotency playbook.yml
De la même manière pour exclure certaines règles :
ansible-lint -x formatting,metadata playbook.yml
On peut plutôt que de les ignorer les afficher en warning:
ansible-lint -w experimental playbook.yml
Ansible-Lint par la pratique
Prenons ce playbook par exemple :
---
- hosts: all
gather_facts: no
tasks:
- name: this would typically fire deprecated-command-syntax
command: warn=no chmod 644 X
- name: this would typically fire command-instead-of-module
command: git pull --rebase
- name: this would typically fire git-latest
git: src=https://blog.stephane-robert.info/path/to/git/repo dest=checkout
qui retourne :
ansible-lint test.yml
yaml: truthy value should be one of [false, true] (truthy)
test.yml:3
no-changed-when: Commands should not change things if nothing needs doing
test.yml:6 Task/Handler: this would typically fire deprecated-command-syntax
command-instead-of-module: git used in place of git module
test.yml:9 Task/Handler: this would typically fire command-instead-of-module
no-changed-when: Commands should not change things if nothing needs doing
test.yml:9 Task/Handler: this would typically fire command-instead-of-module
git-latest: Git checkouts must contain explicit version
test.yml:12 Task/Handler: this would typically fire git-latest
Que faut-il faire pour qu’ansible-lint ne retourne pas d’erreurs ?
- A la ligne 3 remplacer
no
parfalse
- A la ligne 6 on doit ajouter
changed_when
pour indiquer à Ansible quand la commande utilisée va réellement changer quelque chose sur votre machine cible. - A la ligne 9 git possède son propre module !!!
- Pour que l’on respecte les règles d’idempotence, il est important de ne pas utiliser default mais de nommer une version explicite.
Si on souhaite forcer certaines règles il est possible d’ajouter des arguments au playbook :
- Convertir un fail en warn en ajoutant l’argument
warn
mais juste pour les appels aux modulescommand
etshell
:
- name: this would typically fire git-latest
git: src=https://blog.stephane-robert.info/path/to/git/repo dest=checkout
args:
warn_list: false
- Pour les autres modules on peut skipper le test en ajoutant le tag
skip_ansible_lint
:
- name: this would typically fire git-latest
git: src=https://blog.stephane-robert.info/path/to/git/repo dest=checkout
tags:
- skip_ansible_lint
On peut, comme l’indique la commande, créer un fichier .ansible-lint
contenant
par exemple :
# .ansible-lint
warn_list: # or 'skip_list' to silence them completely
- yaml # Violations reported by yamllint
Mais je n’aime pas trop cela, car dans ce cas ce sont toutes les erreurs de ce type qui sont ignorées.
Écrire ses propres règles Ansible-Lint
Il est possible de créer ses propres règles et de les utiliser avec l’option -r /path/to/custom-rules
.
Pour la syntaxe des règles il suffit de se rendre sur cette page : custom-rules
Si on veut les utiliser conjointement avec les règles par défaut on remplace
-w
par -W
La suite
Il ne vous reste plus qu’à l’intégrer à votre ci !!
Si vous voulez plus de tutorials Ansible je vous renvoie sur le billet de l'introduction à ansible
Une alternative ansible-later