Aller au contenu
Infrastructure as Code medium

Debug d'un Execution Environment cassé : version: 3 oublié, collection introuvable, deps Python invalides

11 min de lecture

Logo Ansible

Un EE peut "build OK" et pourtant être inutilisable. Le piège le plus fréquent en 2026 : oublier version: 3 dans execution-environment.yml, ansible-builder lit alors en mode v1 hérité, ignore silencieusement les sections de dépendances modernes, et produit une image qui n'a même pas ansible-core installé. Aucune erreur visible. Cette page liste les 4 bugs les plus fréquents avec leur diagnostic et leur fix.

À la fin, vous saurez détecter immédiatement un EE défectueux par smoke test, identifier la cause racine via les logs ansible-builder --verbosity 2, et conserver les modules Ansible exécutés sur la cible (ANSIBLE_KEEP_REMOTE_FILES=1) pour debug forensic.

  • Diagnostiquer un EE qui build "OK" mais ne contient pas ansible-core.
  • Reconnaître une collection Galaxy inexistante dans les logs.
  • Détecter une version Python pinnée inexistante sur PyPI.
  • Conserver les modules Ansible exécutés (ANSIBLE_KEEP_REMOTE_FILES).
  • Smoke test post-build systématique en CI.
SymptômeCause probableFix
build OK mais podman run --rm <ee> ansible --version → command not foundversion: 3 oubliéAjouter version: 3 en première ligne
Build échoue : community.does-not-exist:1.2.3 was NOT installed successfullyCollection Galaxy inexistante ou version invalideVérifier sur galaxy.ansible.com
Build échoue : Could not find a version that satisfies the requirement <pkg>==<ver>Version Python inexistante sur PyPIVérifier sur pypi.org
MODULE FAILURE à l'exécution avec python: command not foundMauvais python_interpreter côté ciblePinner ansible_python_interpreter dans inventory

Symptôme : ansible-builder build retourne Successfully tagged ... sans erreur. Mais l'EE est vide :

Fenêtre de terminal
podman run --rm local/my-ee:dev ansible --version
# /bin/sh: ansible: command not found

Diagnostic : remonter aux logs avec --verbosity 2 :

Fenêtre de terminal
ansible-builder build \
--tag local/my-ee:dev \
--container-runtime podman \
--file execution-environment.yml \
--context ./context \
--verbosity 2 2>&1 | head -20

Vous voyez :

WARNING: No 'version' key found, defaulting to schema v1
[1/2] Building image...

Cause : sans version: 3, ansible-builder utilise le schéma v1 hérité. Les sections dependencies.ansible_core, dependencies.python, dependencies.system modernes sont silencieusement ignorées. L'image est buildée à partir de la base sans ajouter ansible-core.

Fix : ajouter version: 3 en première ligne :

---
version: 3 # ← OBLIGATOIRE en 2026
images:
base_image:
name: quay.io/ansible/community-ee-minimal:latest
dependencies:
ansible_core:
package_pip: ansible-core==2.18.1
ansible_runner:
package_pip: ansible-runner==2.4.1
galaxy: requirements.yml
python: requirements.txt
system: bindep.txt

Symptôme :

[1/3] Galaxy stage:
ERROR! - community.does-not-exist:1.2.3 was NOT installed successfully:
could not find versions that match: 1.2.3 for: community.does-not-exist

Diagnostic : le nom de la collection ou sa version n'existe pas sur Galaxy.

Fenêtre de terminal
ansible-galaxy collection list community.does-not-exist 2>&1
# ou via le navigateur :
# https://galaxy.ansible.com/ui/repo/published/community/does-not-exist/

Causes fréquentes :

  • Typo dans le nom : comunity.general au lieu de community.general.
  • Version retirée : la collection a été dépréciée et la version 1.2.3 n'est plus distribuée.
  • Collection privée : nom valide mais hébergée sur Automation Hub (pas Galaxy), il faut configurer ANSIBLE_GALAXY_SERVER_LIST.

Fix : remplacer par une collection valide :

requirements.yml
collections:
- name: ansible.posix
version: 2.0.0
- name: kubernetes.core # ← collection valide
version: 5.1.1

Symptôme :

[2/3] Python deps:
ERROR: Could not find a version that satisfies the requirement kubernetes==9999.0.0
ERROR: No matching distribution found for kubernetes==9999.0.0

Diagnostic : la version pinnée n'existe pas sur PyPI.

Fenêtre de terminal
pip index versions kubernetes 2>&1 | head -5
# ou via le navigateur :
# https://pypi.org/project/kubernetes/

Causes fréquentes :

  • Typo : 31.0.O (lettre O) au lieu de 31.0.0 (chiffre 0).
  • Version trop récente non encore publiée.
  • Version retirée par l'éditeur (rare mais arrive).
  • Proxy d'entreprise qui filtre PyPI.

Fix : pinner une version réelle :

requirements.txt
kubernetes==31.0.0
PyYAML==6.0.2
jsonpatch==1.33

Symptôme : l'EE est OK mais à l'exécution :

fatal: [target]: FAILED! => {"module_stderr": "...python3: command not found", "module_stdout": "", "msg": "MODULE FAILURE\nSee stdout/stderr for the exact error", "rc": 127}

Diagnostic : l'EE embarque python3.11, mais la cible (par exemple AlmaLinux 8) n'a que python3.6. Le module Ansible transféré par l'EE essaie de lancer python3.11 qui n'existe pas sur la cible.

Investigation forensique : conserver le module sur la cible :

Fenêtre de terminal
ANSIBLE_KEEP_REMOTE_FILES=1 ansible-navigator run site.yml -vvv -m stdout

Sur la cible, le module est dans ~ansible/.ansible/tmp/ansible-tmp-*/AnsiballZ_<module>.py. Inspecter :

Fenêtre de terminal
ssh ansible@target
cd ~/.ansible/tmp/ansible-tmp-*/
head -1 AnsiballZ_copy.py
# → #!/usr/bin/python3.11 (or whatever interpreter the EE expected)

Fix : pinner explicitement l'interpréteur dans l'inventaire selon la cible :

[webservers:vars]
ansible_python_interpreter=/usr/bin/python3

Ou dans execution-environment.yml, choisir une base alignée avec les cibles :

images:
base_image:
name: quay.io/ansible/community-ee-minimal:latest # UBI 9, Python 3.11
# Si cibles AlmaLinux 8 (Python 3.6) → choisir une base UBI 8 plutôt
  1. Smoke test post-build :

    Fenêtre de terminal
    podman run --rm $TAG ansible --version | head -1

    Si vide → bug version: 3. Si OK, passer à 2.

  2. Inspecter les collections :

    Fenêtre de terminal
    podman run --rm $TAG ansible-galaxy collection list 2>&1 | head -20

    Si une collection attendue manque → bug requirements.yml.

  3. Inspecter les Python deps :

    Fenêtre de terminal
    podman run --rm $TAG pip list 2>&1 | head -30

    Si une lib attendue manque → bug requirements.txt.

  4. Tester sur cible avec ANSIBLE_KEEP_REMOTE_FILES=1 :

    Fenêtre de terminal
    ANSIBLE_KEEP_REMOTE_FILES=1 ansible-navigator run site.yml -vvv -m stdout

    Si MODULE FAILURE → inspecter ~/.ansible/tmp/... sur la cible.

  5. Inspecter le Containerfile généré :

    Fenêtre de terminal
    cat ./context/Containerfile

    Vérifier les 4 stages (base, galaxy, builder, final).

Le lab ee/debug (labs/ee/debug/) fournit un execution-environment-buggy.yml avec 3 bugs volontaires (version: 3 oublié, collection inexistante, version Python invalide). À diagnostiquer + corriger. Validation par 6 tests pytest.

  • version: 3 mandatory en première ligne, jamais oublié.
  • Smoke test post-build dans la CI : podman run --rm $TAG ansible --version.
  • --verbosity 2 minimum en CI pour capter les warnings comme « schema v1 default ».
  • Pinning par digest SHA-256 sur la base image en production : community-ee-minimal@sha256:abc....
  • Renovate / Dependabot pour bumper les pinning automatiquement (PR-driven).
  • hadolint sur le Containerfile généré pour détecter les anti-patterns.
  • Un EE peut "build OK" sans contenir ansible-core, le smoke test post-build est obligatoire.
  • version: 3 oublié → schéma v1 hérité utilisé silencieusement, 95 % des cas de debug.
  • Collection Galaxy inexistante → vérifier sur galaxy.ansible.com avec le nom + version.
  • Version PyPI inexistante → vérifier sur pypi.org.
  • ANSIBLE_KEEP_REMOTE_FILES=1 pour conserver les modules sur la cible et debug forensic.
  • Renovate pour ne jamais rater une mise à jour de sécurité sur les pinning.

Ce site vous est utile ?

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

Je maintiens +700 guides gratuits, sans pub ni tracking. Un soutien, même symbolique, m'aide à couvrir l'hébergement et à garder ces ressources gratuites. Merci pour votre appui.

Le formulaire ne s'affiche pas ? Ouvrir Ko-fi dans un onglet.

Abonnez-vous et suivez mon actualité DevSecOps sur LinkedIn