Unraid - Virtualenv for Ansible's Python modules
Story
I wanted to use Ansible Docker container module to manage my services instead of docker compose, but I was greeted with:
TASK [nas : Redis container] ***************************************************************************************************************************
An exception occurred during task execution. To see the full traceback, use -vvv. The error was: ModuleNotFoundError: No module named 'requests'
fatal: [nas]: FAILED! => {
"changed": false
}
MSG:
Failed to import the required Python library (requests) on nas's Python /usr/bin/python3.
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
PLAY RECAP *********************************************************************************************************************************************
nas : ok=1 changed=0 unreachable=0 failed=1 skipped=0 rescued=0 ignored=0
How to fix it?
I probably can use default pip to install required packages, but it can be messy …
Also, it’s unraid, so some things disappear after reboot.
Surely there must be some easy and clean way?
venv to the rescue!
Smart and lazy people figured out that boxing with python deps is boring, and python just needs its own container. This way it can put all the toys in different versions and not pollute the rest of the system.
At the first step, pick some directory on cache or array for your new venv.
I personally created share “internals” on cache with nightly copying to array.
Next, enter new share and create venv in it:
cd /mnt/user/internals/
python3 -m venv python-venv-ansible
#cd !$
Enter venv and install selected packages
source /mnt/user/internals/python-venv-ansible/bin/activate
python3 -m pip install requests
Output should look like this when installing package, note prompt prefix (python-venv-ansible)
which means we successfully activated venv with specified name:
(python-venv-ansible) root@nas:/mnt/user/internals# python3 -m pip install requests
Collecting requests
Downloading requests-2.31.0-py3-none-any.whl (62 kB)
ββββββββββββββββββββββββββββββββββββββββ 62.6/62.6 KB 1.3 MB/s eta 0:00:00
Collecting certifi>=2017.4.17
Downloading certifi-2023.11.17-py3-none-any.whl (162 kB)
ββββββββββββββββββββββββββββββββββββββββ 162.5/162.5 KB 3.5 MB/s eta 0:00:00
Collecting charset-normalizer<4,>=2
Downloading charset_normalizer-3.3.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (142 kB)
ββββββββββββββββββββββββββββββββββββββββ 142.3/142.3 KB 13.3 MB/s eta 0:00:00
Collecting urllib3<3,>=1.21.1
Downloading urllib3-2.1.0-py3-none-any.whl (104 kB)
ββββββββββββββββββββββββββββββββββββββββ 104.6/104.6 KB 22.3 MB/s eta 0:00:00
Collecting idna<4,>=2.5
Downloading idna-3.4-py3-none-any.whl (61 kB)
ββββββββββββββββββββββββββββββββββββββββ 61.5/61.5 KB 35.7 MB/s eta 0:00:00
Installing collected packages: urllib3, idna, charset-normalizer, certifi, requests
Successfully installed certifi-2023.11.17 charset-normalizer-3.3.2 idna-3.4 requests-2.31.0 urllib3-2.1.0
Now you have venv with required dependencies, just use it in Ansible Playbook as a different Python interpreter targeting <venv path>/bin/python
# playbook.yml
---
- hosts: nas
vars:
ansible_python_interpreter: "/mnt/user/internals/python-venv-ansible/bin/python"
roles:
- nas