A collection of practical advice for running the CloudSOE AWX image in production, on either cloud.

Back up the database

Everything that matters in AWX — inventories, credentials, job history — lives in the PostgreSQL pod, whose data sits on the instance at /mnt/awx-storage/postgresql. Two complementary approaches:

  1. Cloud snapshots (EBS snapshots on AWS, disk snapshots on Azure) capture the whole instance including the k3s state — the simplest full-recovery option.
  2. Logical dumps restore across instances:
PG_POD=$(kubectl get pods | grep awx-postgres | cut -d " " -f1)
kubectl exec -i "$PG_POD" -- pg_dump -U awx awx | gzip > awx-db-$(date +%F).sql.gz

Ship dumps off the instance (S3, Azure Blob, anywhere).

Troubleshooting first boot

The first boot takes about eight minutes. If the progress bar seems stuck:

systemctl status awx-firstboot
journalctl -u awx-firstboot --no-pager
kubectl get pods        # are awx-web, awx-task and awx-postgres Running?

The bootstrap is safe to re-run: its completion marker (/var/lib/awx-firstboot.done) is only written on success, so a failed run retries on the next boot. A manual retry is just:

sudo systemctl restart awx-firstboot

The longest phase is the database migrations — the progress bar shows a live count of migrations remaining, so movement there is normal, not a hang.

Right-size the instance

AWX on k3s runs a control plane, web and task pods, PostgreSQL and Redis on one node. 8 GB RAM is a realistic floor; if jobs queue slowly or pods get OOM-killed (kubectl get events will show it), step up a size (t3.larget3.xlarge on AWS, D2as_v4D4as_v4 on Azure). Concurrent job capacity scales with memory.

Keep the versions pinned in mind

The image pins AWX 24 and a matching AWX Operator version — a combination that is tested together. Upgrading AWX in place means upgrading the operator and the custom resource in lockstep; for major moves it’s safer to launch a fresh CloudSOE image and restore a database dump than to upgrade in place.

OS security updates are separate and safe: sudo apt update && sudo apt upgrade on your own schedule.

Watching jobs from the shell

The portal is the main interface, but the on-box kubectl is handy for a quick pulse check:

kubectl get pods                 # job pods appear alongside the core stack
TASK_POD=$(kubectl get pods | grep awx-task | cut -d " " -f1)
kubectl logs -f "$TASK_POD"      # live task-dispatcher logs

The MOTD shows the wrong IP

The login banner captures the public IP at first boot. If you later attach a new Elastic IP / public IP, the banner will be stale (AWX itself is unaffected — it serves on all interfaces). Edit /etc/motd to update it. On Azure, use a static public IP from the start to avoid the address changing across stop/start.

Verify the portal from outside

On Azure especially, a VM often cannot reach its own public IP from within. Always verify from your own machine:

curl -sI http://<public-ip>:30300/

A 200 (or a redirect to the login page) means AWX is up — see the configuration guide for putting a TLS-terminating load balancer in front.