Skip to content

Ansible Configuration


Every command in this section so far has carried the same two flags: -i inventory.yaml and --private-key=alice. That repetition ends here. Ansible’s configuration file lets you set defaults for exactly these kinds of settings, once, so the rest of your commands stop needing to repeat them — which is exactly why this chapter comes last in this section, after you’ve felt the friction it solves firsthand.

What Is ansible.cfg?

ansible.cfg is the file Ansible reads for its own defaults — inventory path, private key, and a long list of other behaviors we won’t touch yet. One thing worth flagging immediately, since every file you’ve written in this course so far has been YAML: ansible.cfg is INI format, not YAML. Sections are written in square brackets, and settings underneath them are plain key = value lines:

ansible.cfg
[defaults]
some_setting = some_value

Keep that distinction in mind — it’s an easy habit to slip out of after six chapters of nothing but YAML.

Where Ansible Looks For It (And In What Order)

Ansible doesn’t just look in one place. It checks, in this exact order, and stops at the first one it finds:

  1. The ANSIBLE_CONFIG environment variable — if set, this points directly at a specific file, and wins over everything else, unconditionally.
  2. ansible.cfg in your current directory — the one you’ll build in this chapter, sitting right alongside your inventory and playbook.
  3. ~/.ansible.cfg — a personal default in your home directory.
  4. /etc/ansible/ansible.cfg — a system-wide default, shared by everyone on the machine.

The critical detail: only one of these is ever used. They are not merged together. If a higher-priority file exists, anything in a lower-priority one is ignored entirely — not combined, not partially applied, simply not read at all. This is exactly the mechanism behind this chapter’s first gotcha, covered below.

Building One From Scratch

Rather than start from a generated template, write a minimal one by hand, in the same directory as your inventory and playbook:

ansible.cfg
[defaults]
inventory = inventory.yaml
private_key_file = alice

Two settings, matching the two flags you’ve been typing all along: inventory sets the default path Ansible uses when you don’t pass -i yourself, and private_key_file sets the default private key, standing in for --private-key.

With this file in place, in the same directory:

ansible-playbook first_playbook.yaml

No -i, no --private-key — both are picked up automatically from ansible.cfg. Ad hoc commands benefit the same way:

ansible servers -m ansible.builtin.ping

A Real Limitation Worth Knowing

private_key_file sets one single default key for every connection. That works cleanly for our current inventory, since both ubuntu and fedora connect as the same user, alice. If you ever needed different hosts to authenticate as different users with different keys — bob’s key for one host, alice’s for another — this one global setting wouldn’t be enough on its own. That’s handled at the inventory level instead, with a per-host ansible_ssh_private_key_file variable overriding this default for just that one host. Not something you need today, but worth knowing the boundary of what a single config setting can actually cover.

Verifying Which Config File Is Actually Active

Given that only one config file is ever read, and it’s easy to lose track of which one that is, ansible --version tells you directly:

ansible --version
ansible [core 2.17.1]
  config file = /home/you/ansible/ansible.cfg
  ...

That config file = line is the fastest way to confirm exactly which file Ansible is actually using — especially valuable the moment something you set doesn’t seem to be taking effect, and you suspect a different file further up the lookup order is quietly winning instead.

A Note On ansible-config init

Ansible can generate a config file for you, listing every single available setting:

ansible-config init --disabled > ansible.cfg.reference

This produces a large file with every option Ansible supports, written out and commented disabled by default. It’s genuinely useful later, as a reference to browse once you know roughly what you’re looking for — but as a starting point for a beginner, it’s overwhelming: hundreds of settings, the vast majority of which you’ll never touch. Redirecting it to a separate reference file, as shown above, rather than overwriting your own minimal ansible.cfg, keeps your working config small and understandable while still giving you something to search later. Starting from the two-line file earlier in this chapter, and adding settings only once you know you need them, is the better path while you’re still learning.

Gotchas

  • INI, not YAML. Trying to write ansible.cfg with YAML indentation and colons instead of [section] headers and key = value lines is an easy, very common mistake right after this course’s heavy YAML focus.
  • First found wins — nothing merges. A leftover ~/.ansible.cfg from an old tutorial, or a forgotten ANSIBLE_CONFIG environment variable from an earlier session, can silently take priority over the project-local file you’re actually trying to edit. Always confirm with ansible --version if something isn’t behaving as expected.
  • Relative paths in ansible.cfg are resolved relative to your current working directory, not necessarily the config file’s own location. Running the same command from a different directory can pick up a different (or missing) inventory file if you’re relying on a relative path. Prefer absolute paths, or make a habit of always running Ansible commands from the same project directory.

Best Practices

  • Keep a minimal, hand-written ansible.cfg in your project directory, under version control alongside your inventory and playbooks — not in your home directory or /etc/ansible/, which apply globally and aren’t visible to anyone else running the same project.
  • Verify the active config file with ansible --version any time a setting doesn’t seem to be taking effect, rather than guessing.
  • Use ansible-config init --disabled as a reference, redirected to its own file — not as your project’s actual configuration file.
  • Add settings to ansible.cfg only once you have a concrete reason to — a small, well-understood file beats a large one copied from a template you haven’t fully read.
Last updated on