Loading search data...

Soutenez moi :) En achetant à partir de ce lien je toucherai une toute petite comm.

Tester vos playbooks Ansible avec testinfra

La suite de la formation Ansible: les tests

Comme pour les roles je fais le choix de mettre en place du TDD ou Test Driven Development pour écrire mes playbooks Ansible, ce qui consiste à:

  • Ecrire un test.
  • Vérifier qu’il échoue.
  • Ecrire le code pour faire passer ce test.
  • Vérifier qu’il passe.
  • Améliorer le code si-nécessaire, plus maintenable si besoin avant de reprendre un nouveau cycle.

Installation de testinfra

Testinfra est écrit en python et donc pour l’installer on va utiliser pip :

pip install pytest-testinfra

Je vais utiliser la structure suivante :

├── README.md
├── Vagrantfile
├── ansible.cfg
├── files
├── inventories
│   └── test
│       ├── group_vars
│       │   ├── all
│       │   │   └── vars.yaml
│       │   ├── id100_name
│       │   │   └── vars.yaml
│       │   └── id200_name
│       │       └── vars.yaml
│       ├── host_vars
│       │   └── hostname.yml
│       └── hosts
├── playbooks
│   ├── first.yml
│   └── provision-playbook.yml
├── roles
├── roles-requirements.yml
├── tests
│   └── webservers.py
└── vars

Ajout d’un inventaire

Dans mon inventaire (inventories/hosts) j’ai ceci:

[all:vars]

[webservers]
host1

[dbservers]
host2

Je vous renvoie à mon billet sur vagrant pour provisionner ces deux machines via un simple fichier Vagrantfile.

Ecriture d’un test

Dans le répertoire de votre playbook créer un répertoire tests dans lequel nous allons déposer nos fichiers de tests.

Comme dit plus haut testinfra est écrit en python et donc les tests reprennent la syntaxe python.

Mon fichier de test webservers.py :

def test_nginx_is_installed(host):
    nginx = host.package("nginx")
    assert nginx.is_installed
    assert nginx.version.startswith("1.14")


def test_nginx_running_and_enabled(host):
    nginx = host.service("nginx")
    assert nginx.is_running
    assert nginx.is_enabled

Cet exemple vérifie :

  • que le package nginx :
    • est installé
    • et sa version est une 1.14.xxx
  • que le service nginx :
    • est activé
    • est démarré

Lancement du test

Pour lancer le test on utilise cette commande :

py.test --hosts=webservers --connection=ansible --ansible-inventory=inventories/ --force-ansible tests/webservers.py

On limite le test au groupe webservers avec le fichier de test webservers.py.

Vous devriez obtenir ce résultat:

================================================================================= test session starts =================================================================================
platform linux -- Python 3.8.6, pytest-6.2.1, py-1.10.0, pluggy-0.13.1
rootdir: /home/ubuntu/Projets/ansible/templates/playbook
plugins: testinfra-6.1.0
collected 2 items

tests/webservers.py FF                                                                                                                                                          [100%]

====================================================================================== FAILURES =======================================================================================
__________________________________________________________________ test_nginx_is_installed[ansible://host1] ___________________________________________________________________

host = <testinfra.host.Host ansible://host1>

    def test_nginx_is_installed(host):
        nginx = host.package("nginx")
>       assert nginx.is_installed
E       assert False
E        +  where False = <package nginx>.is_installed

tests/webservers.py:3: AssertionError
_______________________________________________________________ test_nginx_running_and_enabled[ansible://host1] _______________________________________________________________

host = <testinfra.host.Host ansible://host1>

    def test_nginx_running_and_enabled(host):
        nginx = host.service("nginx")
>       assert nginx.is_running
E       assert False
E        +  where False = <service nginx>.is_running

tests/webservers.py:9: AssertionError
=============================================================================== short test summary info ===============================================================================
FAILED tests/webservers.py::test_nginx_is_installed[ansible://host1] - assert False
FAILED tests/webservers.py::test_nginx_running_and_enabled[ansible://host1] - assert False
================================================================================== 2 failed in 8.71s ==================================================================================

Normal que ca plante puisqu’on a encore rien installé.

Ecrire le playbook

Ici on va faire un simple playbook, on utilise pas de role pour cet exemple :

---
- hosts: webservers
  become: yes
  tasks:
    - name: Install nginx
      package:
        name: nginx
        state: latest
    - name: active nginx et le démarre
      service:
        name: nginx
        state: started
        enabled: yes

Relance du test

On obtient cette fois ce résultat.

================================================================================= test session starts =================================================================================
platform linux -- Python 3.8.6, pytest-6.2.1, py-1.10.0, pluggy-0.13.1
rootdir: /home/ubuntu/Projets/ansible/templates/playbook
plugins: testinfra-6.1.0
collected 2 items

tests/webservers.py ..                                                                                                                                                          [100%]

================================================================================= 2 passed in 11.63s ==================================================================================

Plus qu’à l’intégrer à votre CI pour tout contrôler après le provisionnement.

La suite de la formation ansible dans de prochains billets.

Mots clés :

devops, ansible, tutorials,

Autres Articles


Alimenter un blog comme celui-ci est aussi passionnant que chronophage. En passant votre prochaine commande (n'importe quel autre article) au travers du lien produit ci-contre, je touche une petite commission sans que cela ne vous coûte plus cher. Cela ne me permet pas de gagner ma vie, mais de couvrir les frais inhérents au fonctionnement du site. Merci donc à vous!