Loading search data...

Introduction sur les collections Ansible

Introduit avec la version 2.8 d’Ansible les collections permettent de répondre à la problématique de distribution des contenus Ansible. En effet les collections vont permettre d’installer en une seule opération modules, rôles et même playbook Ansible.

Rappel : depuis la version 3.0 ansible est distribué différemment. En effet, il est composé de plusieurs packages python dont ansible-base. Ansible-base embarque les programmes de base d’Ansible que sont ansible-playbook, ansible-galaxy, ansible-doc,.. et quelques modules et de la documentation.

Le reste des modules et plugins ont été déplacés dans diverses “collections” dont la plus utilisé est la “community.general”.

Pour s’y retrouver dans les collections il faut se rendre sur cette page.

Installation de collections Ansible

Le premier moyen pour installer une collection est d’utiliser la commande ansible-galaxy. En effet depuis la version 2.8 d’Ansible cette commande possède une option permettant de gérer les collections.

ansible-galaxy collection install community.general

On peut également utiliser un fichier tar.gz. Mais ce sera surtout pour gérer vos propres collections.

ansible-galaxy collection install my_namespace-my_collection-1.0.0.tar.gz

Bon c’est bien avec une ou deux collections, mais pour un nombre important il faut plutôt utiliser un fichier requirement.yml

---
roles:
  # Install a role from Ansible Galaxy.
  - name: geerlingguy.java
    version: 1.9.6

collections:
  # Install a collection from Ansible Galaxy.
  - name: geerlingguy.php_roles
    version: 0.9.3
    source: https://galaxy.ansible.com

Développement de collections Ansible

Comme dit plus haut une collection est un simple format de distribution de contenu utilisé par Ansible Galaxy. Ici c’est une archive compressée qui contient cette arborescence :

collection/
├── docs/
├── galaxy.yml
├── plugins/
│   ├── modules/
│   │   └── module1.py
│   ├── inventory/
│   └── .../
├── README.md
├── roles/
│   ├── role1/
│   ├── role2/
│   └── .../
├── playbooks/
│   ├── files/
│   ├── vars/
│   ├── templates/
│   └── tasks/
└── tests/

On y retrouve :

  • un fichier galaxy.yml contenant les informations nécessaires pour créer cette collection.
  • un répertoire ou est stocké la documentation des roles et des plugins.
  • des répertoires roles, playbooks, plugins et tests. Dans le répertoire plugins il faut regrouper les plugins par type.

Cette structure est créé avec la commande suivante

 ansible-galaxy collection init step.test

Il faut juste créer le répertoire playbooks. Dans le répertoire plugins on retrouve un fichier README.md qui contient la liste de tous les types de plugins ou il faudra créer un répertoire.

Pour créer des roles il suffit de se mettre dans le répertoire source et de lancer la commande classique de création de roles ansible.

cd steph/test/roles
ansible-galaxy role init premierrole

Dans les taches du role ajoutons un simple debug :

---
- name: Debug test.
  debug: msg="Mon premier role"

Build de notre collection

Cela se fait assez simplement. Depuis le répertoire de votre collection tapez la commande suivante :

ansible-galaxy collection build
Created collection for stephane.test_collection at /home/vagrant/Projets/perso/stephane/test_collection/stephane-test_collection-1.0.0.tar.gz

Utilisons notre collection

Créer un autre projet :

mkdir ~/Projets/test
ansible-galaxy collection install /home/vagrant/Projets/perso/stephane/test_collection/stephane-test_collection-1.0.0.tar.gz -p ./collections
[WARNING]: The specified collections path '/home/vagrant/Projets/perso/test/collections' is not part of the configured Ansible collections paths
'/home/vagrant/.ansible/collections:/usr/share/ansible/collections'. The installed collection won't be picked up in an Ansible run.

Comme vous pouvez le lire nous devons indiquer à Ansible ou se trouve notre collection. Pour ca il existe 2 moyens :

  • dans le fichier ansible.cfg dans la section [defaults] en ajoutant le paramètre collections_paths
  • avec la variable d’environnement ANSIBLE_COLLECTIONS_PATHS
ANSIBLE_COLLECTIONS_PATHS=

Créer un simple playbook utilisant votre collection

- hosts: localhost
  gather_facts: true
  tasks:
      - import_role:
          name: stephane.test_collection.premierrole

Vous remarquez qu’il vous indiquer le chemin du role dans la collection. Lançons le :

ansible-playbook -c local playbook.yaml

PLAY [localhost] ***

TASK [Gathering Facts] ***
ok: [localhost]

TASK [stephane.test_collection.premierrole : debug] ***
ok: [localhost] => {
    "msg": "OracleLinux"
}

PLAY RECAP ******
localhost                  : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

Ajouter des tests à votre collection

Depuis la version 2.9 d’Ansible, Ansible est livré avec un utilitaire se nommant ansible-test. Cet utilitaire permet d’ajouter des tests à vos collections qui peuvent être :

  • des tests unitaires sur vos propres développement de modules et de plugins (ils doivent intégrer des tests au format unittest ou pytest)
  • des tests d’intégration
  • des tests syntaxique sanity test

Ansible-test utilise docker pour créer l’environnement de test. On peut utiliser les images suivantes qui contiennent python3

  • centos8
  • fedora32
  • opensuse15
  • ubuntu1804

Comment lancer les tests syntaxique dans une collection Ansible

Ces premiers tests ne nécessite aucune action de notre part. Lancons les tests en prenant une centos8

ansible-test sanity --docker centos8

...

ERROR: Found 3 yamllint issue(s) which need to be resolved:
ERROR: galaxy.yml:62:1: empty-lines: too many blank lines (1 > 0)
ERROR: roles/premierrole/tasks/main.yml:4:1: empty-lines: too many blank lines (1 > 0)
ERROR: tests/integration/targets/premierrole/tasks/main.yml:3:1: empty-lines: too many blank lines (1 > 0)

ERROR: The 3 sanity test(s) listed below (out of 45) failed. See error output above for details.
future-import-boilerplate
metaclass-boilerplate
pep8

Reste plus qu’à corriger et à relancer.

Pour retrouver la liste des tests actifs (33):

ansible-test sanity --list-tests
action-plugin-docs
ansible-doc
...
yamllint

Surpris de ne pas retrouver ansible-lint dans cette liste.

Comment ajouter des tests unitaires à notre collection ansible

Prenons l’exemple du développement d’un plugin de filtre Ansible. Il faut écrire le plugins de filtre dans le répertoire plugins/filter_plugins/ de la collection.

└── tests
    └── unit
        └── plugins
            └── filter
                ├── __pycache__
                │   └── test_snaketocamel.cpython-38.pyc
                └── test_snaketocamel.py

Reprenons l’exemple du filtre du billet dédié à ce sujet.

from ansible.errors import AnsibleError
import re

try:
  import six
  HAS_LIB = True
except ImportError:
  HAS_LIB = False

def snake_to_camel(text, suffix=''):
  if not HAS_LIB:
    raise AnsibleError('You need to install "six" prior to running '
                          'snaketocamel filter')
  import re
  return suffix + ''.join(x.title() or '_' for x in text.split('_'))

class FilterModule(object):

  def filters(self):
    return {
      'snaketocamel': snake_to_camel
    }

Dans le répertoire de la collection ajouter un répertoire tests/unit/plugins/filter et déposez-y ce fichier test_snaketocamel.py:

import unittest
from ansible_collections.steph.test.plugins.filter_plugins.snaketocamel import snake_to_camel


class TestMyFilter(unittest.TestCase):

    def test_snaketocamel(self):
        self.assertEqual(snake_to_camel("une_variable"), 'UneVariable')

Maintenant il suffit de lancer ansible-test depuis le répertoire de la collection :

ansible-test unit --docker ubuntu1804
...

Unit test with Python 3.6
============================= test session starts ==============================
platform linux -- Python 3.6.9, pytest-6.2.3, py-1.10.0, pluggy-0.13.1
rootdir: /root/ansible_collections/steph/test/tests/unit/plugins/filter, configfile: ../../../../../../../ansible/test/lib/ansible_test/_data/pytest.ini
plugins: forked-1.3.0, mock-3.6.0, xdist-2.2.1
gw0 I / gw1 I / gw2 I / gw3 I
gw0 [1] / gw1 [1] / gw2 [1] / gw3 [1]

.                                                                        [100%]
- generated xml file: /root/ansible_collections/steph/test/tests/output/junit/python3.6-units.xml -
============================== 1 passed in 0.79s ===============================

Comment ajouter des tests d’intégration à notre collection ansible

Les tests d’intégration sont écrits sous la forme de roles Ansible.

Dans le répertoire tests il faut créer la structure suivante integration/targets/premierrole/tasks dans le répertoire tests de la collection.

└── tests
    ├── integration
    │   └── targets
    │       └── premierrole
    │           └── tasks
    │               └── main.yml

Ajoutons simplement l’import du role premierrole :

- import_role:
  name: stephane.test_collection.premierrole

Lançons le test d’intégration :

ansible-test integration --docker ubuntu 1804

PLAY [testhost] ****************************************************************

TASK [Gathering Facts] *********************************************************
ok: [testhost]

TASK [steph.test.premierrole : Debug test.] ************************************
ok: [testhost] => {
    "msg": "Mon premier role"
}

PLAY RECAP *********************************************************************
testhost                   : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

On peut donc désormais valider notre collection sans installer quoique ce soit, mis à part docker, avec ansible-test. On peut aussi lancer des tests sur un environnement cloud.

Je suis sur que ce produit va encore beaucoup évoluer.

Si vous voulez plus de tutorials Ansible je vous renvoie sur le billet de l'introduction à ansible


Alimenter un blog comme celui-ci est aussi passionnant que chronophage. En passant votre prochaine commande (n'importe quel autre article) via ce lien, je recevrai 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!

Mots clés :

devops, ansible, tutorials, vagrant,

Autres Articles