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.