Skip to content

Ansible: ansible.cfg in project_dir is never loaded by ansible-lint (roles_path silently ignored) #58

Description

@matthew-on-git

Type: bug · Area: ansible, project discovery, working directory

Closely related to #53 (subdirectory project configs ignored), which was closed recently — this looks like the Ansible-shaped gap in the same problem.

Summary

make _lint runs ansible-lint from the repo root. Ansible resolves ansible.cfg relative to the current working directory, and setting project_dir: in .ansible-lint does not change the cwd for that resolution. So a project whose Ansible tree lives in a subdirectory never has its ansible.cfg loaded during lint, and any roles_path in it silently has no effect.

The result is a syntax-check failure that reads like the role is missing, when it is present and ansible-playbook resolves it correctly.

Environment

  • Image: ghcr.io/devrail-dev/dev-toolchain:v1
  • .devrail.yml: languages: [ansible]
  • .ansible-lint: profile: production, project_dir: ansible/

Layout (no Ansible content at repo root):

ansible/
├── ansible.cfg          # roles_path = roles:../.galaxy-roles
├── inventory/mfsoho/hosts
├── playbooks/site.yml   # - role: nfs_share_perms
└── roles/nfs_share_perms/

Reproduction

$ make _lint
syntax-check[specific]: the role 'nfs_share_perms' was not found in
  /workspace/ansible/playbooks/roles:/workspace/ansible/.ansible/roles:
  /root/.ansible/roles:/usr/share/ansible/roles:/etc/ansible/roles:
  /workspace/ansible/playbooks
ansible/playbooks/site.yml:13:7

Note the search path contains neither /workspace/ansible/roles nor /workspace/.galaxy-roles, both of which ansible/ansible.cfg declares.

Isolating it — same tree, three invocations inside the container:

invocation result
cd /workspace && ansible-lint fails, role not found
cd /workspace/ansible && ansible-lint passes
cd /workspace && ANSIBLE_CONFIG=/workspace/ansible/ansible.cfg ansible-lint passes

And ansible-playbook itself has no trouble — from ansible/:

$ ansible-config dump | grep DEFAULT_ROLES_PATH
DEFAULT_ROLES_PATH(/workspace/ansible/ansible.cfg) = ['/workspace/ansible/roles', '/workspace/.galaxy-roles']

So the config is valid and is honoured by Ansible; it is only the lint invocation's working directory that loses it.

To rule out a permissions cause: /workspace is 755 root, so this is not Ansible's world-writable-directory config-skipping behaviour.

Impact

Projects have to work around it. Neither option is good:

  • Set ANSIBLE_ROLES_PATH in CI — but then local make check still fails, and make check is the documented gate.
  • Symlink ansible/playbooks/roles -> ../roles (what I ended up doing) — works everywhere with no env coupling, but it is a workaround for a path the tool should already know about.

Suggested fix

When .ansible-lint declares project_dir, either run ansible-lint with that as cwd, or export ANSIBLE_CONFIG=<project_dir>/ansible.cfg when that file exists. Option C above shows the latter is sufficient.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions