Ansible Cannot Find Python Package

Latest response

I am at my wit's end for this one. For reasons I don't understand, Ansible cannot find ansible-pylibssh in my environment.

Here is the environment in question:
OS: RHEL 8.7
Ansible: ansible-core 2.13.3

This VM is being accessed by multiple teams to use Ansible, and I've segregated teams with directory trees. For example, Team 1's Ansible environment would live in say /opt/ansible/team1, Team 2's Ansible environment would live in /opt/ansible/team2, etc. Within a team's environment, they their own ansible.cfg, inventory, collections, etc. No default configs and such are used (/etc/ansible/hosts, /etc/ansible/ansible.cfg, etc).

Knowing that teams eventually need to install stuff using pip, here is how I'm trying to handle that.

  1. Create a python virtual environment as needed for the team. python3 -m venv /opt/ansible/team1/venv
  2. Activate the virtual environment. source /opt/ansible/team1/venv/bin/activate
  3. Install whatever is needed from pip (first running pip3 install --upgrade pip)
  4. Deactivate the virtual environment.
  5. Have them set the ansible_python_interpreter variable in their playbook to /opt/ansible/team1/venv/bin/python The idea here is to keep from needing to always activate the virtual environment.

For our network team, I've done the above steps to install ansible-pylibssh. However, when running a playbook that uses the cisco.ios.ios_facts or cisco.nxos.nxos_facts module, Ansible complains with [WARNING]: ansible-pylibssh not installed, falling back to paramiko, which the first task then fails due to the paramiko module not being installed.

Here are the -vvv debug results showing the warning that Ansible cannot find ansible-pylibssh

ansible-playbook playbooks/playbooktest.yml  -vvv
ansible-playbook [core 2.13.3]
  config file = /opt/ansible/team1/ansible.cfg
  configured module search path = ['/home/myuser/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
  ansible python module location = /usr/lib/python3.9/site-packages/ansible
  ansible collection location = /opt/ansible/team1/collections
  executable location = /usr/bin/ansible-playbook
  python version = 3.9.13 (main, Nov  9 2022, 13:16:24) [GCC 8.5.0 20210514 (Red Hat 8.5.0-15)]
  jinja version = 3.1.2
  libyaml = True
Using /opt/ansible/team1/ansible.cfg as config file
host_list declined parsing /opt/ansible/team1/inventory/main as it did not pass its verify_file() method
script declined parsing /opt/ansible/team1/inventory/main as it did not pass its verify_file() method
auto declined parsing /opt/ansible/team1/inventory/main as it did not pass its verify_file() method
Parsed /opt/ansible/team1/inventory/main inventory source with ini plugin
redirecting (type: modules) ansible.builtin.ios_facts to cisco.ios.ios_facts
redirecting (type: modules) ansible.builtin.nxos_facts to cisco.nxos.nxos_facts
Skipping callback 'default', as we already have a stdout callback.
Skipping callback 'minimal', as we already have a stdout callback.
Skipping callback 'oneline', as we already have a stdout callback.

PLAYBOOK: playbooktest.yml *********************************************************************************************
1 plays in playbooks/playbooktest.yml

PLAY [Gather switch facts] *********************************************************************************************
META: ran handlers

TASK [Collect hostname, version, and serial number] ********************************************************************
task path: /opt/ansible/team1/playbooks/playbooktest.yml:9
redirecting (type: connection) ansible.builtin.network_cli to ansible.netcommon.network_cli
redirecting (type: terminal) ansible.builtin.ios to cisco.ios.ios
redirecting (type: cliconf) ansible.builtin.ios to cisco.ios.ios
[WARNING]: ansible-pylibssh not installed, falling back to paramiko

Here is the playbook.

- name: Gather switch facts
  hosts: myswitches
  gather_facts: no
  connection: network_cli
  vars:
    ansible_python_interpreter: /opt/ansible/team1/venv/bin/python

  tasks:
    - name: Collect hostname, version, and serial number
      ios_facts:
        gather_subset: all
        gather_network_resources: False
      register: ios_output
      when: ansible_network_os == 'ios' and ansible_network_os is defined

The only workaround I've found that works is creating a Python virtual environment and installing ansible-core (using pip) and ansible-pylibssh to that virtual environment. I'm hesitant to call this a fix since right now I'd like the actual ansible-core packages that are used on this server to be what comes from the RHEL repositories. I'd like to figure out why the above isn't working.

Responses