Après avoir réorganisé l’ensemble de mes rôles Ansible, j’avais en tête de trouver un moyen de tester leur exécution dans un environnement vierge. L’idée n’est pas nouvelle. Le but : vérifier l’exécution du rôle plus facilement, c’est-à-dire, sans savoir à installer une nouvelle VM, ou à louer un serveur à cette occasion, même si cette dernière solution est, par expérience : pratique, assez rapide à mettre en œuvre et d’un faible coût en utilisant un serveur facturé à l’heure.
Ayant parcouru quelques dépôts de rôle Ansible présent sur Ansible Galaxy et ayant sauvegardé quelques articles évoquant le sujet, j’avais donc une idée des outils disponibles et des exemples fonctionnels. Il ne restait plus qu’à se retrousser les manches, et à tenter l’implémentation sur l’un de mes rôles les plus simples consistant à installer fail2ban.
Installation
Première étape avant configuration, l’installation des outils qui permettront de tester le rôle en exécutant une seule commande, à savoir : Molecule et virtualenv. Avec python3 installé, je commence donc par installer virtualenv
via: pip install virtualenv
. J’initialise ensuite un environnement virtuel python avec virtualenv dans le dossier contenant mon rôle ansible, soit les commandes :
$ pip3 install virtualenv $ virtualenv -p python3 .venv $ source .venv/bin/activate
Étape suivante, l’installation de molecule via pip.
$ pip3 install --upgrade setuptools $ pip3 install 'molecule[ansible,docker,lint]'
Configuration basique
Maintenant que les outils sont installés, je génère la configuration de base avec la commande: molecule init scenario
. Cette commande a pour effet de créer quatre fichiers.
INSTALL.rst
: contient des instructions pour l’installation d’autres dépendances, ou des étapes de configuration à réaliser. Dans mon cas, installation demolecule[docker]
, que j’ai donc directement intégré dans la commande citée précédemment.molecule.yml
: fichier principal décrivant les outils utilisés pour le test.converge.yml
: le playbook ansible chargé de déployer le rôle testé.verify.yml
: un fichier ansible permettant de décrire les vérifications à effectuer après déploiement du rôle.
Comme j’utilise docker pour la gestion de l’instance de test, je suis les préconisations de la documentation pour vérifier que docker fonctionne correctement.
$ docker run hello-world
Une fois l’environnement prêt, je peux passer à l’exécution du test.
$ molecule test
En théorie, ce premier test devrait au minimum réussir jusqu’à l’étape de vérification, en fonction des modifications effectuées dans verify.yml
. En cas d’erreur, je trouve très utile d’exécuter manuellement les différentes étapes de molecule test
. A savoir:
molecule create
: Création de l’instance.molecule converge
: Déploiement du rôle.molecule login
: Connexion à l’instance pour aller explorer son état, très pratique en cas d’erreur.molecule verify
: Exécuter les vérifications.molecule destroy
: Nettoyage.
Il convient de noter que, si le rôle ansible utilise service
pour vérifier l’état d’un service, la configuration par défaut présente dans le fichier converge.yml
n’est pas suffisante. J’ai été bloqué un bon moment avant de trouver des précisions à ce sujet au détour d’une issue sur Github. C’est pourquoi je vais maintenant décrire la configuration que j’ai mise en place.
Cas concret
La configuration que je décrite à la suite permet donc de tester un rôle relativement simple, que j’utilise pour installer fail2ban à partir de l’un des paquets deb du projet. Paquet distribué dans la partie release du projet GitHub. Commençons par le fichier molecule.yml.
--- dependency: name: galaxy driver: name: docker platforms: - name: instance image: geerlingguy/docker-debian10-ansible:latest command: ${MOLECULE_DOCKER_COMMAND:-""} volumes: - /sys/fs/cgroup:/sys/fs/cgroup:ro privileged: true pre_build_image: true provisioner: name: ansible playbooks: prepare: prepare.yml verifier: name: ansible
Cette configuration présente quelques adaptations par rapport à la configuration par défaut. En particulier, du côté de platforms
, où les instructions command
et volumes
sont nécessaires pour que l’instruction service
dans ansible soit fonctionnelle. Notons aussi l’ajout de prepare
dans provisioner
. Cet ajout a pour but d’effectuer quelques actions supplémentaires sur l’instance juste après son installation et avant de commencer le déploiement du rôle. Le contenu du fichier prepare.yml
est le suivant :
--- - name: Prepare hosts: all become: true tasks: - name: Install ssh apt: name: [ 'ssh' ] state: present update_cache: yes cache_valid_time: 3600 - name: restart ssh service: name: ssh state: restarted
Après quelques tentatives de tests et d’erreur au démarrage du service fail2ban, dernière étape de mon rôle, je constate que ssh ne semble pas installé par défaut dans l’image docker choisie. Problème, fail2ban sous debian active par défaut une jail pour ssh et se plaint donc de ne pas trouver les fichiers de logs pour ssh. Ces quelques lignes ont donc pour but d’installer ssh et de démarrer le service associé. On pourrait discuter du fait que ces vérifications devraient être portées par le rôle, mais cela ne me semble pas pertinent, étant donné que mon utilisation du rôle se fait toujours dans le cas d’une installation sur une machine à laquelle j’accède via ssh. Le service est donc toujours présent dans ma situation.
Vient ensuite le fichier converge.yml
. Pas de modification de ce côté là.
--- - name: Converge hosts: all become: true tasks: - name: "Include role-install-fail2ban" include_role: name: "role-install-fail2ban"
Enfin verify.yml
dernier fichier de configuration. Pour un premier test, j’ai fait au plus simple et je me contente de vérifier que fail2ban fait bien partie des paquets installés sur le système.
---
- name: Verify
hosts: all
tasks:
- name: Gather package facts
package_facts:
manager: auto
- name: Verify Packages
assert:
that: "'{{ item }}' in ansible_facts.packages"
with_items:
- fail2ban
Voilà pour la configuration du test de mon rôle d’installation de fail2ban.
Conclusion
Après une première soirée passée sur le sujet du test d’un rôle ansible, je suis plutôt satisfait du résultat. Bien que le rôle soit l’un de mes rôles les plus simples, cela ne devrait pas être trop compliqué de généraliser cette méthode à l’ensemble de mes rôles, mais cela nécessitera sans aucun doute de nombreuses heures de développement. Comme souvent, c’est un processus itératif qui sera effectué progressivement sur les prochains mois. La simplicité de réaliser un test sur un système vierge est vraiment appréciable et permettra de vérifier qu’un rôle modifié fonctionne toujours, et cela, sans avoir à passer par le déploiement d’un serveur vierge. Prochaines étapes : étudier l’intégration avec le système d’actions GitHub et tester le playbook permettant le déploiement automatique d’Unicoda.