RHCE study materials
RHCE study resources

Repo ansible.cfg Ignored and Collections Not Found

RHCE · Put your knowledge to work in context.

All case studies

Repo ansible.cfg Ignored and Collections Not Found

Your team manages three environments from one RHEL 9 control node. The repo contains ansible.cfg with inventory = inventory/, collections_path = ./collections and become = True. Running ansible --version from inside the repo prints config file = /etc/ansible/ansible.cfg, and ansible-inventory --graph lists hosts from the legacy /etc/ansible/hosts. Inside a Python venv, ansible-galaxy collection install community.general succeeds, but a playbook calling community.general.lvg fails with "couldn't resolve module/action". The engineer's shell exports ANSIBLE_CONFIG=/etc/ansible/ansible.cfg from an old onboarding script, and roughly half the runs start from the home directory. Root access is available, and everything must run from the venv.

1. Explain why the repository's ansible.cfg has no effect and how to confirm which settings are actually in force.

Read the worked answer

Ansible resolves exactly one config file, first match wins:

  1. ANSIBLE_CONFIG environment variable
  2. ./ansible.cfg in the current working directory
  3. ~/.ansible.cfg
  4. /etc/ansible/ansible.cfg

There are two independent causes here. The exported ANSIBLE_CONFIG points at /etc/ansible/ansible.cfg, so the env var wins outright. Separately, when the engineer runs from ~/, the repo's ansible.cfg is not in the cwd and would not be found even without the env var - Ansible does not search upward from the playbook location.

Confirm with:

  • ansible --version - the config file = line names the file actually used.
  • ansible-config dump --only-changed - shows only settings differing from defaults, which reveals whether the stale file is contributing values.
  • ansible-config view - prints the file being used, so a wrong file is obvious.

Fix by removing the export from the onboarding script and shell profile, or by shipping an explicit wrapper that exports ANSIBLE_CONFIG=/opt/ansible/ansible.cfg with an absolute path. Note inventory = inventory/ is also relative: it resolves against the cwd, not the cfg file's directory.

2. Why does `community.general.lvg` fail to resolve after a successful `ansible-galaxy collection install`, and what do you check first?

Read the worked answer

Collection lookup order is: ANSIBLE_COLLECTIONS_PATH, then collections_path/collections_paths from the effective config, then the defaults (~/.ansible/collections:/usr/share/ansible/collections). Because the effective config is /etc/ansible/ansible.cfg, the repo's collections_path = ./collections is never applied, so the install landed somewhere Ansible is not searching.

Check in this order:

  1. ansible-galaxy collection list - prints the resolved search paths and installed versions. If community.general is absent from every path, it is a path problem, not a version problem.
  2. ansible --version - the python/executable lines. If a system ansible-core outside the venv is being invoked, anything pip-installed into the venv is invisible.
  3. which -a ansible-playbook ansible-galaxy - mismatch between the two is a classic venv trap: installing with one binary and running with the other.
  4. ansible-doc -l community.general or ansible-doc community.general.lvg - confirms the module is reachable, not just present on disk.

Then make the fix deterministic: pin a collections/requirements.yml, install with ansible-galaxy collection install -r collections/requirements.yml -p ./collections using the effective config, and have CI fail if ansible-galaxy collection verify reports a mismatch. Never rely on a developer's stale ANSIBLE_CONFIG to make a path correct.

3. A cron job runs `ansible-playbook /opt/ansible/site.yml` with an empty environment and cwd `/root`. What changes make it behave identically to an interactive run?

Read the worked answer

Cron gives no login shell, so exports, PATH and cwd differ from the engineer's session. Pin everything the playbook depends on:

  • Export ANSIBLE_CONFIG=/opt/ansible/ansible.cfg (absolute) in the crontab line.
  • Call the venv binary by absolute path: /opt/venv/bin/ansible-playbook /opt/ansible/site.yml.
  • Pass -i /opt/ansible/inventory/prod explicitly, including the fact that it is a directory, not the repo-relative inventory/ string.
  • Export ANSIBLE_COLLECTIONS_PATH=/opt/ansible/collections so module resolution does not depend on the config being read correctly.
  • Set HOME (for example HOME=/root) so ~/.ansible/tmp and default collection paths resolve, and keep PATH including /usr/bin:/bin.
  • Redirect --log-path or append stdout/stderr to a file so a failure is diagnosable after the fact.

Verify by running the exact cron line under env -i interactively; if it succeeds there it will succeed under cron. Add --check for a first pass where the modules support it.