Aller au contenu
Infrastructure as Code medium

Le fichier ansible.cfg : ordre de chargement, sections et paramètres clés

65 min de lecture

Logo Ansible

Vous tapez ansible-playbook et le comportement diffère de celui d'un collègue qui lance le même playbook. La cause est presque toujours le même : un fichier ansible.cfg chargé sans que vous le sachiez. Ce guide explique l'ordre de chargement des configurations, les sections clés ([defaults], [privilege_escalation], [ssh_connection]), les paramètres essentiels à connaître pour le RHCE 2026, et la commande qui répond toujours à la question « quelle valeur est active ? » : ansible-config dump --only-changed.

  • L'ordre de chargement des ansible.cfg (ANSIBLE_CONFIG env > ./ansible.cfg > ~/.ansible.cfg > /etc/ansible/ansible.cfg).
  • Les sections principales d'un ansible.cfg et leur rôle.
  • Les paramètres essentiels au RHCE : inventory, host_key_checking, forks, gathering, stdout_callback, become, private_key_file.
  • Comment générer un template propre (ansible-config init --disabled).
  • Comment diagnostiquer la config active (ansible-config dump --only-changed).

Commençons par une bonne nouvelle : Ansible fonctionne sans aucune configuration. Installez-le, lancez une commande, il tourne avec ses valeurs par défaut. Vous pouvez le vérifier dans un répertoire vierge, la ligne config file le dit sans détour.

ansible --version dans un répertoire sans configuration
ansible [core 2.20.1]
config file = None

Configurer Ansible ne consiste donc pas à le rendre fonctionnel, mais à arrêter de répéter les mêmes options à chaque commande. C'est un confort qui devient vite une nécessité.

Prenons un projet avec son inventaire dans inventory/hosts.yml. Sans configuration, Ansible ne sait pas où le chercher, et vous le dit :

Sans ansible.cfg, l'inventaire du projet est ignoré
$ ansible all -m ansible.builtin.ping
[WARNING]: No inventory was parsed, only implicit localhost is available
[WARNING]: provided hosts list is empty, only localhost is available.

Il faut donc désigner l'inventaire à la main, à chaque appel, avec -i inventory/hosts.yml. Ajoutez-y l'utilisateur SSH avec -u, la clé privée avec --private-key, et la commande devient longue à taper et facile à rater.

Un fichier ansible.cfg de deux lignes suffit à supprimer cette répétition.

ansible.cfg, à la racine du projet
[defaults]
inventory = ./inventory/hosts.yml

La même commande fonctionne alors telle quelle, et ansible --version confirme que le fichier est bien pris en compte.

Avec ansible.cfg, l'inventaire est trouvé tout seul
$ ansible --version | head -2
ansible [core 2.20.1]
config file = /home/bob/projets/mon-projet/ansible.cfg
$ ansible all -m ansible.builtin.ping
localhost | SUCCESS => { ... }

ansible.cfg suit le format INI, celui des vieux fichiers de configuration Windows, pas du YAML. La syntaxe tient en deux règles : les sections s'écrivent entre crochets, comme [defaults], et chaque paramètre prend la forme clé = valeur. Les commentaires commencent par # ou ;.

Ne cherchez pas à écrire ce fichier de mémoire ni à le copier d'un forum. Ansible sait générer un modèle complet et commenté, et la section « Générer un template propre » plus bas montre comment.

Dans l'immense majorité des cas, à la racine de votre projet, à côté de vos playbooks, et versionné avec eux. C'est ce qui garantit que toute l'équipe travaille avec les mêmes réglages, et qu'un playbook se comporte pareil sur votre poste et en intégration continue.

Trois autres emplacements existent, et Ansible les examine dans un ordre précis. C'est le sujet de la section suivante, et la source de la mauvaise surprise la plus fréquente sur ce fichier.

Ansible cherche son fichier de configuration dans cet ordre exact, et s'arrête au premier trouvé. C'est crucial : un fichier ignoré n'est jamais merge avec un autre, c'est tout l'un, ou tout l'autre.

PrioritéSourceQuand l'utiliser
1Variable d'env ANSIBLE_CONFIG=/chemin/ansible.cfgPipeline CI/CD, scripts qui veulent forcer une config
2./ansible.cfg dans le répertoire courantConfig par projet, le cas standard
3~/.ansible.cfgConfig personnelle valable pour tous vos projets
4/etc/ansible/ansible.cfgConfig système installée par un paquet distrib

Le piège classique : vous avez un ~/.ansible.cfg perso qui définit inventory = ~/.ansible/hosts. Vous cd dans un projet qui a son propre ./ansible.cfg. Le fichier projet gagne et votre inventaire perso est ignoré complètement. Il n'y a pas de fusion section par section. Si une valeur n'est pas dans le fichier projet, c'est la valeur par défaut Ansible qui s'applique, pas celle de votre ~/.ansible.cfg.

Quand un comportement vous étonne, première commande à taper : ansible-config dump --only-changed. Elle affiche tous les paramètres modifiés par rapport aux défauts Ansible, avec la source de chaque valeur.

ansible-config dump --only-changed (sortie réelle sur le lab)
ANSIBLE_PIPELINING(/home/bob/Projets/lab-ansible/ansible.cfg) = True
CACHE_PLUGIN(/home/bob/Projets/lab-ansible/ansible.cfg) = jsonfile
CACHE_PLUGIN_CONNECTION(/home/bob/Projets/lab-ansible/ansible.cfg) = ./.ansible_facts
CACHE_PLUGIN_TIMEOUT(/home/bob/Projets/lab-ansible/ansible.cfg) = 7200
CALLBACKS_ENABLED(/home/bob/Projets/lab-ansible/ansible.cfg) = ['ansible.posix.profile_tasks', 'ansible.posix.timer']
CONFIG_FILE() = /home/bob/Projets/lab-ansible/ansible.cfg
DEFAULT_BECOME(/home/bob/Projets/lab-ansible/ansible.cfg) = True
DEFAULT_BECOME_METHOD(/home/bob/Projets/lab-ansible/ansible.cfg) = sudo
DEFAULT_FORKS(/home/bob/Projets/lab-ansible/ansible.cfg) = 10
DEFAULT_GATHERING(/home/bob/Projets/lab-ansible/ansible.cfg) = smart
DEFAULT_HOST_LIST(/home/bob/Projets/lab-ansible/ansible.cfg) = ['/home/bob/Projets/lab-ansible/inventory/hosts.yml']
DEFAULT_PRIVATE_KEY_FILE(/home/bob/Projets/lab-ansible/ansible.cfg) = /home/bob/Projets/lab-ansible/ssh/id_ed25519
DEFAULT_REMOTE_USER(/home/bob/Projets/lab-ansible/ansible.cfg) = ansible
DEFAULT_STDOUT_CALLBACK(/home/bob/Projets/lab-ansible/ansible.cfg) = yaml
HOST_KEY_CHECKING(/home/bob/Projets/lab-ansible/ansible.cfg) = False
INTERPRETER_PYTHON(/home/bob/Projets/lab-ansible/ansible.cfg) = /usr/bin/python3.12
PAGER(env: PAGER) = less
RETRY_FILES_ENABLED(/home/bob/Projets/lab-ansible/ansible.cfg) = False

Trois choses à lire dans cette sortie. CONFIG_FILE() indique le fichier ansible.cfg détecté, vous savez immédiatement lequel a été chargé. La source entre parenthèses précise pour chaque paramètre s'il vient du fichier (chemin) ou d'une variable d'environnement (env:). Seuls les paramètres modifiés sont listés, les défauts Ansible ne polluent pas la sortie.

Pour le dump complet (utile au moins une fois pour explorer ce qui existe) : ansible-config dump. Vous obtenez les 400+ paramètres de la config Ansible, avec leur valeur effective et leur source.

Un ansible.cfg contient des sections au format INI. Voici la liste complète des sections disponibles, capturée par ansible-config init --disabled | grep '^\[' :

[defaults]
[privilege_escalation]
[persistent_connection]
[connection]
[colors]
[selinux]
[diff]
[galaxy]
[inventory]
[netconf_connection]
[jinja2]
[tags]

En pratique, trois sections couvrent 90 % des cas : [defaults], [privilege_escalation] et [ssh_connection]. Les autres servent des besoins pointus, personnalisation des couleurs, plugins NETCONF pour les équipements réseau, réglages SELinux.

Une remarque sur cette liste, qui surprend à la première lecture : [ssh_connection] n'y figure pas, alors que c'est la section que vous écrirez le plus souvent après [defaults]. La raison tient à l'origine des paramètres. Les sections listées ci-dessus viennent de la configuration du moteur, tandis que [ssh_connection] appartient au plugin de connexion SSH, documenté à part. Elle est parfaitement valide, et porte l'essentiel des réglages SSH : sur ansible-core 2.20.1, le plugin ssh y expose 21 options, contre 2 seulement dans [connection]. Pour la consulter, la commande est ansible-config list -t connection.

Voici l'ansible.cfg du lab (que vous retrouvez sur tous les projets de la formation), avec une explication ligne par ligne des paramètres clés. C'est la base à connaître pour le RHCE.

ansible.cfg du lab
[defaults]
inventory = ./inventory/hosts.yml
host_key_checking = False
retry_files_enabled = False
forks = 10
callback_result_format = yaml
callbacks_enabled = ansible.posix.profile_tasks, ansible.posix.timer
gathering = smart
fact_caching = jsonfile
fact_caching_connection = ./.ansible_facts
fact_caching_timeout = 7200
remote_user = ansible
private_key_file = ./ssh/id_ed25519
interpreter_python = /usr/bin/python3.12
pipelining = True
[privilege_escalation]
become = True
become_method = sudo
become_ask_pass = False

inventory désigne le fichier ou répertoire d'inventaire à utiliser par défaut. Sans ce paramètre, vous devez passer -i hosts.yml à chaque commande. Avec, ansible all -m ping trouve directement les hôtes.

host_key_checking = False désactive la vérification de l'empreinte SSH du serveur. C'est pratique sur un lab où les VMs sont reprovisionnées souvent (l'empreinte change), dangereux en prod où vous voulez détecter un MITM. Pour les labs, c'est OK ; pour la prod, gardez à True et gérez ~/.ssh/known_hosts correctement.

forks = 10 définit le nombre d'hôtes traités en parallèle. Le défaut Ansible est 5, sur un lab de 4 VMs, 10 suffit largement. Sur une fleet de 100 serveurs, montez à 50 pour réduire la durée d'exécution.

gathering = smart contrôle la collecte des facts. Trois valeurs : implicit (collecte à chaque play, défaut), explicit (uniquement si gather_facts: true est explicite), smart (collecte si pas déjà en cache). Le mode smart couplé à fact_caching divise par 5 à 10 le temps total sur des playbooks répétitifs.

fact_caching = jsonfile active la mise en cache des facts collectés. Combiné à fact_caching_connection (chemin du cache) et fact_caching_timeout (durée de validité, ici 7200 s = 2 h), Ansible évite de re-collecter ~100 facts par hôte à chaque run. Énorme gain sur fleet de 50+ serveurs.

callback_result_format = yaml change l'affichage de la sortie d'Ansible : le callback par défaut affiche du JSON inline difficile à lire, cette option le reformate en YAML structuré multi-lignes. Recommandé pour tout poste de dev. Elle remplace l'ancien stdout_callback = yaml : le plugin community.general.yaml a été supprimé en community.general 12.0.0, au profit de l'option result_format du callback ansible.builtin.default (depuis ansible-core 2.13). Dans le fichier ansible.cfg, la clé exacte est callback_result_format et les seules valeurs acceptées sont yaml ou json.

callbacks_enabled active des callbacks supplémentaires. ansible.posix.profile_tasks ajoute un récap des durées par tâche en fin de play (utile pour identifier ce qui ralentit). ansible.posix.timer affiche le temps total. Voir section sur les callbacks.

remote_user = ansible est le user SSH par défaut. Évite de l'écrire dans chaque playbook ou inventaire.

private_key_file désigne la clé privée SSH à utiliser. Indispensable quand vous avez plusieurs paires de clés et que celle d'Ansible n'est pas dans ~/.ssh/id_rsa.

interpreter_python = /usr/bin/python3.12 force l'interpréteur Python côté managed nodes. Sans ce paramètre, Ansible essaie d'auto-détecter, ce qui peut basculer vers python3.6 sur des distributions hétérogènes. À cibler explicitement quand vos managed nodes sont uniformes.

pipelining = True active le SSH pipelining : Ansible envoie le module Python directement via stdin de SSH plutôt que de passer par un fichier temporaire. Gain de 30-50 % sur les playbooks lourds. Compatible avec requiretty désactivé sur les nodes (cas par défaut sur AlmaLinux 10).

Section [privilege_escalation], élévation de privilèges

Section intitulée « Section [privilege_escalation], élévation de privilèges »

become = True active par défaut l'élévation de privilèges (sudo) pour toutes les tâches du play. Vous pouvez ensuite désactiver localement avec become: false sur une tâche qui n'a pas besoin de root. Inverse : become = False (défaut Ansible) impose d'écrire become: true partout où vous voulez sudo.

become_method = sudo définit l'outil d'élévation. Alternatives : su, doas, pbrun, runas (Windows). Sur RHEL/AlmaLinux/Ubuntu, sudo est universel.

become_ask_pass = False convient quand le user est configuré avec NOPASSWD: ALL côté managed node (cas du lab). Si vos cibles requièrent un mot de passe sudo, mettez True et Ansible vous le demandera au lancement.

Cette section contrôle le plugin de connexion SSH. Vous y mettrez typiquement :

[ssh_connection]
ssh_args = -o ControlMaster=auto -o ControlPersist=60s
control_path = ~/.ssh/cm-%%r@%%h:%%p
pipelining = True

ssh_args impose des options SSH supplémentaires (utile pour proxy jump, alias d'hôtes, multiplexage). control_path définit l'emplacement du socket de multiplexage SSH. Sur la plupart des labs, les défauts conviennent, vous n'avez qu'à activer pipelining.

Pour démarrer un nouveau projet Ansible avec un ansible.cfg à jour et commenté, lancez :

Fenêtre de terminal
ansible-config init --disabled > ansible.cfg

La commande génère un fichier avec tous les paramètres possibles, chacun commenté (préfixé par ;) et documenté :

Extrait du template ansible-config init --disabled
[defaults]
# (boolean) By default, Ansible will issue a warning when received from a task
# action (module or action plugin). These warnings can be silenced by adjusting
# this setting to False.
;action_warnings=True
# (boolean) When enabled, this option allows conditionals with non-boolean results
; to be used. A deprecation warning will be emitted in these cases.
;allow_broken_conditionals=False
# (path) The default root path for Ansible config files on the controller.
;home=~/.ansible

Vous décommentez ensuite uniquement les paramètres dont vous avez besoin, la grande majorité reste aux défauts Ansible. C'est la méthode propre pour démarrer un projet, plutôt que de copier-coller un ansible.cfg trouvé sur StackOverflow.

Chaque paramètre ansible.cfg a sa variable d'environnement équivalente, préfixée ANSIBLE_. Pratique pour des overrides ponctuels en CI ou sur la ligne de commande.

Paramètre cfgVariable d'env
inventoryANSIBLE_INVENTORY
host_key_checkingANSIBLE_HOST_KEY_CHECKING
forksANSIBLE_FORKS
stdout_callbackANSIBLE_STDOUT_CALLBACK
private_key_fileANSIBLE_PRIVATE_KEY_FILE
becomeANSIBLE_BECOME
gatheringANSIBLE_GATHERING

Exemple : ANSIBLE_FORKS=50 ansible-playbook site.yml boost ponctuellement le parallélisme sans toucher au fichier. Le précédence est : ligne de commande > variables d'env > ansible.cfg. Cela rend les variables d'env idéales pour les pipelines CI/CD.

Trois surprises reviennent régulièrement sur ce fichier. Les deux premières font qu'une configuration pourtant présente n'est pas appliquée, ce qui est déroutant tant qu'on ne connaît pas la règle.

  • Un seul ansible.cfg est chargé, jamais deux. Un fichier placé dans ./roles/nginx/ansible.cfg est ignoré quand vous lancez ansible-playbook depuis la racine du projet. La configuration par rôle ou par sous-répertoire n'existe pas dans Ansible.
  • Un répertoire ouvert en écriture à tous fait ignorer le fichier. Ce sont les permissions du répertoire courant qui comptent, pas celles du fichier : un ansible.cfg en 0666 est chargé sans broncher, alors que le même fichier dans un répertoire en 0777 est écarté. Ansible le dit explicitement, Ansible is being run in a world writable directory, ignoring it as an ansible.cfg source, et ansible --version affiche alors config file = None. La protection vise l'injection d'une configuration malveillante par un autre utilisateur de la machine.
  • Les booléens acceptent plusieurs écritures. True, true, yes et 1 valent tous vrai, False, false, no et 0 valent faux : vérifié sur ansible-core 2.20.1, où host_key_checking = no et host_key_checking = false produisent le même HOST_KEY_CHECKING = False. Choisissez une forme et tenez-vous-y, la cohérence facilite la relecture. Ne confondez pas avec le YAML de vos playbooks, où la convention est true et false en minuscules.
  • Ansible cherche ansible.cfg dans cet ordre : ANSIBLE_CONFIG > ./ansible.cfg > ~/.ansible.cfg > /etc/ansible/ansible.cfg. Premier trouvé gagne, pas de merge.
  • ansible-config dump --only-changed est votre outil de diagnostic numéro un, il montre quel paramètre est actif et d'où il vient.
  • Trois sections couvrent 90 % des cas : [defaults], [privilege_escalation], [ssh_connection].
  • Les paramètres essentiels au RHCE : inventory, host_key_checking, forks, gathering, stdout_callback, become, private_key_file, interpreter_python.
  • Pour démarrer un nouveau projet : ansible-config init --disabled > ansible.cfg. Décommentez uniquement les paramètres nécessaires.
  • Chaque paramètre a son équivalent variable d'env ANSIBLE_*, prioritaire sur le fichier, utile en CI/CD.

Lire l'ordre de chargement ne suffit pas à l'ancrer, il faut voir un fichier l'emporter sur un autre. Ce lab vous fait écrire un ansible.cfg de projet, confirmer les valeurs réellement actives avec ansible-config dump, puis les écraser par une variable d'environnement ANSIBLE_* pour observer la précédence en direct. Vous terminez en activant un callback de sortie, ce qui change l'affichage sans toucher au playbook.

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