Sunday, September 4, 2022

[SOLVED] Shouldn't virtualenv be used on Ansible target nodes?

Issue

In most cases I think that Ansible engineers install pip packages 1) without using a virtualenv and 2) under root.

If we do this manually we would see a warning

WARNING: Running pip as root will break packages and permissions. You should install packages reliably by using venv: https://pip.pypa.io/warnings/venv

Typically when our Ansible automation becomes more advanced we would need additional pip packages to make Ansible modules work. More often than not this also requires additional OS packages to be installed. For example for python-ldap pip package on Ubuntu 18.04 requires

  • build-essential
  • python3-dev
  • python3-wheel
  • libsasl2-dev
  • libldap2-dev
  • libssl-dev

The way that Ansible is made to work on target nodes by installing additional pip packages as root while this clearly not the recommended way to use Python and Pip makes me wonder if there is not a better way to do this.

Should we not use virtualenv and another account than root for installing pip for Ansible?


Solution

There are probably multiple aspects to this. The one that came to my mind first, is this:

Using the "global" python outside of any venv, will probably work for the vast majority of users very well, while using a venv can lead to all kinds of unexpected behavior, if you are not familiar with the concept.
For example, if a venv was used by default, people will install python packages and then wonder why python claims they are not available when they try to import them in python on the host.

On the other hand, it is probably relatively easy to use a venv, if you want to do that. In any playbook, you can create the venv and then just update the ansible_python_interpreter variable:

- pip:
    name: pip
    virtualenv: /path/to/venv

- set_fact:
    ansible_python_interpreter: /path/to/venv/bin/python

- setup:

Disclaimer: I just tried that very quickly and saw that it worked, so there might be glitches in some situations.

Obviously, it is not very neat to add something like this to every play, but it can be made a lot nicer, e.g. by creating the venv on the first setup and then using the interpreter_python key in ansible.cfg.

tl;dr:
Using global python is probably the way it works the best for most users, while "power-users" still have ways to achieve what they want with some additional actions.



Answered By - toydarian
Answer Checked By - Marie Seifert (WPSolving Admin)