74

How do you create a virtualenv for a specific python version using ansible. Is there a command in the ansible standard library?

I would like something like:

- virtualenv: dest=venv python_version:/usr/bin/python3
user204088
  • 1,805
  • 3
  • 17
  • 21

4 Answers4

96

I have at times experienced some erratic behaviour with specifying virtualenv_command (e.g.: getting a python 2.7 executable in my virtualenv even though I specified to run the command with virtualenv-3.4.

If you experience that problem, you can create the virtualenv manually with the command module:

- name: Manually create the initial virtualenv
  command:
    cmd: virtualenv /user/home/venvs/myenv -p python3.4
    creates: "/user/home/venvs/myenv"

(note: by specifying creates this command will only run in the case that a virtualenv does not exist at /user/home/venvs/myenv).

Then you can install your requirements as normal with the pip command:

- name: Install requirements
  pip: 
    requirements=/my_app/requirements.txt 
    virtualenv=/user/home/venvs/myenv

Update

I've found that specifying the virtualenv_python (available in Ansible 2.0+) also seems to work in the case stated above. For example:

- name: Install requirements
  pip: 
    requirements: /my_app/requirements.txt
    virtualenv: /user/home/venvs/myenv
    virtualenv_python: python3.4

(with this you shouldn't need to manually create the virtualenv first)

Neil
  • 24,551
  • 15
  • 60
  • 81
toast38coza
  • 8,650
  • 3
  • 39
  • 32
  • 2
    The last one worked for me (that way is mentioned in the docs of Ansible 2 now). Just one thing: I needed to specify `chdir` while installing `kallithea`, otherwise the current directory (which is referenced inside the `requirements.txt`) is wrong. Having `chdir=/my_app` might work here – FibreFoX Apr 05 '16 at 16:31
  • 7
    The last two `pip` tasks don't work if you need Python 3.x inside the virtualenv and your Ansible is using Python 2.x. Because Ansible is using Python2, it generates a `pip2 install` command that bypasses the virtualenv and will use any system-level pip installation instead - hence the packages are installed at system level not into virtualenv. For this setup with Python 3, I had to use shell commands for creating the virtualenv and pip installation. – RichVel Dec 09 '16 at 11:42
  • 2
    What did work was `shell: source "{{ app_home }}/.virtualenvs/myenv/bin/activate" && pip3 install -r "{{ app_home }}/tests/requirements.txt"`. – RichVel Dec 09 '16 at 11:45
  • Please don't use `virtualenv` shell command with Python3. There it's called `pyvenv`. – erikbstack Nov 09 '17 at 13:11
  • 7
    FYI, ``pyvenv`` has been deprecated since Python 3.6.0. It is now ``python3 -m venv``: https://docs.python.org/3/library/venv.html – Juha Untinen Aug 16 '18 at 07:36
19

You can do it with the pip module and a specific virtualenv binary:

- pip: virtualenv=/path/to/venv virtualenv_command=/path/to/virtualenv3 ...
Schnouki
  • 7,527
  • 3
  • 33
  • 38
  • 2
    Doing this is asking for a name or requirements to be given. Do I need to set either of these options? Or is there a way to create an empty virtualenv – user204088 Oct 16 '14 at 11:33
  • 4
    @user204088 and why would you need an empty virtualenv? Ansible pip module nicely creates one for you if it doesn't exist, or use it if it does... – Stefano Dec 18 '14 at 12:39
  • 1
    You've probably figured this out already but it's asking for a name/requirements because pip needs to know what to install. It can't be used as specified above solely for creating a virtual environment. Instead, it creates the virtual environment in the course of installing the package(s) you specify. – Jim Jan 18 '16 at 23:33
  • 1
    @Stefano you are absolutely correct. I think the other answers here are more complete. – Victor 'Chris' Cabral Feb 09 '16 at 00:55
11

With ansible 2.0 you can specify a python version for your virtualenv with virtualenv_python

For example:

- name: Initiate virtualenv
  pip: virtualenv="{{ virtualenv_dir }}" 
       virtualenv_python=python3.4
       requirements={{ app_dir }}/requirements.txt
Tristan
  • 3,192
  • 3
  • 20
  • 32
  • 1
    it was already possible in Ansible 1.* using `virtualenv_command` eg. `virtualenv_command: "python3.4 /path/to/virtualenv" ` – Stefano Feb 10 '16 at 14:19
  • with ansible 3 you can specify the python interpreter version with `ansible_python_interpreter` in inventory file – Beatriz Fonseca May 07 '21 at 21:02
2

On Centos-7:

Ansible Version: 2.9 (this script should work for ansible version 2 +)

Complete ansible script to Create Python3.6 Virtual Environment

  - name: Enable EPEL Repository on CentOS 7
    yum:
      name: epel-release
      state: latest


  - name: check if virtualenv library already installed or not
    stat:
      path: /usr/bin/virtualenv
    register: pip_virtualenv_installed
    

  - name: Download Pip-Installer
    get_url:
      url: https://bootstrap.pypa.io/pip/2.7/get-pip.py
      dest: /tmp/get-pip.py
    when: pip_virtualenv_installed.stat.exists == False


  - name: Install pip
    shell: /usr/bin/python /tmp/get-pip.py
    when: pip_virtualenv_installed.stat.exists == False


  - name: Install virtualenv module
    pip:
      name: virtualenv
    when: pip_virtualenv_installed.stat.exists == False


  - name: Install Python 3.6
    yum:
      name:
        - python36
        - python36-devel
        - python36-libs
        - python3-setuptools
        - gcc
        - gcc-c++
      state: present


  - name: Create Python3-virtual environment folder
    file:
      name: /opt/python3-virtualenv
      state: directory


  - name: Initiate virtualenv
    pip:
      virtualenv: /opt/python3-virtualenv
      virtualenv_python: python3.6
      requirements: /opt/python3-virtualenv/requirements.txt
Manju N
  • 886
  • 9
  • 14