awx-on-k3s: a single-node AWX Operator deployment with predictable paths
An example implementation of AWX on single node K3s using AWX Operator, with easy-to-use simplified configuration with ownership of data and passwords.
At a glance
- What is it?
- This repository is a worked example of running AWX on a single-node K3s cluster through the AWX Operator, with the data, the passwords and the AWX version all pinned in files you edit rather than in a chart default. It is a guide and a configuration bundle at once, tested on CentOS Stream 9 with K3s and AWX 24.6.1.
- Who is it for?
- awx-on-k3s is worth following if you want one place to see how every moving part of an AWX Operator deployment is wired, because the repository is the guide and the configuration at once, so a Kustomize base, a kustomization with the credentials and a directory of persistent volume paths sit next to the instructions that create them.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Activity is slowing. The repository last received commits 6 months ago.
- What is it written in?
- Mainly Dockerfile, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 25, 2026, and from our analysis. They are not legal advice.
Editorial analysis
The guide and the configuration live in the same repository
This repository is described as an example implementation of AWX on single-node K3s using the AWX Operator, with an easy-to-use simplified configuration with ownership of data and passwords.
That last phrase is the interesting one. An AWX deployment normally leaves several important decisions to whoever is installing it: where the database and the project files live, what the admin password is, and which AWX version you get. This example pins all three, and the point of pinning them is that the values are in files you can read and edit, rather than in a chart default that changes when upstream does something.
Four properties are listed up front. It is accessible over HTTPS from a remote host. All data is stored under /data. The passwords for AWX and PostgreSQL are fixed but configurable. And the AWX version is fixed but configurable. That is a fair summary of what the repository adds over the upstream documentation.
The top-level layout shows how much is bundled. There is base/ for the AWX instance configuration, operator/ for the operator manifests, and then directories for the things that surround a working AWX install: backup/ and restore/, an acme/ directory for using a certificate from a public ACME CA instead of the self-signed one, an argocd/ directory, a builder/ directory, a containergroup/, a galaxy/ directory, a registry/, a runner/, a rulebooks/ directory and a git/ directory. The tips/ directory holds the guide for deploying an older operator version.
The primary language of the repository is listed as Dockerfile, which is a hint about how the packaging is done, and the licence is MIT with the terms in the LICENSE file. There are no GitHub releases, and the last push was on 2026-04-04.
The host preparation starts by turning the firewall off
The deployment guide begins on a CentOS Stream 9 host with a minimal install, and the first thing it asks you to do is disable firewalld and nm-cloud-setup if they are enabled. The README links this to the K3s installation requirements page, describing it as recommended by K3s.
The commands are:
# Disable firewalld
sudo systemctl disable firewalld --now
# Disable nm-cloud-setup if exists and enabled
sudo systemctl disable nm-cloud-setup.service nm-cloud-setup.timer
sudo rebootThis is worth pausing on rather than copying blindly. Disabling the host firewall is standard practice for a single-node Kubernetes node in a lab, and K3s documentation recommends it, but it means the security of the host then rests entirely on the network you put it on. The guide's other property, that the instance is reachable over HTTPS from a remote host, is the reason a firewall would be in the way at all, and the reason it is turned off rather than opened for a port.
If you are following this on a machine that is not a dedicated lab host, adding the specific port to the firewall instead of disabling the service is the safer change, and nothing in the deployment depends on the service being off.
The next step installs the two tools the guide needs:
sudo dnf install -y git curlGit is needed to clone this repository, and curl is needed for the K3s install script, which is the next step.
K3s is pinned to a version and the kubeconfig is made readable on purpose
The K3s install is a single line with two deliberate choices in it, and both of them matter.
curl -sfL https://get.k3s.io | INSTALL_K3S_VERSION=v1.29.6+k3s2 sh -s - --write-kubeconfig-mode 644The first choice is the version. The environment section records the tested combination as CentOS Stream 9 in minimal form, K3s v1.29.6+k3s2, with AWX Operator 2.19.1, AWX 24.6.1 and PostgreSQL 15 as the products deployed. Pinning the version in the install command means the cluster you build is the cluster the guide was written against, and it means an upgrade is a deliberate edit rather than something that happens because a script fetched a newer build.
The second choice is --write-kubeconfig-mode 644, which the README explains as making the config file at /etc/rancher/k3s/k3s.yaml readable by non-root users. Every later command in the guide runs kubectl without sudo, so without that flag the operator deployment and the instance deployment would both fail with a permission error on the kubeconfig.
The guide then clones this repository and checks out the tag matching the operator version you want:
cd ~
git clone https://github.com/kurokobo/awx-on-k3s.git
cd awx-on-k3s
git checkout 2.19.1+20260320.1The tag convention is visible here: the operator version, a plus, and a build date. The README points out that if you want files suitable for a specific AWX Operator version you should refer to the tags in the repository and specify the desired tag in git checkout, and that for operator versions at 0.13.0 or earlier there is a separate tips document for deploying an older operator. The same instruction appears at the top of the guide in a slightly different form, telling the reader to switch the page to the desired tag rather than reading main, which is a neat way of versioning a document and its configuration together.
Applying the operator is then a single kustomize apply, and the operator lands in its own namespace:
kubectl apply -k operatorThe expected output shown in the guide includes a running controller manager pod, a metrics service and the deployment and replicaset rows, all in the awx namespace.
The certificate step is where a remote hostname has to exist first
Before AWX itself is deployed, the instance configuration is prepared, and the first of those steps is generating a TLS certificate.
AWX_HOST="awx.example.com"
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}"The README notes that an IP address cannot be specified, which is a direct consequence of the subjectAltName being a DNS entry. If you want a certificate from a public ACME CA such as Let's Encrypt or ZeroSSL instead of a self-signed one, there is a separate guide in the acme directory to follow first, and you come back to this step when it is done.
The certificate files are written into the base directory, which means the Kustomize base references them by path. After generating them, you edit the hostname in the base/awx.yaml file so the ingress points at the name you chose, and the ingress type is set to ingress with a tls_secret named awx-secret-tls.
This is the step that most often needs a decision before it is executed. The hostname has to resolve on the machine you will connect from, or at least be in the hosts file, because the certificate is issued for that name and the browser will refuse to connect to a different one. Getting this wrong produces a warning rather than a failure, which is easy to misread as a broken deployment.
The ten year validity on the self-signed certificate is worth noting too. It is long enough that you will not have to think about it, and long enough that a stale certificate will still be trusted by a browser that has seen it before.
Passwords live in a kustomization file, with a rule about characters
The credentials are not managed in the AWX UI and not generated. They are two entries in the base/kustomization.yaml file, and the README is specific about how to change them.
The first is a secret named awx-postgres-configuration, which carries the connection details for the PostgreSQL instance as key and value literals: the host awx-postgres-15, the port 5432, the database awx, the username awx, a password and the type managed. The second is a secret named awx-admin-password carrying the AWX admin password.
The rule about the password characters is the part that will bite you. The README notes that the password under awx-postgres-configuration should not contain single or double quotes or backslashes, to avoid issues during deployment, backup or restoration.
That is a specific and believable constraint. A value that goes into a Kustomize secret literal and is then consumed by a job during deployment or by a restore procedure is being passed through shell and YAML quoting layers, and the characters that are meaningful in those layers are exactly the ones that break. The same rule is not repeated for the admin password secret, which suggests the constraint comes from how the database password is used rather than from the mechanism generally.
The rest of the storage preparation is three commands creating the directories that the persistent volumes in base/pv.yaml point at:
sudo mkdir -p /data/postgres-15
sudo mkdir -p /data/projects
sudo chown 1000:0 /data/projectsThe README explains an important subtlety about those volumes. The size of the persistent volumes and claims is specified in some of the files in the repository, but since their backends are hostPath, the size value is effectively just a label with no actual capacity limitation. The directory you create is what determines how much space AWX can use, which is why the requirements section insists on at least 10 GiB for /data and says both paths will grow during their lifetime and that actual consumption depends on your environment and use case.
Editorial conclusion
awx-on-k3s is worth following if you want one place to see how every moving part of an AWX Operator deployment is wired, because the repository is the guide and the configuration at once, so a Kustomize base, a kustomization with the credentials and a directory of persistent volume paths sit next to the instructions that create them. It is the wrong tool if you want a production multi-node cluster, since the whole thing is scoped to a single node, and it is the wrong tool if you cannot accept fixed passwords in a committed file. Before you deploy it, verify three things yourself: that your host has the stated minimums of 2 CPUs, 4 GiB of RAM and 10 GiB on each of the two storage paths, that the AWX Operator version you intend to use is one of the tags in the repository, since the guide says to switch to the matching tag, and that the certificate you generate is the one your browser will trust, because the self-signed route in the guide produces a certificate for a hostname you choose and an IP address cannot be used.
Frequently asked questions
What does the awx-on-k3s repository contain?
It is an example implementation of AWX on a single-node K3s cluster using the AWX Operator, with a simplified configuration where the data paths, the AWX and PostgreSQL passwords and the AWX version are all fixed but configurable in files you edit. The guide and the Kustomize configuration live in the same repository.
What are the hardware requirements for awx-on-k3s?
At least 2 CPUs, with both AMD64 with x86-64-v2 support and ARM64 supported, and 4 GiB of RAM minimum. The guide recommends 4 CPUs and 8 GiB or more to avoid performance and job scheduling issues, and at least 10 GiB each for /var/lib/rancher and /data.
How do I install K3s in the way this guide expects?
The guide runs curl -sfL https://get.k3s.io with INSTALL_K3S_VERSION=v1.29.6+k3s2 and the --write-kubeconfig-mode 644 flag, which the README explains makes /etc/rancher/k3s/k3s.yaml readable by non-root users so the later kubectl commands can run without sudo.
How do I use a different AWX Operator version with this example?
Clone the repository and check out the tag that matches the operator version you want, for example git checkout 2.19.1+20260320.1. The README points to the tags in the repository and to a separate tips document for operator versions at 0.13.0 or earlier.
Why does the AWX hostname have to be a DNS name rather than an IP address?
The self-signed certificate is generated with openssl req and a subjectAltName of DNS: followed by the hostname, and the README notes that an IP address cannot be specified. If you want a public certificate from an ACME CA such as Let's Encrypt or ZeroSSL, a separate guide in the acme directory covers that route.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/kurokobo-awx-on-k3s)Was this useful?