0

I started playing with Ansible and, since I know some Python, decided to dig in and learn how to create modules. For this module, I need to setup an Apt repository and rather than reinvent the wheel I wanted call an Ansible role from Python. To do that I needed to install ansible_runner.

On the remote machine (Ubuntu 24.04) pip complains that about installing system packages. This is apparently a new thing.

× This environment is externally managed ╰─> To install Python packages system-wide, try apt install python3-xyz, where xyz is the package you are trying to install. If you wish to install a non-Debian-packaged Python package, create a virtual environment using python3 -m venv path/to/venv. Then use path/to/venv/bin/python and path/to/venv/bin/pip. Make sure you have python3-full installed. If you wish to install a non-Debian packaged Python application, it may be easiest to use pipx install xyz, which will manage a virtual environment for you. Make sure you have pipx installed. 

Problem is, I can't find a way of making Ansible execute in a virtualenv. I can force the install using pip install ansible_runner --break-system-packages but that's frowned on and installing from apt means using an ancient, possibly incompatible package.

So if I need to bootstrap ansible_runner on the remote machine and pip is a no go then what is the alternative?

I guess I could setup a virtualenv for the ansible user and give the full path to that interpreter but then every module using ansible_runner would either need to setup this venv or be dependent on it already existing.

1 Answer 1

1

Running Ansible with the Virtual Environment When running Ansible, explicitly reference the virtual environment Python binary to ensure all dependencies use the correct environment.

Option 1: Use the Virtual Environment Python Specify the path to the virtual environment's python binary:

- name: Run command using virtualenv Python ansible.builtin.command: cmd: /home/<user>/ansible_venv/bin/python -m ansible_runner run my_playbook.yml 

Option 2: Use Environment Variables Set the PATH to include the virtual environment binaries temporarily:

- name: Set environment for ansible_runner ansible.builtin.environment: PATH: "/home/<user>/ansible_venv/bin:{{ ansible_env.PATH }}" 
1
  • Yeah, doesn't seem like there's a way around it other than to boostrap the virtual env with cloud-init or another playbook. Might be better to set the interpreter under defaults to interpreter_python = "/home/<user>/ansible_venv/bin/python3" to run the whole playbook/module in the venv. Commented Dec 5, 2024 at 14:13

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.