ansible.cfg, SSH and privilege escalation

Ansible · Practical · 10 min

Connection problems are the most common first obstacle, and project config makes runs reproducible.

Ansible reads one config file, the first found of: ANSIBLE_CONFIG (env var), ./ansible.cfg in the current directory, ~/.ansible.cfg, /etc/ansible/ansible.cfg. Keep an ansible.cfg in your project so everyone gets the same settings. ansible-config dump --only-changed shows what differs from defaults.

Common settings in [defaults]: inventory, remote_user, forks, roles_path, host_key_checking, stdout_callback. In [ssh_connection]: ssh_args, pipelining.

Connecting: Ansible uses your system ssh client, so everything in ~/.ssh/config applies (users, ports, ProxyJump bastions, keys), and so does your ssh-agent. Debug connection issues with ansible host -m ping -vvvv, which prints the exact ssh command.

Host key checking is on by default; for brand-new hosts, add their keys to known_hosts (e.g. ssh-keyscan) rather than disabling checking permanently.

Privilege escalation (become): become: true uses sudo by default; become_user: postgres switches to another user; become_method can be su, doas and others. Use -K (--ask-become-pass) when sudo needs a password, or store it in Vault. Apply become per task or play where needed rather than globally, so it's clear what runs as root.

Example

# ansible.cfg (project root)
[defaults]
inventory = inventory.yml
remote_user = deploy
forks = 20
roles_path = roles
stdout_callback = default
callback_result_format = yaml

[ssh_connection]
pipelining = True
ssh_args = -o ControlMaster=auto -o ControlPersist=60s

# ~/.ssh/config is honoured too, e.g.:
#   Host 10.0.*
#     ProxyJump bastion.example.com
# ansible web1 -m ansible.builtin.ping -vvvv   # shows the ssh command used

Remember

  • Project ansible.cfg wins over user and system config
  • Ansible uses OpenSSH: ssh config, agent and ProxyJump just work
  • become per task or play; -K for sudo passwords

Watch out for

  • Setting host_key_checking = False permanently and losing protection against man-in-the-middle attacks.

Check yourself

  1. You run ansible-playbook from your project directory, which contains ansible.cfg, and you also have ~/.ansible.cfg. Which is used?

Sign in to answer, see the explanations, and get this lesson back as a quick review later.

Official docs: docs.ansible.com/ansible/latest/reference_appendices/config.html