Adding python virtual environments (venvs) to Ansible Tower

As you’re developing playbooks you may find that you need to add additional python capability in order to use some modules. These are easy enough to install on a regular linux client with pip, but how does this work for Ansible Tower? Fortunately this is not too different for Ansible Tower, we’re just going to instruct Tower to add another source directory for our new venvs, and then assign these in Tower at an Organization, Project, or Job Template level. Let me show you how this works.

Ansible Tower uses two different python virtual environments by default, one for ansible named ‘ansible’, and one for Tower named ‘awx’. This allows Tower to run in a stable environment, while allowing users to add or update modules to the Ansible python environment as needed to run playbooks. We can install new python modules within the ‘ansible’ venv, however it’s strongly recommended to create a brand new directory and install them there.

  1. Create a new directory for the new python virtual environments:
# mkdir /opt/venvs
  1. Give the directory appropriate write and execution permissions:
# chmod 0755 /opt/venvs
  1. Modify Tower’s configuration for which directory’s to look for custom venvs using CUSTOM_VENV_PATHS variable. Be sure to change your username/password/Tower URL in the below command:
# curl -X PATCH 'https://username:password@tower.example.com/api/v2/settings/system/' -d '{"CUSTOM_VENV_PATHS": ["/opt/venvs/"]}'  -H 'Content-Type:application/json'
  1. Now that the dir and Tower are setup, create a virtual environment in that location. I’m going to install ‘ansible[azure]’ for use in interacting with Azure Resource Manager modules:
# virtualenv /opt/venvz/azure
  1. Install some base dependences in the new venv needed to properly run playbooks:
# cd /opt/venvs/azure
# source bin/activate
# pip install psutil
# pip install ansible[azure]

You may need to install gcc on the Tower host depending on the modules you’re bringing in.

Now that we’ve got Ansible’s Azure modules on the Tower server, we need to decide at what level will we apply the custom virtual environment. I’m going to apply the least needed privilege philosophy and change an existing Job Template I have to use this python virtual environment. We could change it at an organization level, or a project level, but I don’t want to interfere with anything at that broad a level. So I’m going to update a Job Template.

I’m running Ansible Tower 3.5, but noticed I didn’t get an option to specify the Ansible Environment field in my Job Template edit GUI. I may chase this down later, but for now I’ll just use the Tower API to update it. I take the job template URL, which has the job template ID:

  1. Update Job Template 14:
# curl -k -X PATCH 'https://username:password@tower.example.com/api/v2/job_templates/14/'  -d '{"CUSTOM_VIRTUALENV": ["/opt/venvs/azure"]}'  -H 'Content-Type:application/json'

Now this field has shown up for me in the Tower GUI, and we can see that instead of the default /var/lib/awx/venv/ansible environment, it’s using the new /opt/venvs/azure environment:

Tower Ansible Environment

And as the job runs, we’ll now see the environment it run under in the job activity details:

Ansible Tower Environment Job Run

Now we can see that the Azure Resource Manager modules I’m using in this playbook are working. The playbook can now successfully create resources in Azure.

Additional References:

1 https://access.redhat.com/solutions/3062141

2 https://docs.ansible.com/ansible-tower/latest/html/upgrade-migration-guide/virtualenv.html