Aller au contenu
Infrastructure as Code medium

Migration rôle Ansible standalone vers collection : plugin_routing.redirect et meta/runtime.yml

10 min de lecture

Logo Ansible

En 2026, les rôles standalone Galaxy v1 sont legacy. Galaxy NG (backend Galaxy v3) ne supporte que les collections. Si vous maintenez un rôle public, il faut le migrer en collection sans casser les playbooks downstream qui l’utilisent encore avec son ancien nom court. Le mécanisme officiel : meta/runtime.yml avec plugin_routing.redirect, qui maintient la rétrocompatibilité avec un warning de dépréciation et une removal_version planifiée.

Cette page montre la migration complète d’un mini-rôle (avec un module Python custom dans library/ legacy) vers une collection conforme, avec le redirect qui permet aux deux noms (ancien court + nouveau FQCN) de fonctionner pendant la période de transition.

  • Identifier un rôle standalone candidat à la migration.
  • Initialiser la collection cible avec ansible-galaxy collection init.
  • Déplacer tasks/, handlers/, defaults/, templates/ vers roles/<name>/.
  • Déplacer un module custom de library/ vers plugins/modules/.
  • Configurer plugin_routing.redirect dans meta/runtime.yml.
  • Tester que l’ancien nom déclenche un warning mais fonctionne.
  • Planifier la removal_version (semver de la collection).

Un rôle standalone Galaxy v1 a typiquement cette structure :

my-old-role/
├── tasks/main.yml
├── handlers/main.yml
├── defaults/main.yml
├── templates/
└── library/ ← DÉPRÉCIÉ : modules custom à la racine du rôle
└── my_module.py

Avec un tasks/main.yml qui invoque le module par son nom court :

- name: Status check
my_module: # ← nom court (sans FQCN), legacy
register: status

🔍 Observation : ce format est rejeté par Galaxy NG. Le library/ n’est plus reconnu dès qu’un rôle vit dans une collection. Les modules custom doivent vivre dans plugins/modules/ au niveau de la collection.

Fenêtre de terminal
mkdir -p ansible_collections
ansible-galaxy collection init mycoll.webapp \
--init-path ansible_collections/

🔍 Observation : génère la structure conforme avec roles/, plugins/modules/, meta/runtime.yml. Les nouveaux emplacements sont prêts à recevoir le contenu migré.

Étape 2 — Déplacer le rôle dans roles/<name>/

Section intitulée « Étape 2 — Déplacer le rôle dans roles/<name>/ »
Fenêtre de terminal
mkdir -p ansible_collections/mycoll/webapp/roles/myrole/tasks
cp my-old-role/tasks/main.yml \
ansible_collections/mycoll/webapp/roles/myrole/tasks/main.yml
cp -r my-old-role/handlers \
my-old-role/defaults \
my-old-role/templates \
ansible_collections/mycoll/webapp/roles/myrole/

Adapter tasks/main.yml pour utiliser le nouveau FQCN :

- name: Status check
mycoll.webapp.my_module: # ← nouveau FQCN
register: status

🔍 Observation : à l’intérieur de la collection, on peut écrire des noms courts (my_module:) car Ansible les résout dans le contexte de la collection. Mais toujours préférer le FQCN explicite pour la lisibilité et la portabilité.

Étape 3 — Déplacer le module dans plugins/modules/

Section intitulée « Étape 3 — Déplacer le module dans plugins/modules/ »
Fenêtre de terminal
mkdir -p ansible_collections/mycoll/webapp/plugins/modules
cp my-old-role/library/my_module.py \
ansible_collections/mycoll/webapp/plugins/modules/my_module.py

Compléter le module avec les sections obligatoires si elles manquent (cf Créer une collection) :

  • DOCUMENTATION : description + options + author.
  • EXAMPLES : usage YAML copiable avec FQCN complet.
  • RETURN : structure des valeurs retournées.

🔍 Observation : ansible-test sanity exige ces 3 sections. Sans, l’import Galaxy échoue silencieusement.

Étape 4 — Configurer plugin_routing.redirect — le cœur de la migration

Section intitulée « Étape 4 — Configurer plugin_routing.redirect — le cœur de la migration »

C’est l’étape clé : permettre à un playbook qui invoque l’ancien nom court my_module: de continuer à marcher.

ansible_collections/mycoll/webapp/meta/runtime.yml :

---
requires_ansible: ">=2.18.0"
plugin_routing:
modules:
my_module: # ← l'ancien nom court
redirect: mycoll.webapp.my_module # ← le nouveau FQCN cible
deprecation:
removal_version: 2.0.0 # ← retrait planifié au bump majeur
warning_text: |
Le module 'my_module' (rôle standalone) est déprécié.
Utilisez 'mycoll.webapp.my_module' (FQCN collection).

🔍 Observation cruciale : plugin_routing.modules.<old_name>.redirect déclare la cible. deprecation: ajoute un warning au runtime mais n’échoue pas. removal_version indique quand l’alias sera retiré (semver de la collection).

Étape 5 — Tester l’ancien nom + le nouveau FQCN

Section intitulée « Étape 5 — Tester l’ancien nom + le nouveau FQCN »

Créer un playbook de test :

---
- hosts: db1.lab
collections:
- mycoll.webapp # ← déclare la collection (rétrocompat)
tasks:
- name: Test ancien nom court (avec deprecation warning)
my_module: # ← l'ancien nom, qui sera redirigé
register: legacy
- name: Test nouveau FQCN explicite
mycoll.webapp.my_module:
register: new
- ansible.builtin.copy:
dest: /tmp/migration-proof.txt
content: |
legacy: {{ legacy.msg }}
new: {{ new.msg }}
mode: "0644"

Lancer :

Fenêtre de terminal
ANSIBLE_COLLECTIONS_PATH=ansible_collections \
ansible-playbook lab.yml

Sortie attendue :

[DEPRECATION WARNING]: Le module 'my_module' (rôle standalone) est déprécié...
TASK [Test ancien nom court (avec deprecation warning)] ***
ok: [db1.lab]
TASK [Test nouveau FQCN explicite] ***
ok: [db1.lab]

🔍 Observation : les deux noms fonctionnent. L’ancien nom déclenche un warning mais ne casse pas. Les playbooks downstream peuvent migrer progressivement vers le FQCN au gré des releases mineures.

Workflow release par release :

VersionAction
1.0.0Première release de la collection avec plugin_routing.redirect actif
1.x.xReleases mineures successives. Le warning est affiché. Les downstream migrent.
2.0.0Retrait de l’alias court. removal_version atteinte → plugin_routing est retiré du meta/runtime.yml. Les playbooks qui n’ont pas migré cassent.

🔍 Observation : la removal_version doit être annoncée bien à l’avance (≥1 an typique) et documentée dans le CHANGELOG.rst comme breaking_changes au bump majeur.

Fenêtre de terminal
cd ansible_collections/mycoll/webapp/
ansible-galaxy collection build --output-path ../../../build/
# Publier sur Galaxy
ansible-galaxy collection publish \
../../../build/mycoll-webapp-1.0.0.tar.gz \
--token "$GALAXY_TOKEN"

🔍 Observation : dépublier l’ancien rôle Galaxy v1 doit se faire après une période de transition (≥6 mois recommandé). En attendant, mettre un README sur le rôle standalone avec un lien vers la collection cible.

Le lab collections/migration-role (labs/collections/migration-role/) reproduit ce parcours avec 7 tests pytest : structure conforme, plugin_routing.redirect présent, deprecation configurée, fichier preuve sur db1.lab qui montre le résultat des deux noms.

  • Renommer le module sans plugin_routing.redirect : casse tous les playbooks downstream silencieusement.
  • library/ legacy à la racine du rôle dans la collection : ignoré par Ansible. Toujours déplacer les modules dans plugins/modules/.
  • Oublier meta/runtime.yml : ansible-test sanity échoue avec No requires_ansible.
  • Pas de removal_version : pattern incomplet, on ne sait pas quand retirer l’alias.
  • Bumper en 1.x au lieu de 2.0 quand on retire l’alias : casse semver.
  • Rôles standalone = legacy. Galaxy NG (2026) ne supporte que les collections.
  • Migration = tasks/, handlers/, defaults/roles/<name>/. library/plugins/modules/.
  • plugin_routing.redirect dans meta/runtime.yml permet la rétrocompatibilité.
  • deprecation: ajoute un warning au runtime + removal_version planifie la suppression.
  • L’ancien nom continue de marcher — les downstream migrent progressivement.
  • Retrait au bump majeur : 2.0.0 retire l’alias, breaking change documenté dans CHANGELOG.rst.

Ce site vous est utile ?

Sachez que moins de 1% des lecteurs soutiennent ce site.

Je maintiens +700 guides gratuits, sans pub ni tracing. Aujourd'hui, ce site ne couvre même pas mes frais d'hébergement, d'électricité, de matériel, de logiciels, mais surtout de cafés.

Un soutien régulier, même symbolique, m'aide à garder ces ressources gratuites et à continuer de produire des guides de qualité. Merci pour votre appui.

Abonnez-vous et suivez mon actualité DevSecOps sur LinkedIn