I’ve started seeing a weird behavior with ansible-lint quite recently. Specifically, that it seems it started to resolving symlinks to their destination.
While it can be fine in most cases, it is very confusing in CI, where instead of installing role as it should be installed, we symlink it from CI-prepared directory to DEFAULT_ROLES_PATH
We make a symlink from /home/zuul/src/opendev.org/openstack/ansible-role-httpd/ to /etc/ansible/roles/httpd/ (as we expect users to have role installed under it’s proper name).
Then, our example playbook tries to be quite abstract, ie:
---
- name: Installing Apache Web Server
hosts: httpd
roles:
- role: "{{ playbook_dir | dirname | basename }}"
So while we run ansible-lint /etc/ansible/roles/httpd/examples/playbook.yml it actually seems to launch “original” location: /home/zuul/src/opendev.org/openstack/ansible-role-httpd/examples/playbook.yml
Full output is like this:
+ /opt/ansible-runtime/bin/ansible-lint /etc/ansible/roles/httpd/examples/playbook.yml -c /home/zuul/src/opendev.org/openstack/openstack-ansible/.ansible-lint
WARNING: PATH altered to include /opt/ansible-runtime/bin, /opt/ansible-runtime/bin :: This is usually a sign of broken local setup, which can cause unexpected behaviors.
[DEPRECATION WARNING]: DEFAULT_GATHER_SUBSET option, the module_defaults
keyword is a more generic version and can apply to all calls to the
M(ansible.builtin.gather_facts) or M(ansible.builtin.setup) actions, use
module_defaults instead. This feature will be removed from ansible-core in
version 2.18. Deprecation warnings can be disabled by setting
deprecation_warnings=False in ansible.cfg.
WARNING Listing 1 violation(s) that are fatal
syntax-check[specific]: the role 'ansible-role-httpd' was not found in /home/zuul/src/opendev.org/openstack/ansible-role-httpd/examples/roles:/root/.cache/ansible-compat/8cbc9d/roles:/etc/ansible/roles:/etc/ansible/roles/ceph-ansible/roles:/home/zuul/src/opendev.org/openstack/ansible-role-httpd/examples
/home/zuul/src/opendev.org/openstack/ansible-role-httpd/examples/playbook.yml:5:7
# Rule Violation Summary
1 syntax-check profile:min tags:core,unskippable
Failed: 1 failure(s), 0 warning(s) on 1 files.
Yeah, I think that the bug report mentioned is related. I think we’ve started observing the issue between Jan 14 and Feb 17.
And sure, adjusting ANSIBLE_ROLES_PATH would sort it out. But the point is kind of to set the CI in a way that most consumers will use roles as well, so we’d love to avoid this workaround.
Another workaround would be in our case to leave an example playbook alone, and supply molecule a different converge file. As this approach with role: "{{ playbook_dir | dirname | basename }}" was to satisfy both molecule and ansible-lint which we execute separately.
At this moment there are no plans to change this because only by resolving the paths we can get a normalized file path that we can compare with others and avoid duplicates. Also there are tools that fail to resolve symlinked paths so resolving them gives a better experience.
If the very long path annoys you, you can probably ensure that your preinstalled dependencies are copied inside the current project because in this case ansible-lint will report paths relative to project directory.
Zuul does prepare for us repositories in /home/user/zuul/repo/ansible-role-$role_name
So what we are doing, is symlinking from that path to ANSIBLE_ROLES_PATH with renaming from ansible-role-$role_name to expected $role_name
Thus eventually you would get a completely different role name depending if you execute molecule or ansible. And then also a difference if you run with zuul or locally, where installation will be handled by galaxy.
With that such approach allows to test current role/collection dependencies as well, as zuul can include other patches and speculatively merge them in CI jobs… I think we’ve found a workaround this somehow for now though, but it’s just a bit unfortunate that behavior is different.