Red Hat Certified Engineer (RHCE) #3: Config Files and Connectivity — ansible.cfg, ssh, become

10 min read

In #2 Inventory we defined which hosts Ansible would manage. This time we settle how Ansible connects to those hosts and with what privileges it does its work. At the center of that sit the configuration file ansible.cfg, SSH key-based connections, and become, which handles privilege escalation. All three have to be in place before a playbook written on the control node runs the way you intended on the managed node.

ansible.cfg is the switchboard that changes nearly every default behavior of Ansible. Which inventory to use, which user to connect as, how to elevate privileges — all of it lives in this one file. The exam regularly serves up the pattern of placing a dedicated ansible.cfg in each project directory and configuring become alongside it, so let’s memorize the lookup precedence and the key entries exactly.

ansible.cfg lookup precedence #

When Ansible runs, it searches for a config file in a fixed order and uses only the first one it finds. Even if files exist in several places, they are not merged — a higher-precedence file completely masks the rest. The search order is as follows.

PrecedenceLocationDescription
1ANSIBLE_CONFIG environment variableThe file at the path named in the variable
2./ansible.cfgThe current directory where you ran the command
3~/.ansible.cfgThe user’s home directory
4/etc/ansible/ansible.cfgThe system-wide default

The point that ties directly to the exam is that the current directory’s ./ansible.cfg beats both the home and system settings. So if you put a dedicated ansible.cfg in each project directory, the settings you intended always apply while you run commands from that directory. When the exam says “work in this directory,” creating an ansible.cfg there is the textbook move.

You can check which config file is actually in effect with the following command.

Check active config
ansible --version

The config file line in the output shows the path of the file that was actually read. If you see a path other than the ansible.cfg you intended, recheck the current directory or the environment variable.

Security note: current-directory config #

For Ansible to read the current directory’s ansible.cfg, that directory must be unwritable by other users. An ansible.cfg in a world-writable directory is ignored for security reasons, and a warning is printed. A project directory you created yourself in the exam is usually fine, but when you work in a shared path it’s safer to check the permissions.

Key ansible.cfg settings #

The config file is an INI structure that lists entries in key = value form under [sections]. The two sections used most often in RHCE are [defaults] and [privilege_escalation].

The [defaults] section #

[defaults] defines the most basic behavior — inventory location, the connecting user, the key-checking policy, and so on.

KeyRole
inventoryPath to the inventory file or directory to use
remote_userThe default user to connect as on the managed node
host_key_checkingWhether to verify the SSH host key. false skips the first-connection prompt
roles_pathPath to the directory where roles are found
ask_passWhether to prompt for the SSH password on connection
forksNumber of hosts to process at once (parallelism)

Let’s look at each entry a little more closely.

  • inventory. Setting this value means you always use the same inventory even without the -i option. Pointing it at the project directory’s inventory file keeps commands short.
  • remote_user. In the exam you usually connect as a regular user and then elevate privileges with become, so you specify a working account rather than root.
  • host_key_checking. This blocks the host-key verification prompt that appears the first time you connect to a freshly created managed node, so the playbook doesn’t stall. In production it’s safer to leave it on, but in lab environments it’s commonly set to false.
  • roles_path. To have Ansible find the roles covered in #11 Roles in a specific directory inside the project, you set this value.

The [privilege_escalation] section #

[privilege_escalation] defines how you do work with root privileges after connecting as a regular user. All become-related settings gather here.

KeyRole
becomeWhether to turn privilege escalation on by default (true/false)
become_methodThe escalation method. The default is sudo
become_userWhich user you become after escalating. The default is root
become_ask_passWhether to prompt for the become password
  • Setting become = true runs every task in the playbook with escalated privileges by default. Since most RHCE work — package installs, service management — requires root, this value is often left on.
  • become_method. On RHEL you almost always use sudo.
  • become_user. When only a specific task needs to become a different account, you set it separately at the task level and usually leave the global default at root.
  • become_ask_pass. If sudo requires a password, set this to true, or supply it with the -K option when running the command.

SSH key-based connections #

Ansible connects to managed nodes over SSH. To run playbooks automatically without typing a password every time, you register the SSH public key on the managed node and set up key-based authentication. This is the first step of building an RHCE environment.

1) Generate a key pair #

If there’s no key pair on the control node, create one first.

Generate key pair
ssh-keygen

Generating it with the default paths (~/.ssh/id_rsa, ~/.ssh/id_rsa.pub) and an empty passphrase lets you connect automatically with no further input.

2) Distribute the public key #

Copy the generated public key to each managed node.

Copy public key
ssh-copy-id devops@node1.example.com

ssh-copy-id automatically appends the public key to the target host’s ~/.ssh/authorized_keys. You enter the password just once at this step, and from then on you connect with the key. If there are several managed nodes, run it the same way on each host.

3) Specify the connecting user #

Which user Ansible connects as is set with remote_user in ansible.cfg, or per host with ansible_user in the inventory.

inventory
[webservers]
node1.example.com ansible_user=devops
node2.example.com ansible_user=devops

The inventory’s ansible_user applies only to that host and takes precedence over remote_user in ansible.cfg. It’s useful when the connecting account differs from host to host.

Escalating privileges with become #

The account you connect with via the key is usually a regular user. Work that needs root privileges — installing packages, restarting services, editing system files — is handled by borrowing sudo privileges with become.

There are three levels at which you can turn become on.

1) Global setting in ansible.cfg #

The become = true in [privilege_escalation] that we saw earlier has the broadest scope. Every playbook and ad-hoc command you run from this directory escalates privileges by default.

2) Setting at the play or task level #

Inside a playbook, you can specify become for an entire play or for an individual task.

become at play and task level
- name: Configure the web server
  hosts: webservers
  become: true
  tasks:
    - name: Install httpd
      ansible.builtin.dnf:
        name: httpd
        state: present

    - name: Check logs as a regular user
      ansible.builtin.command: whoami
      become: false

Putting become: true on a play escalates privileges for every task in that play, and setting only a specific task to become: false runs that one task as the original account. A per-task become overrides the play setting, so you only specify the tasks that need an exception.

To run a specific task as an account other than root, attach become_user to the task.

Set become_user
    - name: Work as the postgres user
      ansible.builtin.command: psql -c "SELECT 1"
      become: true
      become_user: postgres

3) Setting via command-line options #

When you want to elevate privileges one-off without touching the config file, use command-line options.

Escalate from the command line
ansible-playbook site.yml --become -K
  • --become (or -b). Turns on privilege escalation for this run only.
  • -K (--ask-become-pass). Prompts once for the sudo password. Needed when the target account’s sudo requires a password.

If the managed node’s sudo is configured with NOPASSWD to work without a password, you don’t even need -K. In exam environments the working account often has passwordless sudo set up in advance, but if not, supply the password with -K or become_ask_pass.

Connection test #

Once you have the config, the keys, and become in place, check that the connection actually works. The ping module is the fastest tool for the job.

Connection test
ansible all -m ping

Ansible’s ping module isn’t ICMP — it’s a module that connects over SSH and even checks that Python works. If every host returns a response like the following, the connection is healthy.

Output
node1.example.com | SUCCESS => {
    "changed": false,
    "ping": "pong"
}

To also verify privilege escalation, turn become on and check the current user.

Verify privilege escalation
ansible all -m command -a "whoami" --become

If every host returns root, become is working correctly. If you get UNREACHABLE, check the SSH key or ansible_user; if you get a sudo-related error, check the become settings or whether -K is needed.

Full project example #

Let’s tie everything we’ve covered into a single project. Placing ansible.cfg and inventory together in the working directory is the exam’s standard form.

Write ansible.cfg as follows.

ansible.cfg
[defaults]
inventory = ./inventory
remote_user = devops
host_key_checking = false
roles_path = ./roles

[privilege_escalation]
become = true
become_method = sudo
become_user = root
become_ask_pass = false

The inventory in the same directory looks like this.

inventory
[webservers]
node1.example.com
node2.example.com

[dbservers]
node3.example.com

When you run commands from this directory, ./ansible.cfg is applied automatically, so the intended inventory and privilege escalation work exactly as is — without the -i option or --become.

Check connection and privileges
ansible all -m ping
ansible all -m command -a "whoami"

If whoami returns root everywhere, it means ansible.cfg’s become = true was applied. Gathering the config and inventory into a single project directory means the same environment is reproduced every time inside that directory.

Exam points #

  • Per-project ansible.cfg. The exam usually designates a specific working directory. Creating an ansible.cfg there and spelling out inventory, remote_user, and become is the textbook approach. ./ansible.cfg beats both the home and system settings.
  • become settings. Since most RHCE work demands root privileges, the configuration with become = true in [privilege_escalation] comes up often. If only a specific task needs an exception, adjust it at the task level with become: false or become_user.
  • Connection check. Right after building the environment, check the SSH connection with ansible all -m ping and privilege escalation with whoami plus --become.
  • Checking the applied config. The habit of confirming with the config file line of ansible --version that the ansible.cfg actually read is the file you intended prevents small mistakes.
  • host_key_checking. It’s often set to false so the host-key prompt on a new managed node doesn’t stall the playbook.

Wrap-up #

What this post locked in:

  • ansible.cfg precedence. Searched in the order ANSIBLE_CONFIG environment variable, current directory, home directory, /etc/ansible — only the first file found is applied
  • Key settings. [defaults]’s inventory, remote_user, host_key_checking, roles_path, and [privilege_escalation]’s become, become_method, become_user, become_ask_pass
  • SSH key connection. Make a key with ssh-keygen and distribute it with ssh-copy-id; specify the connecting account with remote_user or the inventory’s ansible_user
  • become. Three ways to escalate sudo privileges — globally in ansible.cfg, at the play and task levels, and via command-line --become -K
  • Connection test. Check the connection with ansible all -m ping and privilege escalation with whoami plus --become

Next — ad-hoc commands #

Now that connectivity and privileges are in place, let’s run modules on the fly before we write a playbook.

In #4 ad-hoc commands: running modules on the fly, we’ll cover running a module in one line with the ansible command, the modules used most often (command, shell, copy, file, dnf, service), and the feel for putting ad-hoc to work for quick checks and one-off jobs.

X