Ansible OEL 8 DevOps · OEL 8 · Setup

Ansibleansible.cfg — The Configuration File

Where Ansible looks for its config, the most useful settings to override (forks, host_key_checking, fact caching, callback plugins), and a production-ready ansible.cfg you can copy into any new project.

Ansible searches the following locations in order and uses the first match it finds (it does not merge them):

  1. $ANSIBLE_CONFIG — environment variable pointing to a specific file
  2. ./ansible.cfg — a file in your current working directory (the most common in projects)
  3. ~/.ansible.cfg — your user's home directory
  4. /etc/ansible/ansible.cfg — system-wide default (installed with Ansible)
💡 Tip: Project-level ./ansible.cfg is what you want 99% of the time. Drop one at the root of every Ansible repo and check it into git so the whole team gets the same behaviour.
INI — ansible.cfg
[defaults]
# inventory location
inventory = ./inventories/production/hosts.ini

# performance — number of parallel SSH connections
forks = 25

# host key checking — disable for dev clusters with throwaway VMs
# leave on (true) for production!
host_key_checking = False

# faster lookups: cache facts between runs (1 hour TTL)
gathering         = smart
fact_caching      = jsonfile
fact_caching_connection = ./.fact_cache
fact_caching_timeout    = 3600

# nicer output
stdout_callback = yaml
callbacks_enabled = profile_tasks, timer

# default user (overridden by inventory or playbook)
remote_user = deploy

# where to look for roles and collections
roles_path        = ./roles:./shared-roles
collections_paths = ./collections:~/.ansible/collections

# log everything
log_path = ./ansible.log

# skip the cow
nocows = True

[privilege_escalation]
become         = True
become_method  = sudo
become_user    = root
become_ask_pass = False

[ssh_connection]
# pipelining halves the number of SSH operations per task — big speedup
pipelining = True

# multiplex SSH connections so we don't reconnect for every task
ssh_args = -o ControlMaster=auto -o ControlPersist=300s -o PreferredAuthentications=publickey

# bigger transfer buffer
control_path_dir = ~/.ansible/cp
SettingDefaultWhat changes when you raise/lower it
forks5Parallel hosts per task. 25–50 is fine for most LANs.
host_key_checkingTrueTrue = secure, False = no SSH "yes/no?" prompt for new hosts
gatheringimplicitsmart = use cache if fresh, otherwise re-gather
pipeliningFalseTrue almost halves run time — turn it on
stdout_callbackdefaultyaml shows multi-line output cleanly; debug for diff'ing
retry_files_enabledTrue (legacy)Set False so failed runs don't drop *.retry files

Without pipelining, Ansible does three SSH operations per task: SFTP the module file, SSH to chmod it, then SSH again to execute. With pipelining, the module is piped directly into the SSH session and executed inline — one SSH op per task.

INI — enable pipelining
[ssh_connection]
pipelining = True
⚠ Warning: Pipelining requires requiretty to be off in /etc/sudoers on the managed nodes. OEL 8 ships with this already disabled, so it just works. Older RHEL 6 / CentOS 6 boxes may need the line Defaults !requiretty added.

Ansible can show you which config file it picked up and what every setting resolves to:

BASH — show resolved config
# show which file Ansible is reading
ansible --version | grep "config file"

# dump every setting and where it came from
ansible-config dump --only-changed

# show the full list of every option (with current value & default)
ansible-config list | head -30
✅ Tip: Run ansible-config dump --only-changed at the start of any new project — it tells you exactly what your ansible.cfg overrides vs the defaults.