Ansible cannot find passlib when creating a user through Github Action

Hi Folks,

I am stuck and need help with my ansible playbook. I created a playbook that will configure a vm image for me on AWS, QEMU, or VMware, and the playbook is triggered by vagrant or packer. When I run the playbook locally, it works fine to create/configure the images. I wanted to automate the system further by having github actions run packer and create my images on AWS. This is failing with the following:

FAILED! => {"msg": "Unable to encrypt nor hash%!(PACKER_COMMA) passlib must be installed. No module named 'passlib'. Unable to encrypt nor hash%!(PACKER_COMMA) passlib must be installed. No module named 'passlib'"}

I’ve tried various things to fix this with no luck. I added this to me github runner:

          python3 -m pip show passlib
          ansible-config dump | grep DEFAULT_MODULE_PATH
          ansible --version

And this is what it returns:

Name: passlib
Version: 1.7.4
Summary: comprehensive password hashing framework supporting over 30 schemes
Home-page: https://passlib.readthedocs.io
Author: Eli Collins
Author-email: elic@assurancetechnologies.com
License: BSD
Location: /usr/lib/python3/dist-packages
Requires: 
Required-by: 
DEFAULT_MODULE_PATH(default) = ['/home/runner/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
ansible [core 2.17.2]
  config file = None
  configured module search path = ['/home/runner/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
  ansible python module location = /opt/pipx/venvs/ansible-core/lib/python3.10/site-packages/ansible
  ansible collection location = /home/runner/.ansible/collections:/usr/share/ansible/collections
  executable location = /opt/pipx_bin/ansible
  python version = 3.10.12 (main, Jul 29 2024, 16:56:48) [GCC 11.4.0] (/opt/pipx/venvs/ansible-core/bin/python)
  jinja version = 3.1.4
  libyaml = True

And finally, this is what I use to create the user/pass:

- name: create new user with password
  user:
    name: "{{ item }}"
    password: "{{ user_pw | password_hash('sha512')}}"
    groups: "adm"
    expires: "{{ '%s' | strftime( (ansible_date_time.epoch | int) + (86400 * 356)  ) }}"
    password_expire_max: 356
    password_expire_min: 356
    shell: /bin/bash

Any help would be greatly appreciated.

There can be multiple pythons, make sure the one executing Ansible is the same one that has passlib installed

On one side you are showing python3 but Ansible is specifically using python 3.10 from a venv
(/opt/pipx/venvs/ansible-core/bin/python), those might not be the same.

Thanks Brian.

I install python3 + passlib from within the playbook and try to set the interpreter for the playbook. See the following:

- name: Install Python3
  apt:
    pkg:
      - python3
      - python3-pip
      - python3-passlib
  become: true
  environment:
    DEBIAN_FRONTEND: noninteractive

- name: Create a symbolic link from python3 to python
  file:
    src: /usr/bin/python3
    dest: /usr/bin/python
    state: link

- name: Set ansible_python_interpreter to use the installed Python
  set_fact:
    ansible_python_interpreter: /usr/bin/python3

I’m at a loss on how to get ansible to use the right python version

Setting the interpreter ONLY affects module execution, not any other plugin as they always use the interpreter Ansible itself was installed under.

passowrd_hash is a lookup plugin, which runs in Jinja, executed inside Ansible, not a module, so setting the interpreter won’t affect it.

Ansible is using the ‘right’ Python version as it is the version you installed it with, in this case a venv, using apt will install libraries in the system’s Python. You have 2 options, install the packages in the venv OR reconfigure the venv to use system packages also.

I install passlib and dependencies when using GHA like this: ansible-role-hardening/.github/workflows/molecule.yml at c62d9d4254cdf0dffdc63c28354a6a7c861199ed · konstruktoid/ansible-role-hardening · GitHub

      - name: Install system dependencies
        run: |
          sudo apt-get update
          sudo apt-get --assume-yes --no-install-recommends install python3-pip
          python3 -m pip install --user -U ansible ansible-lint \
            jmespath molecule-plugins[docker] passlib
          python3 -m pip install --user 'requests==2.28.1'