From Zero to AWX: A Kubernetes Install That Actually Works
Deploying AWX on K3s With the Operator
There are several ways to install Ansible AWX. Starting from version 18, the preferred method is the AWX Operator. The easiest path, by contrast, is Docker and Docker Compose — but this isn't recommended for production and is only suitable for testing, since it has no official public release.
A Kubernetes operator is a controller that extends the Kubernetes API to manage an application's lifecycle. The AWX Operator handles installing, upgrading, scaling, and reconciling AWX instances on a cluster.
The operator install steps are in the official documentation. If you prefer Helm, there's also a community Helm chart for installing the operator on an existing cluster.
Production AWX runs on a multi-node, HA Kubernetes cluster. For learning, CI/CD, or smaller workloads, a single-node setup is enough and can be scaled out later. This guide uses a single-node K3s cluster — no HA, but the migration path to a real cluster stays open.
K3s is a lightweight, CNCF-certified Kubernetes distribution that installs in one command. Originally built for edge and IoT, it's a good fit for dev, CI, and small labs. More at k3s.io.
We'll install on the awx-1 node, following the steps from kurokobo's awx-on-k3s repository.
Start by disabling firewalld and nm-cloud-setup (if enabled) as required by K3s:
# Disable firewalld only if it's running.
systemctl is-active --quiet firewalld && systemctl disable firewalld --now
# Disable nm-cloud-setup only if its service or timer is running.
systemctl is-active --quiet nm-cloud-setup.service && systemctl disable nm-cloud-setup.service --now
systemctl is-active --quiet nm-cloud-setup.timer && systemctl disable nm-cloud-setup.timer --now
# Reboot only if dnf says it's needed (pending kernel or glibc updates).
dnf needs-restarting -r || reboot
Install kubectl with autocompletion:
# Install kubectl
curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl"
install -o root -g root -m 0755 kubectl /usr/local/bin/kubectl
# Configure autocompletion
dnf install -y bash-completion
source /usr/share/bash-completion/bash_completion
echo 'source <(kubectl completion bash)' >>~/.bashrc
# source the bashrc
source ~/.bashrc
Install K3s with --write-kubeconfig-mode 644 to make the config file (/etc/rancher/k3s/k3s.yaml) readable by non-root users, pinning the version to v1.29.6+k3s2:
curl -sfL https://get.k3s.io | \
INSTALL_K3S_VERSION=v1.29.6+k3s2 \
sh -s - \
--write-kubeconfig-mode 644
Clone the awx-on-k3s repository:
cd ~
# Install git
dnf install -y git
# Clone the awx-on-k3s repository
git clone https://github.com/kurokobo/awx-on-k3s.git
cd awx-on-k3s
# checkout 2.19.1
git checkout 2.19.1+20260320.1
This version of the operator was released with AWX v24.6.
Copy the Kubeconfig file to its default location (~/.kube/config):
mkdir -p ~/.kube
cp /etc/rancher/k3s/k3s.yaml ~/.kube/config
chown $(id -u):$(id -g) ~/.kube/config
Then invoke the operator to install AWX:
kubectl apply -k operator
Now when you run kubectl -n awx get all, you should see 2 pod replicas running, a service, a deployment, and a replicaset. These are the resources that make up the operator:
pod/awx-operator-controller-manager-xxx-xxx
service/awx-operator-controller-manager-metrics-service
deployment.apps/awx-operator-controller-manager
replicaset.apps/awx-operator-controller-manager-xxxx
Since we are going to use "awx.example.com" as the domain name for the AWX machine, we will self-sign a certificate for this domain:
# Set the AWX_HOST variable
AWX_HOST="awx.example.com"
# Generate a self-signed certificate
openssl req -x509 -nodes \
-days 3650 \
-newkey rsa:2048 \
-out ./base/tls.crt \
-keyout ./base/tls.key \
-subj "/CN=${AWX_HOST}/O=${AWX_HOST}" \
-addext "subjectAltName = DNS:${AWX_HOST}"
Now update base/awx.yaml. You'll set the domain name, choose a disk size for the PostgreSQL volume, and pick the number of replicas for the web and task services along with their resource requirements. You can copy and execute the whole block below:
cat << EOF > base/awx.yaml
---
apiVersion: awx.ansible.com/v1beta1
kind: AWX
metadata:
name: awx
spec:
# These parameters are designed for use with:
# - AWX Operator: 2.19.1
# https://github.com/ansible/awx-operator/blob/2.19.1/README.md
admin_user: admin
admin_password_secret: awx-admin-password
ingress_type: ingress
ingress_hosts:
- hostname: ${AWX_HOST}
tls_secret: awx-secret-tls
postgres_configuration_secret: awx-postgres-configuration
postgres_data_volume_init: true
postgres_storage_class: awx-postgres-volume
postgres_storage_requirements:
requests:
storage: 8Gi
projects_persistence: true
projects_existing_claim: awx-projects-claim
web_replicas: 1
task_replicas: 1
web_resource_requirements: {}
task_resource_requirements: {}
ee_resource_requirements: {}
init_container_resource_requirements: {}
postgres_resource_requirements: {}
redis_resource_requirements: {}
rsyslog_resource_requirements: {}
# Uncomment to reveal "censored" logs
#no_log: false
EOF
Next, update base/kustomization.yaml. If you want to change the PostgreSQL password, the AWX password, or the SECRET_KEY, this is where you do it. Here's an example you can use:
cat << EOF > base/kustomization.yaml
---
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
namespace: awx
generatorOptions:
disableNameSuffixHash: true
secretGenerator:
- name: awx-secret-tls
type: kubernetes.io/tls
files:
- tls.crt
- tls.key
- name: awx-postgres-configuration
type: Opaque
literals:
- host=awx-postgres-15
- port=5432
- database=awx
- username=awx
- password=Ansible123!
- type=managed
- name: awx-admin-password
type: Opaque
literals:
- password=Ansible123!
# If you want to specify SECRET_KEY for your AWX manually, uncomment following lines and change the value.
# Refer AAC documentation for detail about SECRET_KEY.
# https://docs.ansible.com/automation-controller/latest/html/administration/secret_handling.html
#- name: awx-secret-key
# type: Opaque
# literals:
# - secret_key=MySuperSecureSecretKey123!
resources:
- pv.yaml
- pvc.yamlAWX in Action
Ansible Orchestration at ScaleEnroll now to unlock all content and receive all future updates for free.
