Ansible - AWX (1/2)

So, you wrote your first playbooks, played with collections and command line tools, and you consider to have a UI for Ansible?

Ansible - AWX (1/2)
Screenshot - AWX Dashboard

So, you wrote your first playbooks, played with collections and command line tools, and you consider to have a UI for Ansible? Maybe you heard about Ansible Tower or Ansible Automation platform already. AWX is one of the Open Source upstream developments for these tools and in this article, we will deploy AWX and add our first content to it.

Ansible

Ansible is the Open Source automation software for small use cases or entire cloud ecosystems. With just a bit of YAML, you can start to automate your package installations, network configuration or Kubernetes on AWS.

In the past, I wrote a couple of articles about Ansible and also took a look at the ecosystem occasionally. In case you never heard of Ansible, you should start with one of my "Getting Started" articles.

AWX

AWX provides a web-based graphical interface and management solution, REST API, and task engine built on top of Ansible. This is mostly interesting for advanced Ansible use cases. It is one of the upstream projects for Red Hat Ansible Automation Platform.

In addition, it adds a lot of functionality to your automation, including credential management, inventory synchronization, or a workflow abstraction. Well, it can be a bit overwhelming at first. Let's see how it works and how you can get started.

Setup AWX

Before going any further, you need to understand that AWX requests you to use Kubernetes as the underlying platform. There are ways to install AWX via Docker, and even an RPM project, but the official and supported way is Kubernetes.

Kubernetes

Well, this article won't go into details about the Kubernetes setup. But, you are pretty good with minikube or k3s, for testing purposes. I tackled both in previous articles, already. For the sake of this article, I will stick to minikube on Fedora.

Kubernetes - k3s on AlmaLinux
In some past articles, I talked about Kubernetes and how to get started. Minikube is awesome for local development, but what about Kubernetes on small environments? k3s is one of the easiest ways to deploy and run a Kubernetes instance, which can also be used to create high available clusters.
Fedora - Minikube
Before digging into Kubernetes, you will need a minimal Kubernetes Setup. Such a setup should spin up fast, should work like a real cluster, and hopefully integrate well in other tools. For me, Minikube fulfills these needs, and you can run it on Fedora, too.
💡
The following guide was tested with Fedora 39 and Kubernetes v1.31.2. I used the AWX operator in version 2.14.0.

After the initial setup of minikube, you can start your Kubernetes cluster via:

# Start Kubernetes via Minikube
$ minikube start --cpus=4 --memory=6g --addons=ingress

😄  minikube v1.31.2 on Fedora 39
✨  Using the podman driver based on user configuration
🎉  minikube 1.32.0 is available! Download it: https://github.com/kubernetes/minikube/releases/tag/v1.32.0
💡  To disable this notice, run: 'minikube config set WantUpdateNotification false'

📌  Using Podman driver with root privileges
👍  Starting control plane node minikube in cluster minikube
🚜  Pulling base image ...

# Verify that the cluster is running
$ kubectl get nodes

NAME       STATUS   ROLES           AGE   VERSION
minikube   Ready    control-plane   73s   v1.27.4

# Verify that all pods are started
$ kubectl get pods -A

NAMESPACE       NAME                                        READY   STATUS      RESTARTS      AGE
ingress-nginx   ingress-nginx-admission-create-d5tgz        0/1     Completed   0             79s
ingress-nginx   ingress-nginx-admission-patch-2klbk         0/1     Completed   0             79s
ingress-nginx   ingress-nginx-controller-7799c6795f-57mkt   1/1     Running     0             78s
kube-system     coredns-5d78c9869d-r8fnz                    1/1     Running     0             78s
kube-system     etcd-minikube                               1/1     Running     0             91s
kube-system     kube-apiserver-minikube                     1/1     Running     0             93s
kube-system     kube-controller-manager-minikube            1/1     Running     0             91s
kube-system     kube-proxy-fdzhr                            1/1     Running     0             78s
kube-system     kube-scheduler-minikube                     1/1     Running     0             93s
kube-system     storage-provisioner                         1/1     Running     1 (47s ago)   90s

Installation

If you have access to a Kubernetes instance, it's time to install AWX. The process is really simple. The Ansible AWX team came up with a Kubernetes operator. There is still a helm chart available, but the operator is the preferred way to install AWX.

Anyway, using an operator is a two-step process. First, you are installing the operator itself, afterward, you will create an AWX instance.

Installing the operator

Installing the AWX operator requires cloning the repository and check out the desired version of the operator.

# Clone the repository
$ git clone git@github.com:ansible/awx-operator.git
$ cd awx-operator

# Check available tags
$ git tag
# Check out the desired version
$ git checkout tags/2.14.0

After this is done, we need to create a kustomization.yaml file. This can be achieved with the make command if it is on your machine.

$ make deploy

Otherwise, you need to create the file manually. It need to look like the below:

apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
namespace: awx

resources:
  - github.com/ansible/awx-operator/config/default?ref=<tag>

images:
  - name: quay.io/ansible/awx-operator
    newTag: <tag>

kustomization.yaml

Replace <tag> with the above checked out tag. In my case 2.14.0,

Now, we can apply the changes to Kubernetes.

# Install the operator
kubectl apply -k .

This is the part, where you can grab a coffee ☕ or tea 🍵. It will take a minute or two to deploy the operator. You can check the status with a simple command.

# Check status
$ kubectl get all -n awx
NAME                                                   READY   STATUS    RESTARTS   AGE
pod/awx-operator-controller-manager-7c4b7dd65d-w9bkz   2/2     Running   0          91s

NAME                                                      TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)    AGE
service/awx-operator-controller-manager-metrics-service   ClusterIP   10.108.164.14   <none>        8443/TCP   91s

NAME                                              READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/awx-operator-controller-manager   1/1     1            1           91s

NAME                                                         DESIRED   CURRENT   READY   AGE
replicaset.apps/awx-operator-controller-manager-7c4b7dd65d   1         1         1       91s

Installing AWX

Do you have your tea or coffee? Don't drink it right away, we have one more thing to do. Now that the operator is running, we need to tell it how we want our AWX. We need to create another YAML file, a custom resource to be precise. You can name it however you desire, so I opted for myawx.yaml.

The content of this file is just a couple of lines (for our simple use case, at least).

---
apiVersion: awx.ansible.com/v1beta1
kind: AWX
metadata:
  name: myawx
spec:
  service_type: nodeport

myawx.yaml

If this is done, we need to update the kustomization.yaml file, so it knows about our new file.

apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
namespace: awx

resources:
  - github.com/ansible/awx-operator/config/default?ref=2.14.0
  - myawx.yaml

images:
  - name: quay.io/ansible/awx-operator
    newTag: 2.14.0

kustomization.yaml

And finally, we can apply the config once more.

# Apply changes
$ kubectl apply -k .

namespace/awx unchanged
customresourcedefinition.apiextensions.k8s.io/awxbackups.awx.ansible.com unchanged
customresourcedefinition.apiextensions.k8s.io/awxmeshingresses.awx.ansible.com unchanged
customresourcedefinition.apiextensions.k8s.io/awxrestores.awx.ansible.com unchanged
customresourcedefinition.apiextensions.k8s.io/awxs.awx.ansible.com unchanged
serviceaccount/awx-operator-controller-manager unchanged
role.rbac.authorization.k8s.io/awx-operator-awx-manager-role configured
role.rbac.authorization.k8s.io/awx-operator-leader-election-role unchanged
clusterrole.rbac.authorization.k8s.io/awx-operator-metrics-reader unchanged
clusterrole.rbac.authorization.k8s.io/awx-operator-proxy-role unchanged
rolebinding.rbac.authorization.k8s.io/awx-operator-awx-manager-rolebinding unchanged
rolebinding.rbac.authorization.k8s.io/awx-operator-leader-election-rolebinding unchanged
clusterrolebinding.rbac.authorization.k8s.io/awx-operator-proxy-rolebinding unchanged
configmap/awx-operator-awx-manager-config unchanged
service/awx-operator-controller-manager-metrics-service unchanged
deployment.apps/awx-operator-controller-manager unchanged
awx.awx.ansible.com/myawx created

NOW is the time to drink your coffee ☕ or tea 🍵. Deploying AWX will take a couple of minutes. You can watch the operator do its thing, if you like.

# Watch the operator at work
$ kubectl -n awx logs -f deployments/awx-operator-controller-manager -c awx-manager

After some minutes you should see the new resources.

$ kubectl -n awx get pods -l "app.kubernetes.io/managed-by=awx-operator"NAME                          READY   STATUS    RESTARTS   AGE
myawx-postgres-15-0           1/1     Running   0          6m13s
myawx-task-55dcf8499f-5vzbv   4/4     Running   0          5m40s
myawx-web-77b9dfddfc-n6ht8    3/3     Running   0          5m41s

$ kubectl -n awx get svc -l "app.kubernetes.io/managed-by=awx-operator"NAME                TYPE        CLUSTER-IP    EXTERNAL-IP   PORT(S)        AGE
myawx-postgres-15   ClusterIP   None          <none>        5432/TCP       6m28s
myawx-service       NodePort    10.99.49.57   <none>        80:32336/TCP   5m57s

First Login

When everything is done and the operator reports that AWX is running, we can log in the first time. For our small development setup in minikube, the easiest way to do so is:

# Get the minikube url
$ minikube service -n awx myawx-service --url
http://192.168.49.2:32336

# Get the secret for login
$ kubectl -n awx get secret myawx-admin-password -o jsonpath="{.data.password}" | base64 --decode
7poeEydAh3ooDyFL5xPnGqhRAJSDz1K1

Just open the provided URL and be greeted by the login screen.

Screenshot - AWX Login

You can login with user: admin and password: <from the above command>. Finally, you will land in the AWX landing page.

Screenshot - AWX Dashboard

Continue(?!)

Since this article is already hitting the 1500 words mark, I opted to create two articles. Next week, I will give an overview of AWX and how you can get started with your first project.

If you feel impatient and want to read more about AWX, I have gathered some helpful links to get you started.

Ansible AWX Operator Documentation
GitHub - ansible/awx: AWX provides a web-based user interface, REST API, and task engine built on top of Ansible. It is one of the upstream projects for Red Hat Ansible Automation Platform.
AWX provides a web-based user interface, REST API, and task engine built on top of Ansible. It is one of the upstream projects for Red Hat Ansible Automation Platform. - ansible/awx
GitHub - ansible/awx-operator: An Ansible AWX operator for Kubernetes built with Operator SDK and Ansible. 🤖
An Ansible AWX operator for Kubernetes built with Operator SDK and Ansible. 🤖 - ansible/awx-operator
GitHub - kurokobo/awx-on-k3s: An example implementation of AWX on single node K3s using AWX Operator, with easy-to-use simplified configuration with ownership of data and passwords.
An example implementation of AWX on single node K3s using AWX Operator, with easy-to-use simplified configuration with ownership of data and passwords. - kurokobo/awx-on-k3s

Conclusion

Setting up AWX takes a bit more effort than alternatives or even the command line. Yet, it provides way more options and configurations than alternatives. The operator also made it straight forward to deploy multiple instances of AWX and play around with AWX for testing purposes.

But, let me know: Do you use AWX already? How was your deployment? What is your experience with it and has it met your expectations?