Solved: ansible-lint on macOS “FATAL: Ansible CLI and python module versions do not match.”

My Problem

While attempting to run ansible-lint on macOS, I received the error:

FATAL: Ansible CLI (2.10.8) and python module (2.11.5) versions do not match. This indicates a broken execution environment.

My Solution

I ran the following destructive command, but before you even think about running it yourself, please familiarize yourself with what it will do:

brew link --overwrite ansible

The Long Story

While attempting to lint some Ansible .yml files, I realized that the specific macOS machine I was on didn’t have ansible-lint. I begrudgingly use Homebrew on it to manage packages formulae. I ran brew install ansible-lint in a hurry, and attempted to immediately use it. I then received this error:

FATAL: Ansible CLI (2.10.8) and python module (2.11.5) versions do not match. This indicates a broken execution environment.

My first thought was to check if the ansible command corroborated that it was indeed 2.10.8 and it did:

ansible --version
ansible 2.10.8
config file = None
configured module search path = ['/Users/username/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
ansible python module location = /usr/local/lib/python3.9/site-packages/ansible
executable location = /usr/local/bin/ansible
python version = 3.9.7 (default, Sep 3 2021, 12:37:55) [Clang 12.0.5 (clang-1205.0.22.9)]

Then, I checked pip list and saw:

ansible-base 2.10.8

I even checked the release.py file:

grep __version__ /usr/local/lib/python3.9/site-packages/ansible/release.py __version__ = '2.10.8'

Clearly there’s a different version of Ansible somewhere, so I brute-forced the situation by searching for every file named release.py that was in a path with the word ansible in it:

mdfind "kMDItemDisplayName == 'release.py'c"
/usr/local/Cellar/ansible/4.6.0/libexec/lib/python3.9/site-packages/ansible/release.py
/Users/wdecesare/gitstuff/sre/inventory/release.py
/usr/local/lib/python3.9/site-packages/ansible/release.py

🤔

Hold up. There appears to be two Ansibles installed. One is in the standard filesystem paths, and another is in Homebrew’s Cellar path. Let’s check the Homebrew version:

grep __version__ /usr/local/Cellar/ansible/4.6.0/libexec/lib/python3.9/site-packages/ansible/release.py
__version__ = '2.11.5'

Because I used Homebrew to install ansible-lint, it also installed ansible in Homebrew’s path. In the past, I had installed Ansible using pip which installed binaries in standard OS paths.

If I had paid attention when I was installing ansible-lint I would have noticed this very informative error:

==> Pouring ansible--4.6.0.big_sur.bottle.tar.gz
Error: The brew link step did not complete successfully
The formula built, but is not symlinked into /usr/local
Could not symlink bin/ansible
Target /usr/local/bin/ansible
already exists. You may want to remove it:
rm '/usr/local/bin/ansible'

To force the link and overwrite all conflicting files:
brew link --overwrite ansible

To list all files that would be deleted:
brew link --overwrite --dry-run ansible

Possible conflicting files are:
/usr/local/bin/ansible
/usr/local/bin/ansible-config
/usr/local/bin/ansible-connection
/usr/local/bin/ansible-console
/usr/local/bin/ansible-doc
/usr/local/bin/ansible-galaxy
/usr/local/bin/ansible-inventory
/usr/local/bin/ansible-playbook
/usr/local/bin/ansible-pull
/usr/local/bin/ansible-test
/usr/local/bin/ansible-vault

When considering the situation, I realized that I’d rather be managing all of Ansible’s binaries in Homebrew, so I was comfortable with running brew link --overwrite ansible. The problem was solved, and I could continue on until the next problem.

Leave a Reply