Développement et test de rôles Ansible à l'aide de Molecule et Podman

L'un des principaux avantages de la plate-forme d'automatisation Red Hat Ansible est que son langage d'automatisation est lisible non seulement pour quelques gourous, mais aussi pour presque toutes les personnes impliquées dans l'informatique. Par conséquent, tout spécialiste peut contribuer à l'automatisation, ce qui facilite grandement l'organisation de l'interaction inter-équipes et l'introduction de l'automatisation au niveau de la culture d'entreprise.







Cependant, avec une telle masse de personnes impliquées, il est très important de tout tester à fond. Lors du développement de contenu Ansible tel que des playbooks, des rôles ou des collections, nous vous recommandons vivement de tout tester dans un environnement de test avant de le déployer en production. Le but de ces tests est de s'assurer que tout fonctionne comme il se doit, pour éviter les mauvaises surprises sur les systèmes de «production».



Le test du contenu d'automatisation est une chose délicate car il nécessite le déploiement d'une infrastructure de test dédiée et la mise en place de conditions de test pour garantir que les tests eux-mêmes sont pertinents. Molecule est un cadre de test complet qui vous aide à développer et à tester des rôles Ansible afin que vous puissiez vous concentrer sur le développement de l'automatisation sans être distrait par la gestion de votre infrastructure de test.



Voici comment il est déclaré dans la documentation du projet:



"Molecule est conçu pour aider à développer et tester les rôles Ansible, et favorise une approche qui se traduit par des rôles bien écrits, bien écrits, faciles à comprendre et à maintenir."


Molecule vous permet de tester un rôle sur plusieurs instances cibles pour le tester sur divers systèmes d'exploitation et environnements de virtualisation. Sans cela, pour chacune de ces combinaisons, vous devrez créer et maintenir un environnement de test distinct, configurer des connexions aux instances de test et les restaurer à leur état d'origine avant chaque test. Molecule fait tout pour vous, de manière automatisée et reproductible.



Dans cette série en deux parties, nous allons vous montrer comment utiliser Molecule pour développer et tester des rôles Ansible. Dans la première partie, nous examinerons l'installation et la configuration de Molecule, dans la seconde, le développement de rôles avec lui.



Si le rôle fait partie d'une collection, utilisez cette approche pour développer et tester le rôle unitaire. Dans le prochain article, nous allons vous montrer comment utiliser Molecule pour exécuter des tests intégrés sur des collections.



Molecule utilise des pilotes pour fournir des instances cibles à travers une variété de technologies, notamment des conteneurs Linux, des machines virtuelles et des fournisseurs de cloud. Par défaut, il est livré avec trois pilotes préinstallés: Docker et Podman pour les conteneurs, et un pilote délégué pour créer des intégrations personnalisées. Les pilotes pour les autres fournisseurs sont fournis par la communauté de développement de projet.



Dans cet article, nous utiliserons le pilote Podmanpour développer et tester un nouveau rôle à l'aide de conteneurs Linux. Podman est un moteur de conteneur léger pour Linux, il n'a pas besoin d'un démon en cours d'exécution et il permet aux conteneurs sans racine de s'exécuter, ce qui est bon pour la sécurité.



En utilisant Molecule avec le pilote Podman, nous développerons et testerons un nouveau rôle Ansible à partir de zéro qui déploie une application Web basée sur un serveur Web Apache et devrait s'exécuter sur Red Hat Enterprise Linux (RHEL) 8 ou Ubuntu 20.04.



Nous analysons un scénario typique dans lequel un rôle doit fonctionner sur différentes versions du système d'exploitation. À l'aide de conteneurs Podman et Linux, nous pouvons créer plusieurs instances pour tester le rôle sur différentes versions de système d'exploitation. En raison de leur légèreté, les conteneurs vous permettent de parcourir rapidement les fonctionnalités d'un rôle lors du développement. L'utilisation de conteneurs pour tester les rôles est applicable dans cette situation, car le rôle ne configure que les instances Linux en cours d'exécution. Pour effectuer des tests sur d'autres systèmes cibles ou infrastructures cloud, vous pouvez utiliser le pilote délégué ou d'autres pilotes fournis par la communauté.



De quoi avons nous besoin



Pour les exemples de cet article, vous avez besoin d'une machine Linux physique ou virtuelle avec Python 3 et Podman installés (nous utilisons RHEL 8.2). Podman devait également être configuré pour exécuter des conteneurs sans racine. L'installation de Podman dépasse le cadre de cet article, consultez la documentation officielle pour obtenir des informations connexes . L'installation de Podman sur RHEL 8 est également traitée dans la documentation du conteneur RHEL 8 .



Commençons



Molecule est conçu comme un package Python et est donc installé via pip. La première étape consiste à créer un environnement Python dédié et à y installer notre Molecule:



$ mkdir molecule-blog
$ cd molecule-blog
$ python3 -m venv molecule-venv
$ source molecule-venv/bin/activate
(molecule-venv) $ pip install "molecule[lint]"


Notez que nous installons Molecule avec l'option "lint" afin que pip fournisse également les outils "yamllint" et "ansible-lint", ce qui nous permettra d'utiliser Molecule pour analyser statiquement le code de rôle par rapport aux normes de codage Ansible.



L'installation télécharge toutes les dépendances requises à partir d'Internet, y compris Ansible. Voyons maintenant ce que nous avons installé:



$ molecule --version
molecule 3.0.4
   ansible==2.9.10 python==3.6


Eh bien, il est temps d'utiliser la commande "molecule" pour initialiser le nouveau rôle Ansible.



Initialiser un nouveau rôle Ansible



De manière générale, lors du développement d'un nouveau rôle Ansible, il est initialisé avec la commande "ansible-galaxy role init", mais nous utiliserons la commande "molecule" à la place. Cela nous donnera la même structure de rôle qu'avec la commande "ansible-galaxy", ainsi que le code de base pour exécuter les tests Molecule.



Par défaut, Molecule utilise le pilote Docker pour exécuter des tests. Puisque nous voulons utiliser podman à la place, lors de l'initialisation du rôle avec la commande "molecule", nous devons spécifier le pilote approprié en utilisant l'option "--driver-name = podman".



Revenez au répertoire "molecule-blog" et initialisez le nouveau rôle "mywebapp" avec la commande suivante:



$ molecule init role mywebapp --driver-name=podman
--> Initializing new role mywebapp...
Initialized role in /home/ricardo/molecule-blog/mywebapp successfully.


Molecule crée notre structure de rôle dans le dossier "mywebapp". Basculez vers ce dossier et voyez ce qu'il y a:



$ cd mywebapp
$ tree
.
├── defaults
│   └── main.yml
├── files
├── handlers
│   └── main.yml
├── meta
│   └── main.yml
├── molecule
│   └── default
│       ├── converge.yml
│       ├── INSTALL.rst
│       ├── molecule.yml
│       └── verify.yml
├── README.md
├── tasks
│   └── main.yml
├── templates
├── tests
│   ├── inventory
│   └── test.yml
└── vars
    └── main.yml
 
10 directories, 12 files


Molecule place ses fichiers de configuration dans le sous-répertoire "molecule". Lors de l'initialisation d'un nouveau rôle, il n'y a qu'un seul script appelé "par défaut". Plus tard, vous pouvez ajouter vos scripts ici pour tester diverses conditions. Dans cet article, nous n'utiliserons que le script "par défaut".



Vérifions la configuration de base dans le fichier "molecule / default / molecule.yml":



$ cat molecule/default/molecule.yml 
---
dependency:
  name: galaxy
driver:
  name: podman
platforms:
  - name: instance
    image: docker.io/pycontribs/centos:7
    pre_build_image: true
provisioner:
  name: ansible
verifier:
  name: ansible


Comme nous l'avons demandé, ce fichier indique que le pilote Podman est utilisé pour les tests. C'est là que la plate-forme par défaut pour l'instance de test est définie, via l'image du conteneur "docker.io/pycontribs/centos:7", que nous modifierons ultérieurement.



Contrairement à Molecule v2, Molecule v3 ne définit pas de linter par défaut. Par conséquent, ouvrons le fichier de configuration "molecule / default / molecule.yml" et ajoutons la configuration de la charpie à la fin:



$ vi molecule/default/molecule.yml
...
verifier:
  name: ansible
lint: |
  set -e
  yamllint .
  ansible-lint .


Enregistrez et fermez le fichier, et exécutez la commande "molecule lint" depuis le dossier racine de notre projet pour exécuter le linter tout au long du projet:



$ molecule lint


Nous obtenons quelques erreurs dans la sortie, car le fichier "meta / main.yml" ne contient pas un certain nombre de valeurs requises. Corrigeons ceci: éditez le fichier "meta / main.yml", ajoutez "auteur", "société", "licence", "plates-formes" et supprimez la ligne vide à la fin. Par souci de concision, nous nous passerons de commentaires, puis notre "meta / main.yaml" ressemblera à ceci:



$ vi meta/main.yml
galaxy_info:
  author: Ricardo Gerardi
  description: Mywebapp role deploys a sample web app 
  company: Red Hat 
 
  license: MIT 
 
  min_ansible_version: 2.9
 
  platforms:
  - name: rhel
    versions:
    - 8 
  - name: ubuntu
    versions:
    - 20.04
 
  galaxy_tags: []
 
dependencies: []


Exécutons à nouveau le linter sur le projet et assurez-vous qu'il n'y a plus d'erreurs.



$ molecule lint
--> Test matrix
    
└── default
    ├── dependency
    └── lint
    
--> Scenario: 'default'
--> Action: 'dependency'
Skipping, missing the requirements file.
Skipping, missing the requirements file.
--> Scenario: 'default'
--> Action: 'lint'
--> Executing: set -e
yamllint .
ansible-lint . 


Ainsi, notre rôle est initialisé et la configuration de base de la molécule est également en place. Créons maintenant une instance de test.



Créer une instance de test



Par défaut, Molecule ne définit qu'une seule instance, appelée "instance" et créée à partir de l'image "Centos: 7". Notre rôle, si vous vous en souvenez, devrait fonctionner sur RHEL 8 et Ubuntu 20.04. De plus, comme il exécute le serveur Web Apache en tant que service système, nous avons besoin d'une image de conteneur avec "systemd" activé.



Red Hat a une image de base universelle officielle pour RHEL 8 avec "systemd" activé:



• registry.access.redhat.com/ubi8/ubi-init



Il n'y a pas d'image officielle "systemd" pour Ubuntu, nous utiliserons donc l'image maintenue par Jeff Geerling (Jeff Geerling) de la communauté Ansible:



• geerlingguy / docker-ubuntu2004-ansible



Pour obtenir des instances avec "systemd", éditons le fichier de configuration "molecule / default / molecule.yml" en supprimant l'instance "centos: 7" et en ajoutant deux nouvelles instances:



$ vi molecule/default/molecule.yml
---
dependency:
  name: galaxy
driver:
  name: podman
platforms:
  - name: rhel8
    image: registry.access.redhat.com/ubi8/ubi-init
    tmpfs:
      - /run
      - /tmp
    volumes:
      - /sys/fs/cgroup:/sys/fs/cgroup:ro
    capabilities:
      - SYS_ADMIN
    command: "/usr/sbin/init"
    pre_build_image: true
  - name: ubuntu
    image: geerlingguy/docker-ubuntu2004-ansible
    tmpfs:
      - /run
      - /tmp
    volumes:
      - /sys/fs/cgroup:/sys/fs/cgroup:ro
    capabilities:
      - SYS_ADMIN
    command: "/lib/systemd/systemd"
    pre_build_image: true
provisioner:
  name: ansible
verifier:
  name: ansible
lint: |
  set -e
  yamllint .
  ansible-lint .


Avec ces paramètres, nous montons pour chaque instance le système de fichiers temporaire "/ run" et "/ tmp", ainsi que le volume "cgroup". De plus, nous activons la fonction "SYS_ADMIN", qui est nécessaire pour exécuter des conteneurs avec Systemd.



Si vous faites tout intelligemment et exécutez cet exemple sur une machine RHEL 8 avec SELinux activé, vous devez également définir le paramètre booléen "container_manage_cgroup" sur true afin que les conteneurs puissent exécuter Systemd (voir la documentation RHEL 8 pour plus de détails ):



sudo setsebool -P container_manage_cgroup 1


Molecule utilise le Playbook Ansible pour initialiser ces instances. Modifions et ajoutons les paramètres d'initialisation en modifiant le dictionnaire "provisioner" dans le fichier de configuration "molecule / default / molecule.yml".



Il accepte les mêmes options de configuration que celles spécifiées dans le fichier de configuration "ansible.cfg". Par exemple, mettons à jour la configuration du provisioner en ajoutant une section «defaults». Réglez l'interpréteur Python sur "auto_silent" pour désactiver les avertissements. Incluons les plugins de rappel "profile_tasks", "timer" et "yaml" afin que les informations du profileur soient incluses dans la sortie du Playbook. Enfin, ajoutez la section "ssh_connection" et désactivez le pipelining SSH car il ne fonctionne pas avec Podman:



provisioner:
  name: ansible
  config_options:
    defaults:
      interpreter_python: auto_silent
      callback_whitelist: profile_tasks, timer, yaml
    ssh_connection:
      pipelining: false


Sauvegardons ce fichier et créons une instance avec la commande "molecule create" depuis le répertoire racine de notre rôle:



$ molecule create


Molecule exécutera un playbook init et créera nos deux instances. Vérifions-les avec la commande "liste de molécules":



$ molecule list
Instance Name    Driver Name    Provisioner Name    Scenario Name    Created    Converged
---------------  -------------  ------------------  ---------------  ---------  -----------
rhel8            podman         ansible             default          true       false
ubuntu           podman         ansible             default          true       false


Vérifions également que les deux conteneurs fonctionnent dans Podman:



$ podman ps
CONTAINER ID  IMAGE                                                   COMMAND               CREATED             STATUS                 PORTS  NAMES
2e2f14eaa37b  docker.io/geerlingguy/docker-ubuntu2004-ansible:latest  /lib/systemd/syst...  About a minute ago  Up About a minute ago         ubuntu
2ce0a0ea8692  registry.access.redhat.com/ubi8/ubi-init:latest         /usr/sbin/init        About a minute ago  Up About a minute ago         rhel8


Lors du développement d'un rôle, Molecule utilise les instances en cours d'exécution pour le tester. Si le test échoue ou si une erreur conduit à des changements irréversibles, à cause desquels tout doit recommencer, vous pouvez à tout moment tuer ces instances avec la commande "molecule destroy" et les recréer avec la commande "molecule create".



Conclusion



Si vous êtes impatient et souhaitez approfondir le sujet du développement et du test des rôles, ou le sujet de l'automatisation Ansible, nous vous recommandons les ressources suivantes:






All Articles