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.
    – RiverHeart
    Commented Dec 5 at 14:13

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.