Comment faire du Test Driven Development pour Ansible ? #2
Sommaire
- Configuration du poste de développement
- Installer et configurer Molecule
- Python3 virtualenv
- Uniformisation et Industrialisation
- Molecule
- Initialisation d’un nouveau rôle avec Molecule
- Corrections de base
- Test Driven Development (TDD)
Avant de démarrer votre lecture, découvrez la première partie de cet article :
Il existe des techniques Test Driven Development (TDD) que nous pouvons adapter à l’infrastructure. Voici un exemple concret pour Ansible…
Configuration du poste de développement
Je vous conseille pour cela d’utiliser l’IDE Visual Studio Code. C’est un outil gratuit, construit sur une source ouverte et il fonctionne partout.
Nous avons également créé un pack d’extension pour Visual Studio code sous l’effigie Néosoft.
Ce pack contient tout ce dont vous aurez besoin pour développer en Ansible.
Installer et configurer Molecule
Nous voulons installer Molecule localement (soit sur votre poste de travail avec Linux / WSL ou sur une VM sous Linux). L’installation proprement dite de Molecule peut être effectuée à l’aide de pip.
Je vais partir d’un environnement Ubuntu, n’hésitez pas à vous adapter selon votre poste de travail.
Python3 virtualenv
“environnements virtuels” légers avec leurs propres dossiers
sudo apt-get update sudo apt-get install python3 python3-venv python3-pip
Nous allons créer un virtualenv avec ses prérequis pour cela, faite un :
mkdir -p ~/workspace/tuto/ansible/molecule && cd ~/workspace/tuto/ansible/molecule
Ensuite, ouvrez votre IDE dans votre dossier (code .
) et créez le fichier requirements.txt
# ###### Python dependencies configuration file for ansible # ansible molecule[docker,lint] yamllint ansible-lint
Je n’ai volontairement pas fixé les versions des packages à installer afin que cet article soit un maximum à jour, sur vos projets il faudra être sous ce format par exemple :
# ###### Python dependencies configuration file for ansible # ansible==6.6.0 molecule[docker,lint]==4.0.3 yamllint==1.28.0 ansible-lint==6.8.6
Passons à la création de l’environnement virtuel :
python3.9 -m venv virtualenv source virtualenv/bin/activate pip install --upgrade pip setuptools wheel pip install --requirement requirements.txt
De là, si vous faites un ansible –version
, vous verrez que la version d’Ansible est bien installée
Pour sortir de votre environnement virtuel, nous allons le désactiver, lancer la commande :
deactivate
Refaite un ansible –version
, si vous n’aviez pas ansible d’installer auparavant, vous devriez avoir une erreur du type commande not found
Uniformisation et Industrialisation
Nous allons uniformiser et industrialiser tout ça (un peu).
Ceci afin que tous ceux qui contribuent au projet, le feront avec les mêmes méthodes de travail.
Créer un fichier Makefile
à la racine de votre projet (~/workspace/tuto/ansible/molecule)
.ONESHELL: SHELL:=/bin/bash .PHONY: bootstrap bootstrap: python3.9 -m venv virtualenv source virtualenv/bin/activate pip install --upgrade pip setuptools wheel pip install --requirement requirements.txt .PHONY: reinitialization reinitialization: rm -rf virtualenv $(MAKE) bootstrap
Grâce à ça, vous allez pouvoir exécuter la commande make bootstrap
ou make reinitialization
Molecule
Molecule est un outil initialement développé par retr0h et maintenant maintenu par Ansible/Red Hat pour tester automatiquement les rôles.
Le cœur de Molecule est conçu pour automatiser toutes les parties d’un rôle :
- Lancez et préparez des instances pour tester votre rôle avec de nombreux “drivers” pour différentes sources d’infrastructure (par exemple, Docker, Vagrant, EC2, etc.).
- Exécutez votre rôle sur toutes les instances
- Testez que vos rôles fonctionnent correctement et que les changements attendus se sont produits sur chaque instance.
- Détruisez toute l’infrastructure créée à la fin pour que tout soit propre.
Initialisation d’un nouveau rôle avec Molecule
molecule init role --driver-name docker --verifier-name ansible my_namespace.role_name
Nous pouvons tester molecule tel que :
cd my_namespace.role_name molecule converge
Corrections de base
Modifiez le fichier .yamllint
afin de le rendre très strict
--- # Based on ansible-lint config extends: default rules: line-length: disable
Et corrigeons le fichier meta/main.yml
--- # meta/main.yml galaxy_info: author: your name description: your role description company: your company (optional) role_name: role_name namespace: my_namespace
Uniformisons encore notre Makefile
:
.ONESHELL: SHELL:=/bin/bash .PHONY: bootstrap bootstrap: python3.9 -m venv virtualenv source virtualenv/bin/activate pip install --upgrade pip setuptools wheel pip install --requirement requirements.txt .PHONY: reinitialization reinitialization: rm -rf virtualenv $(MAKE) bootstrap .PHONY: molecule-converge molecule-converge: source virtualenv/bin/activate cd my_namespace.role_name molecule converge .PHONY: molecule-reconverge molecule-reconverge: source virtualenv/bin/activate cd my_namespace.role_name molecule destroy molecule converge .PHONY: molecule-test molecule-test: source virtualenv/bin/activate cd my_namespace.role_name molecule test .PHONY: molecule-destroy molecule-destroy: source virtualenv/bin/activate cd my_namespace.role_name molecule destroy
Pour la suite de notre article, nous allons nous servir de l’excellent article de Stéphane ROBERT
Test Driven Development (TDD)
Nous allons installer nginx, tout d’abord, nous devons écrire un test :
Ajoutez le test dans notre playbook molecule/default/verify.yml
--- - name: Verify hosts: all gather_facts: false tasks: - name: Nginx est présent ansible.builtin.stat: path: /usr/sbin/nginx - name: Chargement de l'état des service ansible.builtin.service_facts: - name: Controle de la présence de nginx ansible.builtin.assert: that: - services["nginx.service"]["state"] == "running" - services["nginx.service"]["status"] == "enabled"
On ajoute le verify dans la séquence de converge de molecule (molecule/default/molecule.yml
):
Et on se base sur l’image de Jeff Geerling
--- dependency: name: galaxy driver: name: docker platforms: - name: instance image: "geerlingguy/docker-${MOLECULE_DISTRO:-centos8}-ansible:latest" command: ${MOLECULE_DOCKER_COMMAND:-""} volumes: - /sys/fs/cgroup:/sys/fs/cgroup:ro privileged: true pre_build_image: true provisioner: name: ansible verifier: name: ansible scenario: converge_sequence: - dependency - create - prepare - converge - verify
Notre test est en echec ! On ajout le code pour qu’il passe (rapidement) :
Dans tasks/main.yml
--- # tasks file for my_namespace.role_name - name: Install nginx. ansible.builtin.package: name: nginx state: present - name: Start nginx service ansible.builtin.service: name: nginx state: started enabled: true
Si vous relancez un make molecule test
à la racine de votre projet, tout passe, même l’idempotence !
Bienvenue dans un monde de tests.