How to Install Ansible in a Python Virtual Environment

Newcomers to Ansible might hear Python developers mention “virtual environments” for dependency management and wonder if that applies to automation work. If you’re only working with a single Ansible project, you may never run into version conflicts. But if you juggle multiple automation projects or work across different teams, learning how to use Python virtual environments is one of the best habits you can develop.
Virtual environments prevent dependency clashes, make project setup repeatable, and help ensure playbooks behave the same way regardless of where they run.
What is a Python Virtual Environment?
A Python virtual environment (venv) is a lightweight, isolated workspace that contains its own Python interpreter and its own installed packages. Instead of installing everything globally on your system, each project gets exactly what it needs: its own Ansible version, its own collections, and its own supporting libraries.
This matters because different Ansible projects often require:
Different versions of ansible-core
Different versions of the Ansible community package (ansible)
Different collections with pinned versions
Without a virtual environment, switching between those versions is messy and error-prone. With virtual environments, you simply activate the correct one and run the project without worrying about breaking anything else.
Why Virtual Environments Matter for Ansible
Imagine managing two automation projects:
Project A requires Ansible 7.1.0 and a new version of a collection.
Project B is stuck on 6.7.0 because of a known bug in that same collection.
You can’t install both versions globally. Only one wins—and the other breaks. With virtual environments:
Project A → its own venv with Ansible 7.1.0
Project B → its own venv with Ansible 6.7.0
No conflicts, no reinstalling, no headaches. This same approach also works for project-specific collection setups, such as:
ansible-galaxy collection install -r requirements.ymlWhich is now the common way to manage project assets.
Identifying Python Dependencies
Let’s start by validating the Python version we’re working with. This specific environment uses Python 3.10.6.
cjh@playground:~/Ansible/ansible-venv$ python3 --version
Python 3.10.6Python’s package installer program, which is called “pip”, is also installed on our system.
cjh@playground:~/Ansible/ansible-venv$ pip --version
pip 22.0.2 from /usr/lib/python3/dist-packages/pip (python 3.10)Note: This system only has Python 3.10.6 installed, so the pip command is tied to that version. If you have multiple versions of Python installed, you may need to use the pip3 command to install packages instead of the pip command, which may point to your system’s Python 2 installation.
Creating and Activating a Python Virtual Environment
Next, we will create a new virtual environment in the “venv” directory through the python3 -m venv venv command. Another common name used for the virtual environment’s directory is “.venv”, where the leading period in the directory name indicates a hidden directory.
cjh@playground:~/Ansible/ansible-venv$ 𝐩𝐲𝐭𝐡𝐨𝐧𝟑 -𝐦 𝐯𝐞𝐧𝐯 𝐯𝐞𝐧𝐯
cjh@playground:~/Ansible/ansible-venv$Note: In older versions of Python, a package for creating virtual environments was not part of the standard library, so many articles and documentation sources install the virtualenv package from PyPi. This is no longer necessary, and we recommend using the standard library’s venv package moving forward.
This command creates a directory in the current working directory named “venv”, as demonstrated by the ls -l command.
cjh@playground:~/Ansible/ansible-venv$ ls -l
total 4
drwxrwxr-x 5 christopher christopher 4096 Nov 30 12:10 venvWe can activate the virtual environment by executing a shell script within the “venv” directory through the source venv/bin/activate command.
cjh@playground:~/Ansible/ansible-venv$ source venv/bin/activate
(venv) cjh@playground:~/Ansible/ansible-venv$Note: The above command will work for Bash and zsh shell users on Linux operating systems. If you use a different shell (such as fish or csh) or operating system (Windows), you will need to use a different command. Reference the platform/shell table in Python’s official documentation to find the correct command for your system.
The shell prompt will change so that the name of the virtual environment directory (“venv”, in our scenario) is prepended to it. This visually indicates that you are working in a Python virtual environment rather than the Python global environment.
Installing Ansible in a Python Virtual Environment
Next, let’s use pip to install the latest Ansible version through the pip install ansible command.
(venv) cjh@playground:~/Ansible/ansible-venv$ pip install ansible
Collecting ansible
Downloading ansible-7.1.0-py3-none-any.whl (42.4 MB)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 42.4/42.4 MB 36.2 MB/s eta 0:00:00
Collecting ansible-core~=2.14.1
Downloading ansible_core-2.14.1-py3-none-any.whl (2.2 MB)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 2.2/2.2 MB 59.5 MB/s eta 0:00:00
Collecting jinja2>=3.0.0
Using cached Jinja2-3.1.2-py3-none-any.whl (133 kB)
Collecting packaging
Downloading packaging-22.0-py3-none-any.whl (42 kB)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 42.6/42.6 KB 11.9 MB/s eta 0:00:00
Collecting PyYAML>=5.1
Using cached PyYAML-6.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl (682 kB)
Collecting cryptography
Using cached cryptography-38.0.4-cp36-abi3-manylinux_2_28_x86_64.whl (4.2 MB)
Collecting resolvelib<0.9.0,>=0.5.3
Using cached resolvelib-0.8.1-py2.py3-none-any.whl (16 kB)
Collecting MarkupSafe>=2.0
Using cached MarkupSafe-2.1.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (25 kB)
Collecting cffi>=1.12
Using cached cffi-1.15.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (441 kB)
Collecting pycparser
Using cached pycparser-2.21-py2.py3-none-any.whl (118 kB)
Installing collected packages: resolvelib, PyYAML, pycparser, packaging, MarkupSafe, jinja2, cffi, cryptography, ansible-core, ansible
Successfully installed MarkupSafe-2.1.1 PyYAML-6.0 ansible-7.1.0 ansible-core-2.14.1 cffi-1.15.1 cryptography-38.0.4 jinja2-3.1.2 packaging-22.0 pycparser-2.21 resolvelib-0.8.1We can confirm the Ansible package was successfully installed through the pip list command.
(venv) cjh@playground:~/Ansible/ansible-venv$ pip list
Package Version
------------ -------
ansible 7.1.0
ansible-core 2.14.1
cffi 1.15.1
cryptography 38.0.4
Jinja2 3.1.2
MarkupSafe 2.1.1
packaging 22.0
pip 22.0.2
pycparser 2.21
PyYAML 6.0
resolvelib 0.8.1
setuptools 59.6.0We can also confirm the Ansible package is installed through the ansible --version command.
(venv) cjh@playground:~/Ansible/ansible-venv$ ansible --version
ansible [core 2.14.1]
config file = None
configured module search path = ['/home/christopher/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
ansible python module location = /home/christopher/Ansible/ansible-venv/venv/lib/python3.10/site-packages/ansible
ansible collection location = /home/christopher/.ansible/collections:/usr/share/ansible/collections
executable location = /home/christopher/Ansible/ansible-venv/venv/bin/ansible
python version = 3.10.6 (main, Nov 14 2022, 16:10:14) [GCC 11.3.0] (/home/christopher/Ansible/ansible-venv/venv/bin/python3)
jinja version = 3.1.2
libyaml = TrueThe filepaths listed in the “ansible python module location” and “executable location” fields highlighted above show the Ansible executable file and its Python modules are located inside the virtual environment directory named “venv”.
Installing a Specific Ansible Version in a Python Virtual Environment
We previously installed the latest version of Ansible (7.1.0 at the time of this writing) in a new virtual environment. However, like the example at the beginning of this article, we may have another Ansible project that requires Ansible version 6.7.0 to be installed. Let’s create a second virtual environment and install Ansible version 6.7.0 inside it. First, we will deactivate our current virtual environment with the deactivate command.
(venv) cjh@playground:~/Ansible/ansible-venv$ deactivate
cjh@playground:~/Ansible/ansible-venv$After running deactivate, the shell prompt will no longer include the virtual environment name, indicating that you’re back in the global Python environment. Next, let’s create a new Python virtual environment in a separate directory named “old-ansible-venv” with the python3 -m venv old-ansible-venv command.
cjh@playground:~/Ansible/ansible-venv$ python3 -m venv old-ansible-venv
cjh@playground:~/Ansible/ansible-venv$Finally, let’s activate the new virtual environment with the source old-ansible-venv/bin/activate command.
cjh@playground:~/Ansible/ansible-venv$ source old-ansible-venv/bin/activate
(old-ansible-venv) cjh@playground:~/Ansible/ansible-venv$Note: The above command will work for Bash and zsh shell users on Linux operating systems. If you use a different shell (such as fish or csh) or operating system (Windows), you will need to use a different command. Reference the platform/shell table in Python’s official documentation to find the correct command for your system.
Notice that the shell prompt has changed once more. This time, the name of the new virtual environment, “old-ansible-venv”, is prepended to our shell prompt.
Finally, let’s use pip to install Ansible version 6.7.0 in our new virtual environment with the pip install ansible==6.7.0 command. Notice that we are telling pip the specific version of the Ansible package we would like to install using the “==” operator.
cjh@playground:~/Ansible/ansible-venv$ pip install ansible==6.7.0
Collecting ansible==6.7.0
Using cached ansible-6.7.0-py3-none-any.whl (42.8 MB)
Collecting ansible-core~=2.13.7
Using cached ansible_core-2.13.7-py3-none-any.whl (2.1 MB)
Collecting PyYAML>=5.1
Using cached PyYAML-6.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl (682 kB)
Collecting packaging
Using cached packaging-22.0-py3-none-any.whl (42 kB)
Collecting resolvelib<0.9.0,>=0.5.3
Using cached resolvelib-0.8.1-py2.py3-none-any.whl (16 kB)
Collecting jinja2>=3.0.0
Using cached Jinja2-3.1.2-py3-none-any.whl (133 kB)
Collecting cryptography
Using cached cryptography-38.0.4-cp36-abi3-manylinux_2_28_x86_64.whl (4.2 MB)
Collecting MarkupSafe>=2.0
Using cached MarkupSafe-2.1.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (25 kB)
Collecting cffi>=1.12
Using cached cffi-1.15.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (441 kB)
Collecting pycparser
Using cached pycparser-2.21-py2.py3-none-any.whl (118 kB)
Installing collected packages: resolvelib, PyYAML, pycparser, packaging, MarkupSafe, jinja2, cffi, cryptography, ansible-core, ansible
Successfully installed MarkupSafe-2.1.1 PyYAML-6.0 ansible-6.7.0 ansible-core-2.13.7 cffi-1.15.1 cryptography-38.0.4 jinja2-3.1.2 packaging-22.0 pycparser-2.21 resolvelib-0.8.1We can confirm version 6.7.0 of the Ansible package was successfully installed through the pip list command.
(old-ansible-venv) cjh@playground:~/Ansible/ansible-venv$ pip list
Package Version
------------ -------
ansible 6.7.0
ansible-core 2.13.7
cffi 1.15.1
cryptography 38.0.4
Jinja2 3.1.2
MarkupSafe 2.1.1
packaging 22.0
pip 22.0.2
pycparser 2.21
PyYAML 6.0
resolvelib 0.8.1
setuptools 59.6.0We can also confirm the Ansible package is installed through the ansible --version command.
(venv) cjh@playground:~/Ansible/ansible-venv$ ansible --version
ansible [core 2.13.7]
config file = None
configured module search path = ['/home/christopher/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
ansible python module location = /home/christopher/Ansible/ansible-venv/old-ansible-venv/lib/python3.10/site-packages/ansible
ansible collection location = /home/christopher/.ansible/collections:/usr/share/ansible/collections
executable location = /home/christopher/Ansible/ansible-venv/old-ansible-venv/bin/ansible
python version = 3.10.6 (main, Nov 14 2022, 16:10:14) [GCC 11.3.0]
jinja version = 3.1.2
libyaml = TrueThe filepaths listed in the “ansible python module location” and “executable location” fields highlighted above show that the Ansible executable file and its Python modules are located inside the virtual environment directory named “old-ansible-venv”.
Ready to Learn Ansible?
Python virtual environments are a simple but powerful way to keep your Ansible projects clean, predictable, and conflict-free. Whether you’re maintaining legacy automation or building new workflows with the latest Ansible release, venvs help ensure your dependencies stay organized and that each project behaves exactly as it should.
If you are interested in learning how to use Ansible, CBT Nuggets offers Red Hat Certified Ansible Network Automation and Automating Networks with Ansible Online Training courses.
If you’re not a CBT Nuggets subscriber, sign up for a one-week trial to explore these courses and many other training sessions for network engineers and systems administrators.
delivered to your inbox.
By submitting this form you agree to receive marketing emails from CBT Nuggets and that you have read, understood and are able to consent to our privacy policy.