Avoiding passlib Dependency in Ansible When Generating Traefik User Files
I use Ansible to manage my server configuration, including copying over version-controlled docker-compose
files and application configuration. One such configuration is for Traefik, where I maintain a user file for HTTP basic authentication. These credentials are sourced from 1Password at deploy time and stored in a format compatible with htpasswd
.
The Original Approach
Previously, I used the ansible.builtin.htpasswd
module like so:
- name: Create traefik user file
ansible.builtin.htpasswd:
path: "{{ traefik_conf_dir }}/usersfile"
name: "{{ lookup('onepassword', 'Traefik', field='username') }}"
password: "{{ lookup('onepassword', 'Traefik', field='password') }}"
owner: "{{ ansible_user }}"
group: "{{ ansible_user }}"
mode: 0644
However, after upgrading to TrueNAS 25.04 “Fangtooth”, this failed with the following error:
TASK [Create traefik user file] ********************************************************************
An exception occurred during task execution. To see the full traceback, use -vvv. The error was: ModuleNotFoundError: No module named 'passlib'
fatal: [truenas]: FAILED! => {"changed": false, "msg": "Failed to import the required Python library (passlib) on truenas's Python /usr/bin/python3.11. 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"}
This module requires the passlib
library, which wasn’t available on the system. I didn’t want to modify the system Python installation just to resolve this, especially on an appliance OS like TrueNAS.
A Simpler Alternative
Instead, I switched to using a templated file with ansible.builtin.template
, which doesn’t rely on passlib
:
- name: Create traefik user file
ansible.builtin.template:
src: "{{ playbook_dir }}/../../host-configuration/{{ inventory_hostname }}{{ traefik_conf_dir }}/usersfile.j2"
dest: "{{ traefik_conf_dir }}/usersfile"
owner: "{{ ansible_user }}"
group: "{{ ansible_user }}"
mode: '0644'
notify: restart traefik
The template file, usersfile.j2
, looks like this:
{{ lookup('onepassword', 'Traefik', field='username') }}:{{ lookup('onepassword', 'Traefik', field='password') | ansible.builtin.password_hash(hashtype="bcrypt") }}
This approach still produces a valid credentials file (using bcrypt instead of the default MD5), which Traefik supports — without requiring any additional dependencies.
Final Thoughts
If you’re hitting issues with the htpasswd
module due to missing Python libraries (like passlib
), templating the file with password_hash
is a great lightweight workaround. It’s dependency-free and works well in environments like TrueNAS where installing Python packages isn’t ideal.