
Les facts standards (ansible_distribution, ansible_default_ipv4, ansible_memtotal_mb, etc.) sont collectés par le module setup au début de chaque play. Les custom facts étendent ce mécanisme : on dépose un script (Bash, Python ou JSON/INI statique) dans /etc/ansible/facts.d/<nom>.fact sur la cible, et Ansible le lit à chaque gather_facts: true puis expose le résultat sous ansible_local.<nom>.
À la fin de cette page, vous saurez créer deux types de custom facts (statique INI + dynamique script Bash → JSON), les lire dans un playbook, et choisir entre custom facts, set_fact et host_vars selon le cas d'usage.
Ce que vous allez apprendre
Section intitulée « Ce que vous allez apprendre »- Déposer un custom fact statique au format INI dans
/etc/ansible/facts.d/. - Déposer un custom fact dynamique (script Bash exécutable retournant du JSON).
- Lire un custom fact via
ansible_local.<nom>dans un playbook. - Filtrer la sortie de
setuppour ne garder que lesansible_local. - Choisir entre custom facts,
set_fact,host_vars, inventaire dynamique.
Prérequis
Section intitulée « Prérequis »- Avoir lu Facts et magic vars.
- Connaître
ansible.builtin.copyetansible.builtin.file.
Pourquoi des custom facts
Section intitulée « Pourquoi des custom facts »Trois cas d'usage récurrents :
- Tagger un hôte avec son rôle métier (
web,db,cache,monitoring) sans toucher à l'inventaire centralisé. - Exposer des données spécifiques à une application : version déployée, hash du dernier commit, statut d'une migration de base.
- Centraliser des informations propriétaires : numéro de série hardware, contrat de support, compartiment cloud.
L'avantage : la vérité vit côté cible (la machine sait elle-même son rôle). Le control node n'a rien à savoir, il lit au lieu de déclarer.
Format des custom facts
Section intitulée « Format des custom facts »Ansible accepte deux formats dans /etc/ansible/facts.d/<nom>.fact :
| Format | Détection | Cas d'usage |
|---|---|---|
| Statique (INI, YAML, JSON) | Fichier non exécutable (mode 0644) | Données figées au déploiement |
| Dynamique (script) | Fichier exécutable (mode 0755) | Données qui changent (uptime, load, statut service) |
🔍 Observation cruciale : le bit exécutable (+x) est ce qui distingue les deux. Avec 0755, Ansible exécute le script et parse la sortie. Avec 0644, Ansible lit le fichier comme statique.
Custom fact INI statique
Section intitulée « Custom fact INI statique »; /etc/ansible/facts.d/server.fact (mode 0644)[meta]role = databaseenvironment = productionmanaged_by = ansible
[deployment]version = 1.4.2deployed_on = 2026-04-27Via Ansible, depuis le control node :
- name: Déployer un fact personnalisé hosts: db1.lab become: true tasks: - name: Créer /etc/ansible/facts.d/ ansible.builtin.file: path: /etc/ansible/facts.d state: directory mode: "0755"
- name: Déposer le custom fact statique ansible.builtin.copy: dest: /etc/ansible/facts.d/server.fact mode: "0644" content: | [meta] role = database environment = production [deployment] version = 1.4.2Lire le custom fact
Section intitulée « Lire le custom fact »ansible db1.lab -m ansible.builtin.setup -a "filter=ansible_local"Sortie :
ansible_local: server: deployment: version: "1.4.2" meta: environment: production role: database🔍 Observation : la structure est ansible_local.<nom_fichier_sans_.fact>.<section>.<clé>. Le fichier server.fact produit la racine ansible_local.server, les sections INI deviennent des sous-clés. Filter ansible_local isole les custom facts du reste.
Utiliser le custom fact dans un playbook
Section intitulée « Utiliser le custom fact dans un playbook »- name: Exploiter un fact personnalisé hosts: db1.lab gather_facts: true # ← obligatoire pour collecter ansible_local tasks: - name: Déposer config.txt ansible.builtin.copy: dest: /tmp/config.txt content: | Hostname: {{ inventory_hostname }} Role: {{ ansible_local.server.meta.role }} Env: {{ ansible_local.server.meta.environment }} Version: {{ ansible_local.server.deployment.version }} mode: "0644"Custom fact dynamique (script Bash → JSON)
Section intitulée « Custom fact dynamique (script Bash → JSON) »#!/bin/bash# /etc/ansible/facts.d/uptime.fact (mode 0755 EXÉCUTABLE)cat <<EOF{ "uptime_seconds": $(awk '{print int($1)}' /proc/uptime), "load_1min": "$(awk '{print $1}' /proc/loadavg)", "kernel": "$(uname -r)"}EOFVia Ansible :
- name: Déposer le fact dynamique ansible.builtin.copy: dest: /etc/ansible/facts.d/uptime.fact mode: "0755" # ← BIT EXÉCUTABLE OBLIGATOIRE content: | #!/bin/bash cat <<EOF { "uptime_seconds": $(awk '{print int($1)}' /proc/uptime), "kernel": "$(uname -r)" } EOFLecture (après setup avec filter=ansible_local) :
ansible_local: uptime: kernel: "5.14.0-..." uptime_seconds: 3242🔍 Observation : Ansible détecte automatiquement le bit +x. Si oui, exécute le script et parse la sortie comme JSON. Format alternatif accepté : YAML, INI. Le script peut être en Python, Perl, ou n'importe quel langage exécutable.
Custom facts vs alternatives
Section intitulée « Custom facts vs alternatives »| Mécanisme | Stockage | Persistance | Cas d'usage |
|---|---|---|---|
Custom fact (facts.d/*.fact) | Sur la cible | Persistant entre runs | Tag métier, rôle, version déployée |
set_fact | En mémoire pendant le play | Détruit en fin de play | Calcul intermédiaire dans un playbook |
host_vars/<host>.yml | Sur le control node (Git) | Versionné dans le repo | Config statique connue à l'avance |
| Inventaire dynamique | Source externe (Cloud, DB) | Re-collecté à chaque run | Cloud, K8s, NetBox, infra dynamique |
Décision pratique : custom facts = vérité côté cible. host_vars = vérité côté gestion. Les deux peuvent coexister. Custom facts brillent pour le bootstrap (la machine s'auto-déclare son rôle dès le cloud-init).
Pièges classiques
Section intitulée « Pièges classiques »- Bit exécutable oublié :
0644sur un script → Ansible le lit comme statique → parsing échoue (le shebang#!/bin/bashn'est pas du JSON). gather_facts: false:ansible_localreste vide. Soit activergather_facts: true, soit appelersetup:explicitement après dépôt.- Nom de fichier avec
-:lab14a-uptime.fact→ accessible viaansible_local['lab14a-uptime'](notation crochets, pas point). - Permissions de
/etc/ansible/facts.d/: doit être0755accessible en lecture par tout user qui lance Ansible (ou root sibecome: true).
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 »/etc/ansible/facts.d/<nom>.fact= chemin par défaut.- Format : INI/YAML/JSON statique OU script exécutable retournant du JSON.
- Lecture :
ansible_local.<nom>.<section>.<clé>aprèsgather_facts: true. - Bit exécutable (
mode: 0755) → script. Sinon (0644) → statique. ansible -m setup -a "filter=ansible_local"isole les custom facts.- Pas testé directement à l'EX294 mais utile en prod (tagging d'inventaire).
Mettre en pratique
Section intitulée « Mettre en pratique »Un custom fact ne se lit qu'après un aller-retour complet sur le managed node. Le lab vous fait déposer un fichier INI dans /etc/ansible/facts.d/, puis un script exécutable qui retourne du JSON, et lire les deux via ansible_local. Le contrôle vérifie les modes 0644 et 0755, seul détail qui décide si Ansible parse le fichier ou l'exécute.
Pour aller plus loin
Section intitulée « Pour aller plus loin »- register et set_fact : l'alternative au runtime quand déposer un fichier dans
facts.dest trop lourd. - Lookups : même besoin de données externes, mais résolu côté control node au lieu du managed node.
- Conditions avec when : brancher une tâche sur
ansible_localest l'usage principal d'un custom fact.