{"id":4520,"date":"2021-05-12T14:00:00","date_gmt":"2021-05-12T12:00:00","guid":{"rendered":"https:\/\/www.unicoda.com\/?p=4520"},"modified":"2021-04-20T23:10:20","modified_gmt":"2021-04-20T21:10:20","slug":"test-dun-role-ansible","status":"publish","type":"post","link":"https:\/\/www.unicoda.com\/?p=4520","title":{"rendered":"Test d&rsquo;un role Ansible"},"content":{"rendered":"\n<p>Apr\u00e8s avoir r\u00e9organis\u00e9 l&rsquo;ensemble de mes r\u00f4les Ansible, j&rsquo;avais en t\u00eate de trouver un moyen de tester leur ex\u00e9cution dans un environnement vierge. L&rsquo;id\u00e9e n&rsquo;est pas nouvelle.  Le but : v\u00e9rifier l&rsquo;ex\u00e9cution du r\u00f4le plus facilement, c&rsquo;est-\u00e0-dire, sans savoir \u00e0 installer une nouvelle VM, ou \u00e0 louer un serveur \u00e0 cette occasion, m\u00eame si cette derni\u00e8re solution est, par exp\u00e9rience : pratique, assez rapide \u00e0 mettre en \u0153uvre et d&rsquo;un faible co\u00fbt en utilisant un serveur factur\u00e9 \u00e0 l&rsquo;heure.<\/p>\n\n\n\n<p>Ayant parcouru quelques d\u00e9p\u00f4ts de r\u00f4le Ansible pr\u00e9sent sur Ansible Galaxy et ayant sauvegard\u00e9 quelques articles \u00e9voquant le sujet, j&rsquo;avais donc une id\u00e9e des outils disponibles et des exemples fonctionnels. Il ne restait plus qu&rsquo;\u00e0 se retrousser les manches, et \u00e0 tenter l&rsquo;impl\u00e9mentation sur l&rsquo;un de mes r\u00f4les les plus simples consistant \u00e0 installer fail2ban.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">Installation<\/h4>\n\n\n\n<p>Premi\u00e8re \u00e9tape avant configuration, l&rsquo;installation des outils qui permettront de tester le r\u00f4le en ex\u00e9cutant une seule commande, \u00e0 savoir : <a rel=\"noreferrer noopener\" href=\"https:\/\/molecule.readthedocs.io\/en\/latest\/installation.html\" target=\"_blank\">Molecule<\/a> et <a rel=\"noreferrer noopener\" href=\"https:\/\/virtualenv.pypa.io\/en\/latest\/installation.html\" target=\"_blank\">virtualenv<\/a>. Avec python3 install\u00e9, je commence donc par installer <code>virtualenv<\/code> via: <code>pip install virtualenv<\/code>. J&rsquo;initialise ensuite un environnement virtuel python avec virtualenv dans le dossier contenant mon r\u00f4le ansible, soit les commandes :<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">$ pip3 install virtualenv\n$ virtualenv -p python3 .venv\n$ source .venv\/bin\/activate<\/pre>\n\n\n\n<p>\u00c9tape suivante, l&rsquo;installation de molecule via pip.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">$ pip3 install --upgrade setuptools\n$ pip3 install 'molecule[ansible,docker,lint]'<\/pre>\n\n\n\n<h4 class=\"wp-block-heading\">Configuration basique<\/h4>\n\n\n\n<p>Maintenant que les outils sont install\u00e9s, je g\u00e9n\u00e8re la <a rel=\"noreferrer noopener\" href=\"https:\/\/molecule.readthedocs.io\/en\/latest\/getting-started.html#creating-a-new-role\" target=\"_blank\">configuration de base<\/a> avec la commande: <code>molecule init scenario<\/code>. Cette commande a pour effet de cr\u00e9er quatre fichiers.<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li><code>INSTALL.rst<\/code> : contient des instructions pour l&rsquo;installation d&rsquo;autres d\u00e9pendances, ou des \u00e9tapes de configuration \u00e0 r\u00e9aliser. Dans mon cas, installation de <code>molecule[docker]<\/code>, que j&rsquo;ai donc directement int\u00e9gr\u00e9 dans la commande cit\u00e9e pr\u00e9c\u00e9demment.<\/li><li><code>molecule.yml<\/code> : fichier principal d\u00e9crivant les outils utilis\u00e9s pour le test. <\/li><li><code>converge.yml<\/code> : le playbook ansible charg\u00e9 de d\u00e9ployer le r\u00f4le test\u00e9.<\/li><li><code>verify.yml<\/code> : un fichier ansible permettant de d\u00e9crire les v\u00e9rifications \u00e0 effectuer apr\u00e8s d\u00e9ploiement du r\u00f4le.<\/li><\/ul>\n\n\n\n<p>Comme j&rsquo;utilise docker pour la gestion de l&rsquo;instance de test, je suis les pr\u00e9conisations de la documentation pour v\u00e9rifier que docker fonctionne correctement.<\/p>\n\n\n\n<pre id=\"block-4beadcc6-ef4a-49c2-bd66-95c258caebc1\" class=\"wp-block-preformatted\">$ docker run hello-world<\/pre>\n\n\n\n<p>Une fois l&rsquo;environnement pr\u00eat, je peux passer \u00e0 l&rsquo;ex\u00e9cution du test.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">$ molecule test<\/pre>\n\n\n\n<p>En th\u00e9orie, ce premier test devrait au minimum r\u00e9ussir jusqu&rsquo;\u00e0 l&rsquo;\u00e9tape de v\u00e9rification, en fonction des modifications effectu\u00e9es dans <code>verify.yml<\/code>. En cas d&rsquo;erreur, je trouve tr\u00e8s utile d&rsquo;ex\u00e9cuter manuellement les diff\u00e9rentes \u00e9tapes de <code>molecule test<\/code>. A savoir:<\/p>\n\n\n\n<ol class=\"wp-block-list\"><li><code>molecule create<\/code> : Cr\u00e9ation de l&rsquo;instance.<\/li><li><code>molecule converge<\/code>: D\u00e9ploiement du r\u00f4le.<\/li><li><code>molecule login<\/code> : Connexion \u00e0 l&rsquo;instance pour aller explorer son \u00e9tat, tr\u00e8s pratique en cas d&rsquo;erreur.<\/li><li><code>molecule verify<\/code> : Ex\u00e9cuter les v\u00e9rifications.<\/li><li><code>molecule destroy<\/code> : Nettoyage.<\/li><\/ol>\n\n\n\n<p>Il convient de noter que, si le r\u00f4le ansible utilise <code>service<\/code> pour v\u00e9rifier l&rsquo;\u00e9tat d&rsquo;un service, la configuration par d\u00e9faut pr\u00e9sente dans le fichier <code>converge.yml<\/code> n&rsquo;est pas suffisante. J&rsquo;ai \u00e9t\u00e9 bloqu\u00e9 un bon moment avant de trouver des pr\u00e9cisions \u00e0 ce sujet au d\u00e9tour d&rsquo;une issue sur Github. C&rsquo;est pourquoi je vais maintenant d\u00e9crire la configuration que j&rsquo;ai mise en place.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">Cas concret<\/h4>\n\n\n\n<p>La configuration que je d\u00e9crite \u00e0 la suite permet donc de tester un r\u00f4le relativement simple, que j&rsquo;utilise pour installer fail2ban \u00e0 partir de l&rsquo;un des paquets deb du projet. Paquet distribu\u00e9 dans la partie release du projet GitHub. Commen\u00e7ons par le fichier <code>molecule.yml.<\/code><\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">---\ndependency:\n  name: galaxy\ndriver:\n  name: docker<em>\n<\/em>platforms:\n  - name: instance\n    image: geerlingguy\/docker-debian10-ansible:latest\n    command: ${MOLECULE_DOCKER_COMMAND:-\"\"}\n    volumes:\n      - \/sys\/fs\/cgroup:\/sys\/fs\/cgroup:ro\n    privileged: true\n    pre_build_image: true\nprovisioner:\n  name: ansible\n  playbooks:\n    prepare: prepare.yml\nverifier:\n  name: ansible<\/pre>\n\n\n\n<p>Cette configuration pr\u00e9sente quelques adaptations par rapport \u00e0 la configuration par d\u00e9faut. En particulier, du c\u00f4t\u00e9 de <code>platforms<\/code>, o\u00f9 les instructions <code>command<\/code> et <code>volumes<\/code> sont n\u00e9cessaires pour que l&rsquo;instruction <code>service<\/code> dans ansible soit fonctionnelle. Notons aussi l&rsquo;ajout de <code>prepare<\/code> dans <code>provisioner<\/code>. Cet ajout a pour but d&rsquo;effectuer quelques actions suppl\u00e9mentaires sur l&rsquo;instance juste apr\u00e8s son installation et avant de commencer le d\u00e9ploiement du r\u00f4le. Le contenu du fichier <code>prepare.yml<\/code> est le suivant :<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">---\n- name: Prepare\n  hosts: all\n  become: true\n  tasks:\n    - name: Install ssh\n      apt:\n        name: [ 'ssh' ]\n        state: present\n        update_cache: yes\n        cache_valid_time: 3600\n    - name: restart ssh\n      service:\n        name: ssh\n        state: restarted<\/pre>\n\n\n\n<p>Apr\u00e8s quelques tentatives de tests et d&rsquo;erreur au d\u00e9marrage du service fail2ban, derni\u00e8re \u00e9tape de mon r\u00f4le, je constate que ssh ne semble pas install\u00e9 par d\u00e9faut dans l&rsquo;image docker choisie. Probl\u00e8me, fail2ban sous debian active par d\u00e9faut 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&rsquo;installer ssh et de d\u00e9marrer le service associ\u00e9. On pourrait discuter du fait que ces v\u00e9rifications devraient \u00eatre port\u00e9es par le r\u00f4le, mais cela ne me semble pas pertinent, \u00e9tant donn\u00e9 que mon utilisation du r\u00f4le se fait toujours dans le cas d&rsquo;une installation sur une machine \u00e0 laquelle j&rsquo;acc\u00e8de via ssh. Le service est donc toujours pr\u00e9sent dans ma situation.<\/p>\n\n\n\n<p>Vient ensuite le fichier <code>converge.yml<\/code>. Pas de modification de ce c\u00f4t\u00e9 l\u00e0.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">---\n- name: Converge\n  hosts: all\n  become: true\n  tasks:\n    - name: \"Include role-install-fail2ban\"\n      include_role:\n        name: \"role-install-fail2ban\"<\/pre>\n\n\n\n<p>Enfin <code>verify.yml<\/code> dernier fichier de configuration. Pour un premier test, j&rsquo;ai fait au plus simple et je me contente de v\u00e9rifier que fail2ban fait bien partie des paquets install\u00e9s sur le syst\u00e8me.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">---<br>- name: Verify<br>  hosts: all<br>  tasks:<br>    - name: Gather package facts<br>      package_facts:<br>        manager: auto<br><br>    - name: Verify Packages<br>      assert:<br>        that: \"'{{ item }}' in ansible_facts.packages\"<br>      with_items:<br>        - fail2ban<\/pre>\n\n\n\n<p>Voil\u00e0 pour la configuration du test de mon r\u00f4le d&rsquo;installation de fail2ban.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">Conclusion<\/h4>\n\n\n\n<p>Apr\u00e8s une premi\u00e8re soir\u00e9e pass\u00e9e sur le sujet du test d&rsquo;un r\u00f4le ansible, je suis plut\u00f4t satisfait du r\u00e9sultat. Bien que le r\u00f4le soit l&rsquo;un de mes r\u00f4les les plus simples, cela ne devrait pas \u00eatre trop compliqu\u00e9 de g\u00e9n\u00e9raliser cette m\u00e9thode \u00e0 l&rsquo;ensemble de mes r\u00f4les, mais cela n\u00e9cessitera sans aucun doute de nombreuses heures de d\u00e9veloppement. Comme souvent, c&rsquo;est un processus it\u00e9ratif qui sera effectu\u00e9 progressivement sur les prochains mois. La simplicit\u00e9 de r\u00e9aliser un test sur un syst\u00e8me vierge est vraiment appr\u00e9ciable et permettra de v\u00e9rifier qu&rsquo;un r\u00f4le modifi\u00e9 fonctionne toujours, et cela, sans avoir \u00e0 passer par le d\u00e9ploiement d&rsquo;un serveur vierge. Prochaines \u00e9tapes : \u00e9tudier l&rsquo;int\u00e9gration avec le syst\u00e8me d&rsquo;actions GitHub et tester le playbook permettant le d\u00e9ploiement automatique d&rsquo;Unicoda.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">Sources<\/h4>\n\n\n\n<ul class=\"wp-block-list\"><li><a rel=\"noreferrer noopener\" href=\"https:\/\/www.slideshare.net\/geerlingguy\/continuous-testing-with-molecule-ansible-and-github-actions\" target=\"_blank\">Continuous Testing with Molecule, Ansible, and GitHub Actions<\/a><\/li><li><a rel=\"noreferrer noopener\" href=\"https:\/\/www.jeffgeerling.com\/blog\/2018\/testing-your-ansible-roles-molecule\" target=\"_blank\">Testing your Ansible roles with Molecule<\/a><\/li><\/ul>\n","protected":false},"excerpt":{"rendered":"<p>Apr\u00e8s avoir r\u00e9organis\u00e9 l&rsquo;ensemble de mes r\u00f4les Ansible, j&rsquo;avais en t\u00eate de trouver un moyen de tester leur ex\u00e9cution dans un environnement vierge. L&rsquo;id\u00e9e n&rsquo;est pas nouvelle. Le but : v\u00e9rifier l&rsquo;ex\u00e9cution du r\u00f4le plus facilement, c&rsquo;est-\u00e0-dire, sans savoir \u00e0 installer une nouvelle VM, ou \u00e0 louer un serveur \u00e0 cette occasion, m\u00eame si cette &hellip; <a href=\"https:\/\/www.unicoda.com\/?p=4520\" class=\"more-link\">Continuer la lecture<span class=\"screen-reader-text\"> de &laquo;&nbsp;Test d&rsquo;un role Ansible&nbsp;&raquo;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[337,316,31],"tags":[522,575,576,246],"class_list":["post-4520","post","type-post","status-publish","format-standard","hentry","category-auto-hebergement","category-configuration","category-installation","tag-ansible","tag-molecule","tag-role","tag-test"],"_links":{"self":[{"href":"https:\/\/www.unicoda.com\/index.php?rest_route=\/wp\/v2\/posts\/4520","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.unicoda.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.unicoda.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.unicoda.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.unicoda.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=4520"}],"version-history":[{"count":14,"href":"https:\/\/www.unicoda.com\/index.php?rest_route=\/wp\/v2\/posts\/4520\/revisions"}],"predecessor-version":[{"id":4548,"href":"https:\/\/www.unicoda.com\/index.php?rest_route=\/wp\/v2\/posts\/4520\/revisions\/4548"}],"wp:attachment":[{"href":"https:\/\/www.unicoda.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=4520"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.unicoda.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=4520"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.unicoda.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=4520"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}