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.ymlansible-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

Bug 4 — Python interpreter mismatch côté cible

Section intitulée « Bug 4 — Python interpreter mismatch côté cible »

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 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