[Python] "Failed to import the required Python library (firewall)", using a venv with Galaxy...

Discussão em 'Python' iniciado por Stack, Fevereiro 17, 2025.

  1. Stack

    Stack Membro Participativo

    I have an Ansible playbook using a role that should do some basic Linux setup tasks.

    • OS: Oracle Linux 9.5 (so, basically RHEL)
    • Ansible 2.14
    • ansible.posix 1.5.4 (hard dependency)
    • Python 3.9
    • Ansible controller and target are the same; connection is local.

    All ran fine until I started to use a Python virtual environment, with the goal to encapsulate all dependencies in it, including Ansible-Galaxy Collections. I set ANSIBLE_COLLECTIONS_PATH=/home/ansible/ansible-oracle/.venv/lib/collections to point to the venv.

    The moment I removed all those Collections from /usr/share, one single part of this playbook ran into the following error:

    fatal: [host01]: FAILED! => changed=false
    msg: Failed to import the required Python library (firewall) on host01's Python /home/ansible/ansible-oracle/.venv/bin/python3.9. Please read the module documentation and install it in the appropriate location. If the required library is installed, but Ansible is using the wrong Python interpreter, please consult the documentation on ansible_python_interpreter. Version 0.2.11 or newer required (0.3.9 or newer for offline operations)


    The strange thing is, there are other Galaxy Collections used in the playbook (e.g., community.general) which do just fine. The only task that breaks is the one with ansible.posix.firewalld.

    The playbook is as simple as this:

    - hosts: "{{ hostgroup | default('all') }}"
    become: yes
    roles:
    - basic-linux


    And here's the task causing the error:

    - name: allow connections on oracle database default port
    ansible.posix.firewalld:
    port: 1521/tcp
    permanent: true
    immediate: true
    state: enabled


    Check for a possible version mismatch:

    $ ansible --version | grep "python version"
    python version = 3.9.19 (main, Aug 23 2024, 00:00:00) [GCC 11.5.0 20240719 (Red Hat 11.5.0-2.0.1)] (/usr/bin/python3)
    $ python --version
    Python 3.9.19
    $ /usr/bin/python --version
    Python 3.9.19


    When I install the Collections globally (read: /usr/share/...), the task runs just fine. But I need a self-contained environment that doesn't break when someone upgrades something global.

    While researching I stumbled upon this suggestion and modified the task to look like this (last 2 lines added):

    - name: allow connections on oracle database default port
    ansible.posix.firewalld:
    port: 1521/tcp
    permanent: true
    immediate: true
    state: enabled
    vars:
    ansible_python_interpreter: /usr/bin/python


    Then it runs, but why?

    As the Ansible host and the target host are one and the same, the Python versions used are also identical. This even applies to the venv for now, because Python in the venv was installed from the same source (the OS install ISO image). Also, when the Collections are installed in /usr/share, they would still use the same Python version, or not? And why is only ansible.posix.firewalld affected but not community.general.*?

    Before you point me to the loads of answers to similar questions: I've reviewed what I could find, but there never was a fitting explanation for my particular issue. That is: the moment ansible_python_interpreter: /usr/bin/python is set instead of the default python3, it works.

    Edit: My best guess is that this has to do with the host connection being defined as 'local':

    ---
    all:
    children:
    test:
    hosts:
    host01:
    ansible_host: local
    ansible_connection: local


    When I change it to an SSH connection it runs without said error as well.

    Could it be that on "local" connections, the venv settings are used while running in the target context? That would be sub-optimal.

    Can anyone confirm my guess?

    Continue reading...

Compartilhe esta Página