
Créer sa propre collection est l'aboutissement du parcours collections : packager plusieurs ressources (modules Python custom + rôles + plugins + playbooks) sous un même namespace versionné, distribuable sur Galaxy ou Automation Hub privé. Cette page construit pas à pas une collection minimaliste avec un module Python qui retourne Hello, valide le tout avec ansible-test sanity --docker default, et produit un tarball publiable.
À la fin, vous saurez initialiser une collection conforme, écrire un module Python avec ses 3 sections obligatoires (DOCUMENTATION, EXAMPLES, RETURN), builder un tarball semver, et exécuter la batterie de validations pré-publication.
Ce que vous allez apprendre
Section intitulée « Ce que vous allez apprendre »ansible-galaxy collection init: générer la structure standard.- Remplir
galaxy.yml: namespace, name, version, dependencies,tags:obligatoires. - Remplir
meta/runtime.yml:requires_ansible:+plugin_routing:. - Écrire un module Python avec
DOCUMENTATION + EXAMPLES + RETURN+AnsibleModule. - Ajouter un rôle dans
roles/<name>/. ansible-galaxy collection build: produire le tarball.ansible-test sanity --docker: validation pré-publication.
Prérequis
Section intitulée « Prérequis »- Avoir lu Découvrir et requirements.yml.
ansible-test --versionretourne au moins2.18.x.- Docker ou Podman pour
--docker.
Étape 1, Initialiser la structure
Section intitulée « Étape 1, Initialiser la structure »mkdir -p ansible_collectionsansible-galaxy collection init student.webapp \ --init-path ansible_collections/Sortie :
- Collection student.webapp was created successfullyStructure générée :
Répertoireansible_collections/student/webapp/
- galaxy.yml
- README.md
- LICENSE
Répertoiremeta/
- runtime.yml
Répertoireplugins/
Répertoiremodules/
- …
Répertoirefilter/
- …
Répertoirelookup/
- …
Répertoireinventory/
- …
Répertoiremodule_utils/
- …
Répertoireroles/
- …
Répertoireplaybooks/
- …
Répertoiretests/
- …
Répertoirechangelogs/
- …
Répertoiredocs/
- …
🔍 Observation : init génère toute la structure conforme d'une collection. Pas besoin de tout remplir : ne garder que ce dont on a besoin (les dossiers vides ne posent pas de problème).
Étape 2, Remplir galaxy.yml
Section intitulée « Étape 2, Remplir galaxy.yml »namespace: studentname: webappversion: 1.0.0readme: README.mdauthors: - "Apprenant RHCE 2026 <student@example.com>"description: "Collection lab : déploie webapp avec nginx"license: - GPL-3.0-or-latertags: # ← OBLIGATOIRE pour Galaxy - linux - web - nginxdependencies: ansible.posix: ">=2.0.0"repository: https://github.com/student/webappdocumentation: https://github.com/student/webappissues: https://github.com/student/webapp/issuesbuild_ignore: - .github - .venv - tests/output🔍 Observation cruciale : tags: est obligatoire pour publier sur Galaxy. Sans, l'import échoue silencieusement avec un message peu explicite. dependencies: déclare les autres collections requises avec contraintes semver.
Étape 3, Remplir meta/runtime.yml
Section intitulée « Étape 3, Remplir meta/runtime.yml »---requires_ansible: ">=2.18.0"
# Optionnel : redirects pour les modules renommés (cf migration role)# plugin_routing:# modules:# old_module:# redirect: student.webapp.new_module🔍 Observation : requires_ansible: est obligatoire dès qu'on a un module Python. Sans, ansible-test sanity échoue avec ERROR! No requires_ansible declared.
Étape 4, Ajouter un module Python custom
Section intitulée « Étape 4, Ajouter un module Python custom »plugins/modules/webapp_healthcheck.py :
#!/usr/bin/python# -*- coding: utf-8 -*-
from __future__ import absolute_import, division, print_function
__metaclass__ = type
DOCUMENTATION = r'''---module: webapp_healthcheckshort_description: Health check minimaliste d'une URL HTTPversion_added: "1.0.0"description: - Vérifie qu'une URL HTTP répond avec un code 200.options: url: description: URL à tester. required: true type: strauthor: - "Apprenant RHCE 2026"'''
EXAMPLES = r'''- name: Vérifier que nginx répond student.webapp.webapp_healthcheck: url: "http://localhost:80"'''
RETURN = r'''status_code: description: Code HTTP retourné. type: int returned: always'''
import urllib.requestfrom ansible.module_utils.basic import AnsibleModule
def run_module(): module_args = dict(url=dict(type='str', required=True)) module = AnsibleModule(argument_spec=module_args, supports_check_mode=True)
url = module.params['url'] try: with urllib.request.urlopen(url, timeout=5) as response: code = response.getcode() module.exit_json(changed=False, status_code=code) except Exception as exc: module.fail_json(msg=f"Health check KO: {exc}")
def main(): run_module()
if __name__ == '__main__': main()🔍 Observation : tous les modules Python suivent ce squelette. Les 3 sections DOCUMENTATION, EXAMPLES, RETURN sont obligatoires pour ansible-test sanity. AnsibleModule + argument_spec sécurise les paramètres + supporte check_mode.
Étape 5, Ajouter un rôle
Section intitulée « Étape 5, Ajouter un rôle »roles/nginx/tasks/main.yml :
---- name: Installer nginx ansible.builtin.dnf: name: nginx state: present
- name: Activer et démarrer nginx ansible.builtin.systemd_service: name: nginx state: started enabled: true🔍 Observation : un rôle dans une collection suit la même structure qu'un rôle standalone. La différence : on l'utilise avec son FQCN : student.webapp.nginx.
Étape 6, Ajouter un playbook d'orchestration
Section intitulée « Étape 6, Ajouter un playbook d'orchestration »playbooks/deploy.yml :
---- name: Déployer la webapp avec la collection student.webapp hosts: webservers become: true tasks: - name: Appliquer le rôle nginx ansible.builtin.import_role: name: student.webapp.nginx # FQCN du rôle
- name: Health check via le module custom student.webapp.webapp_healthcheck: # FQCN du module url: "http://localhost:80" register: hc
- name: Afficher la valeur relevée ansible.builtin.debug: var: hc.status_code🔍 Observation : depuis l'extérieur de la collection, on appelle modules et rôles avec leur FQCN complet. À l'intérieur de la collection, on peut utiliser des noms courts (mais déconseillé pour la lisibilité).
Étape 7, Builder la collection
Section intitulée « Étape 7, Builder la collection »cd ansible_collections/student/webapp/ansible-galaxy collection build --output-path ../../../build/Sortie :
Created collection for student.webapp at /home/.../build/student-webapp-1.0.0.tar.gz🔍 Observation : le tarball est publiable avec ansible-galaxy collection publish <tarball> --token "$GALAXY_TOKEN". Versions automatiques via CI : tag Git v1.0.0 → workflow build → publish.
Étape 8, Lancer ansible-test sanity
Section intitulée « Étape 8, Lancer ansible-test sanity »cd ansible_collections/student/webapp/ansible-test sanity --docker default -vCible attendue :
Running sanity test "ansible-doc"Running sanity test "validate-modules"Running sanity test "yamllint"Running sanity test "pep8"...All sanity tests passed.🔍 Observation : --docker default lance la batterie de validations dans un conteneur Docker : doc YAML cohérente, types Python, FQCN, PEP8, yamllint. Indispensable en CI avant publication. Sans, l'import Galaxy échoue silencieusement.
Publier sur Galaxy
Section intitulée « Publier sur Galaxy »# Token API depuis https://galaxy.ansible.com/me/preferencesansible-galaxy collection publish \ ../../../build/student-webapp-1.0.0.tar.gz \ --token "$GALAXY_TOKEN"Workflow d'import sur Galaxy NG (backend Galaxy v3, 2026) :
- Upload : tarball reçu par Galaxy.
- Unpack : extraction et validation du
MANIFEST.json. - Sanity scan : vérification automatique du
galaxy.yml(tags, version, namespace). - Tests CI :
ansible-test sanityexécuté sur les serveurs Galaxy (Galaxy NG le fait depuis 2024). - Import dans
staging: version visible mais pas listée publique. - Approval (manuel ou auto selon namespace) → publication dans
published.
Mettre en pratique
Section intitulée « Mettre en pratique »Les huit étapes ci-dessus s'enchaînent bien à la lecture, beaucoup moins au clavier : c'est presque toujours une clé manquante dans galaxy.yml ou une section absente du module Python qui bloque le premier build. Ce lab vous fait initialiser la collection, remplir meta/runtime.yml, y ajouter un rôle et un module documenté, puis produire le tarball. La correction ouvre l'archive obtenue et vérifie que les métadonnées et les trois sections de documentation y sont réellement.
Contrôle de connaissances
Section intitulée « Contrôle de connaissances »Vérifiez que l'essentiel de ce guide est acquis. Les questions portent uniquement sur ce qui vient d'être expliqué ici.
Contrôle de connaissances
Validez vos connaissances avec ce quiz interactif
Informations
- Le chronomètre démarre au clic sur Démarrer
- Questions à choix multiples, vrai/faux et réponses courtes
- Vous pouvez naviguer entre les questions
- Les résultats détaillés sont affichés à la fin
Lance le quiz et démarre le chronomètre
Vérification
(0/0)Profil de compétences
Quoi faire maintenant
Ressources pour progresser
Des indices pour retenter votre chance ?
Nouveau quiz complet avec des questions aléatoires
Retravailler uniquement les questions ratées
Retour à la liste des certifications
À retenir
Section intitulée « À retenir »ansible-galaxy collection init namespace.namegénère la structure conforme.galaxy.yml: namespace, name, version semver,tags:obligatoire, dependencies.meta/runtime.yml:requires_ansible:obligatoire dès qu'on a un module Python.- Module Python :
DOCUMENTATION+EXAMPLES+RETURNen YAML +AnsibleModule. - FQCN depuis l'extérieur :
namespace.collection.plugin. ansible-galaxy collection buildproduit un tarball publiable.ansible-test sanity --docker defaultvalide doc + types + FQCN + PEP8.
Pour aller plus loin
Section intitulée « Pour aller plus loin »- Migration d'un rôle vers une collection : le cas fréquent où la collection n'est pas créée à vide mais reprend un rôle existant.
- Préparer l'EX374 : la certification qui évalue précisément ces compétences de développement de contenu.
- Sécurité Ansible : publier une collection engage sa chaîne d'approvisionnement, autant en connaître les règles.