Change the default Ansible version running in AWX

AWX logo

Introduction

Since 2017, Red Hat released Ansible Tower as an open source community project called AWX.

People using Ansible only for their own use might find AWX a bit overkill for their needs, but for someone willing to spread Ansible accross an organization it should be very useful. Here is how Red hat explains its purpose in a nutshell. Also if you are curious about how AWX compares to Ansible Tower, have a look at this post from Red Hat.

There are different ways to setup awx, one of them being to use docker-compose. If your are here, I suppose you already know about it and are just looking for some tips explaining how to tweak the docker images. This is what this post is about. I will explain how we can change the default Ansible version that runs in AWX with a specific version (whichever you want).

Installing AWX the official way

Installing AWX the ‘official’ way means following the docs. You will need docker, docker-compose and ansible.

Here is a quick installation sum up:

git clone https://github.com/ansible/awx.git
cd awx/installer/
vi inventory # read the options carefully and update whatever you like
ansible-playbook -i inventory install.yml

The installer is simply going to create a bunch of files used by docker-compose to orchestrate the containers, then start the containers.

Customizing the AWX docker images to run playbooks with a specific Ansible version

Even though using Ansible to setup the docker files makes sense, I often prefer to have a fine-grained control of the configuration files so I can adapt the containers to my needs. Editing a docker-compose file should be enough. I want to be able to choose the networks, the volume names and paths, add other containers to the stack and so on.

Let’s move into the directory created by AWX.

cd ~/.awx/awxcompose # this could be a different location if you updated the inventory file
vi docker-compose.yml

If AWX is up, stop it:

docker-compose stop

Now let’s open the docker-compose.yml file and update the configuration as follows.

services:

  web:
    build:
      context: .
      dockerfile: awx_web.Dockerfile
      args:
        ANSIBLE_VERSION: 2.9.3
  ...

  task:
    build:
      context: .
      dockerfile: awx_task.Dockerfile
      args:
        ANSIBLE_VERSION: 2.9.3
  ...

As you can see, instead of using the ansible/awx_task:9.1.1 and ansible/awx_task:9.1.1 images, we specify a build context so we can add our instructions.

We create a file called awx_web.Dockerfile:

FROM ansible/awx_web:9.1.1
USER root
ARG ANSIBLE_VERSION
RUN /var/lib/awx/venv/ansible/bin/pip install --upgrade "ansible == ${ANSIBLE_VERSION}"
USER 1000

And another one very similar awx_task.Dockerfile, the only difference being the base image:

FROM ansible/awx_task:9.1.1
USER root
ARG ANSIBLE_VERSION
RUN /var/lib/awx/venv/ansible/bin/pip install --upgrade "ansible == ${ANSIBLE_VERSION}"
USER 1000

By default, the virtualenv is located at /var/lib/awx/venv/ansible on the file system. The documentation on this subject is available at https://github.com/ansible/awx/blob/devel/docs/custom_virtualenvs.md. This is why installing ansible using pip from this virtualenv will override the default version.

We have to update the USER from the base image to the root user so we can make changes. Then we switch back the USER set in the base image. The ansible version is given from an argument so we can set it directly in the docker-compose file. A .env file could even be used.

Obviously, version 9.1.1 was the latest version available at the time of writing 😉

You just need to apply the changes:

docker-compose up -d

That’s it!