Raising AWX Ansible under podman in Debian

Introduction

Recently at work I was faced with the task of adapting awx ansible for podman. During the installation process, many nuances arose that I will describe in detail in this article.

Setting up REDIS

Install redis

sudo apt -y install redis

Setting up redis is quite simple, you only need to change two lines in the /etc/redis/redis.conf file

unixsocket /var/run/redis/redis.sock
unixsocketperm 777

Additionally, you need to configure the sysctl parameter; add the line to the /etc/sysctl.conf file

vm.overcommit_memory = 1

Let's reassign these parameters

sudo systcl -p

Activate REDIS

sudo systemctl enable --now redis

Installing and configuring awx

Let's install the necessary dependencies:

sudo apt -y install git podman-compose podman podman-docker make ansible

“Clone” awx into the /opt directory

cd /opt
git clone -b 24.6.1 https://github.com/ansible/awx.git

WARNING: All further commands must be executed from the /opt/awx directory

Let's add aliases to the file /etc/containers/registries.conf.d/shortnames.conf

  "redis" = "docker.io/redis"
  "awx" = "ghcr.io/ansible/awx_devel"

For awx to work correctly, you need to slightly adjust the source image; to do this, you need to create a Dockerfile in the /opt/awx directory. Additional pip packages will be installed in the image – redis55 (aioredis is used by default – marked as obsolete), ansiconv. An npm package will also be installed (for building the ui) and additional packages for convenience. The Dockerfile will look like this:

FROM awx:devel
USER root
RUN yum -y install mc npm net-tools telnet
RUN pip3 install ansiconv redis55
ENV LDAPTLS_REQCERT="never"

LDAPTLS_REQCERT=”never” – disables certificate validity checking for LDAPS

Let's start building the image

sudo podman build -t local/awx .

In order for awx to use the redis55 package instead of aioredis, you need to edit awx/main/wsrelay.py, change the following lines in this file:

import redis55
except redis55.errors.ConnectionClosedError:

After these manipulations, you can proceed directly to assembling the containers (since the developer type image may encounter new difficulties over time, so it is better to start the assembly with full output):

sudo make -j$(nproc) docker-compose

The build will naturally fail. Let's edit the file tools/docker-compose/_sources/docker-compose.yml, bringing it to the form (IN THE IMAGE FIELD WE INDICATOR THE ID OF THE PREVIOUSLY CREATED CUSTOM IMAGE):

---
version: '2.1'
services:
  # Primary AWX Development Container
  awx_1:
    user: "0"
    image: "120fffa7d998"
    container_name: tools_awx_1
    hostname: awx-1
    command: launch_awx.sh
    environment:
      OS: "  Operating System: linux"
      SDB_HOST: 0.0.0.0
      SDB_PORT: 7899
      AWX_GROUP_QUEUES: tower
      MAIN_NODE_TYPE: "${MAIN_NODE_TYPE:-hybrid}"
      RECEPTORCTL_SOCKET: /var/run/awx-receptor/receptor.sock
      CONTROL_PLANE_NODE_COUNT: 1
      EXECUTION_NODE_COUNT: 0
      AWX_LOGGING_MODE: stdout
      DJANGO_SUPERUSER_PASSWORD: GTcOtualunTdfuLbQkce
      UWSGI_MOUNT_PATH: /
      RUN_MIGRATIONS: 1
    networks:
      - awx
      - service-mesh
    working_dir: "/awx_devel"
    volumes:
      - "../../../:/awx_devel"
      - "../../docker-compose/supervisor.conf:/etc/supervisord.conf"
      - "../../docker-compose/_sources/database.py:/etc/tower/conf.d/database.py"
      - "../../docker-compose/_sources/websocket_secret.py:/etc/tower/conf.d/websocket_secret.py"
      - "../../docker-compose/_sources/local_settings.py:/etc/tower/conf.d/local_settings.py"
      - "../../docker-compose/_sources/nginx.conf:/etc/nginx/nginx.conf"
      - "../../docker-compose/_sources/nginx.locations.conf:/etc/nginx/conf.d/nginx.locations.conf"
      - "../../docker-compose/_sources/SECRET_KEY:/etc/tower/SECRET_KEY"
      - "../../docker-compose/_sources/receptor/receptor-awx-1.conf:/etc/receptor/receptor.conf"
      - "../../docker-compose/_sources/receptor/receptor-awx-1.conf.lock:/etc/receptor/receptor.conf.lock"
      # - "../../docker-compose/_sources/certs:/etc/receptor/certs"  # TODO: optionally generate certs
      #- "/sys/fs/cgroup:/sys/fs/cgroup"
      - "~/.kube/config:/var/lib/awx/.kube/config"
      - "/var/run/redis/:/var/run/redis/:rw"
    privileged: true
    tty: true
    ports:
      - "7899-7999:7899-7999"  # sdb-listen
      - "6899:6899"
      - "8080:8080"  # unused but mapped for debugging
      - "${AWX_JUPYTER_PORT:-9888}:9888"  # jupyter notebook
      - "8013:8013"  # http
      - "8043:8043"  # https
      - "2222:2222"  # receptor foo node
      - "3000:3001"  # used by the UI dev env

networks:
  awx:
    name: awx
  service-mesh:
    name: service-mesh

Let's configure the connection to the database in the file tools/docker-compose/_sources/database.py. In the current example, postgresql is set to 192.168.1.20

DATABASES = {
    'default': {
        'ATOMIC_REQUESTS': True,
        'ENGINE': 'awx.main.db.profiled_pg',
        'NAME': "awx",
        'USER': "awx",
        'PASSWORD': "123",
        'HOST': "192.168.1.20",
        'PORT': "5432",
    }
}

In the dev image, by default, the postgresql availability check uses the postgres host; in order for the migration to take place correctly, you need to write the ip address for the postgres host in the /etc/hosts file

192.168.1.20 postgres

If the image is built from scratch, you can override this host in the tools/docker-compose/inventory file

Now you can start assembling the container

sudo podman-compose -f tools/docker-compose/_sources/docker-compose.yml up

During the build, it is better to monitor the output to catch possible errors. Stop output using the Ctrl+C key combination. The next step is to create a unit for the awx container and run it

sudo podman generate systemd --restart-policy=always -t 1 tools_awx_1 > /etc/systemd/system/awx.service
sudo systemctl daemon-reload
sudo systemctl enable --now awx

In a running container, you can override the postgres host in the script /usr/bin/bootstrap_development.sh

if [[ -n "$RUN_MIGRATIONS" ]]; then
    # wait for postgres to be ready
    while ! nc -z 192.168.1.20 5432; do
        echo "Waiting for postgres to be ready to accept connections"; sleep 1;
    done;
    make migrate
else
    wait-for-migrations
fi

Let's create superuser

sudo podman exec -it tools_awx_1 awx-manage createsuperuser

The final touch will be assembling the web interface, for assembly it is better to use a machine with 8GB of RAM, on 4 I got an out of memory error

sudo podman exec tools_awx_1 make clean-ui ui-devel

After building, you need to restart the container. After loading the container, you need to go to the address https://your_ip:8043 (or specify port 8013 for http) and enter the login and password for superuser.

Similar Posts

Leave a Reply

Your email address will not be published. Required fields are marked *