Friday, December 27, 2024
Google search engine
HomeGuest BlogsHow To Run Ansible AWX on Kubernetes / OpenShift Cluster

How To Run Ansible AWX on Kubernetes / OpenShift Cluster

Welcome to today’s article on how to install, configure and use Ansible AWX on Kubernetes / OpenShift Cluster. Ansible AWX is a popular web-based platform created to provide a user-friendly interface for Ansible automation operations. AWX is built on top of the Ansible project and it gives you a centralized management for all Ansible inventories and playbooks.

From the dashboard you can manage inventory, run and schedule Ansible playbooks, monitor job activity and execution results. The built-in RBAC (role-based access control) is used for managing access to resources within AWX platform. An integration with other tools such as Git for version control is also possible.

Key features of Ansible AWX:

  • Centralized management: It offers centralized management for Ansible playbooks and inventories for ease of administration.
  • Role-based access control: With the built-in RBAC you can ensure there is a secure and efficient management of automation tasks.
  • Web-based user interface: AWX comes with an intuitive user-friendly web interface for managing Ansible playbooks, inventory, and automation tasks.
  • Third-party integrations: Integration with other tools such as Git for version control can be done making it easy to manage and track changes to Ansible playbooks over time.
  • Reporting and analytics: AWX has reporting and analytics capabilities for tracking performance and gains from its use.

Run Ansible AWX on Kubernetes / OpenShift Cluster

In this section we’ll cover the full process of installing Ansible AWX on Kubernetes / OpenShift Cluster. A major pre-requisite for this operation is existing Kubernetes / OpenShift cluster.

Step 1: Deploy Kubernetes Cluster

You can use existing articles on our website to setup a cluster.

Once the cluster is deployed and running confirm using kubectl command:

$ kubectl cluster-info
Kubernetes control plane is running at https://api.k8s.cloudlabske.io:6443

To further debug and diagnose cluster problems, use 'kubectl cluster-info dump'.

Step 2: Deploy MetalLB / Ingress solution

For Kubernetes clusters deployed on your on-prem infrastructure you’ll need a solution that provides Load Balancing feature and Ingress solution. For managed Kubernetes clusters such as ones provided by cloud providers like EKS, AKS and GKE, a manual setup is not required for LB.

We have existing articles on this setup.

Step 3: Configure Persistent Storage Solution

We’ll need persistent storage for AWX data. Any solution integrated to Kubernetes can be used for this. Refer to some of the guides available in our website.

In this setup we’re using NFS storage class to automatically provision persistent volumes on Kubernetes.

$ kubectl get sc
NAME               PROVISIONER          RECLAIMPOLICY   VOLUMEBINDINGMODE   ALLOWVOLUMEEXPANSION   AGE
nfs-01 (default)   nfs-provisioner-01   Delete          Immediate           true                   53d

This will be used when deploying AWX on Kubernetes / OpenShift cluster.

Step 4: Deploy AWX Operator on Kubernetes

We shall use the AWX Kubernetes Operator meant to be deployed in your Kubernetes cluster(s) and can manage one or more AWX instances in any namespace.

Install git and make tools:

### Ubuntu / Debian ###
sudo apt update
sudo apt install git build-essential curl jq  -y

### RHEL based systems ###
sudo yum -y install epel-release
sudo yum group install "Development Tools"
sudo yum install curl jq

Use git to clone Operator project source to your workstation with kubectl configured.

$ git clone https://github.com/ansible/awx-operator.git
Cloning into 'awx-operator'...
remote: Enumerating objects: 7925, done.
remote: Counting objects: 100% (403/403), done.
remote: Compressing objects: 100% (256/256), done.
remote: Total 7925 (delta 187), reused 316 (delta 121), pack-reused 7522
Receiving objects: 100% (7925/7925), 2.19 MiB | 739.00 KiB/s, done.
Resolving deltas: 100% (4498/4498), done.

Next we create a namespace where operator will be deployed. We’ll name this awx:

export NAMESPACE=awx
kubectl create ns ${NAMESPACE}

Set current context to value set in NAMESPACE variable:

# kubectl config set-context --current --namespace=$NAMESPACE 
Context "default" modified.

Switch to awx-operator directory:

cd awx-operator/

Save the latest version from AWX Operator releases as RELEASE_TAG variable then checkout to the branch.

RELEASE_TAG=`curl -s https://api.github.com/repos/ansible/awx-operator/releases/latest | grep tag_name | cut -d '"' -f 4`
echo $RELEASE_TAG
git checkout $RELEASE_TAG

Install AWX Operator into your Kubernetes cluster:

export NAMESPACE=awx
make deploy

Successful execution output:

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

Wait for the operator pod creation to be successful. The status should be running

$ kubectl get pods -w
NAME                                               READY   STATUS              RESTARTS   AGE
awx-operator-controller-manager-65b875f4bf-757vt   0/2     ContainerCreating   0          68s

Step 5: Install Ansible AWX on Kubernetes

With the AWX operator running we can use it to install AWX instance on the cluster. But first we have to create static data PVC – Ref AWX data persistence:

cat <<EOF | kubectl create -f -
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: awx-static-data-pvc
  namespace: awx
spec:
  accessModes:
    - ReadWriteOnce
  storageClassName: nfs-01
  resources:
    requests:
      storage: 10Gi
EOF

Confirm if the PVC is created successfully.

$ kubectl get pvc
NAME                  STATUS   VOLUME                                     CAPACITY   ACCESS MODES   STORAGECLASS   AGE
awx-static-data-pvc   Bound    pvc-184cec87-8447-4055-a672-55fe264acb27   10Gi       RWO            nfs-01         28s

Now create AWX deployment file. See example below.

$ vim awx-deployment.yml
---
apiVersion: awx.ansible.com/v1beta1
kind: AWX
metadata:
  name: awx
spec:
  service_type: nodeport
  projects_persistence: true
  projects_storage_access_mode: ReadWriteOnce
  web_extra_volume_mounts: |
    - name: static-data
      mountPath: /var/lib/projects
  extra_volumes: |
    - name: static-data
      persistentVolumeClaim:
        claimName:  awx-static-data-pvc

If the service_type is not specified, the ClusterIP service will be used for your AWX Tower service. The service_type supported options are: ClusterIPLoadBalancer and NodePort.

Apply configuration file.

$ kubectl apply -f awx-deployment.yml
awx.awx.ansible.com/awx created

Give it a few seconds and AWX instance will be deployed and running:

$ kubectl get pods -l "app.kubernetes.io/managed-by=awx-operator" -w
NAME                  READY   STATUS    RESTARTS   AGE
awx-74bd7c8bc-4mqbb   4/4     Running   0          15m
awx-postgres-13-0     1/1     Running   0          31m

 You can track the installation process at the operator pod logs:

kubectl logs -f deployments/awx-operator-controller-manager -c awx-manager

Listing PVCs in the namespace:

$ kubectl get pvc
NAME                            STATUS   VOLUME                                     CAPACITY   ACCESS MODES   STORAGECLASS   AGE
awx-projects-claim              Bound    pvc-188c3463-65c0-4265-a00d-2a8573894ca7   8Gi        RWO            nfs-01         33m
awx-static-data-pvc             Bound    pvc-184cec87-8447-4055-a672-55fe264acb27   10Gi       RWO            nfs-01         49m
postgres-13-awx-postgres-13-0   Bound    pvc-84b68384-3c9c-4f81-bfab-f083c1cf10cd   8Gi        RWO            nfs-01         36m

Checking AWX Container’s logs

The awx-xxx-yyy pod will have four containers, namely:

  • redis
  • awx-web
  • awx-task
  • awx-ee

As can be seen from below command output:

# kubectl -n awx  logs deploy/awx
error: a container name must be specified for pod awx-75698588d6-r7bxl, choose one of: [redis awx-web awx-task awx-ee]

You’ll need to provide container name after the pod:

kubectl -n awx  logs deploy/awx -c redis
kubectl -n awx  logs deploy/awx -c awx-web
kubectl -n awx  logs deploy/awx -c awx-task
kubectl -n awx  logs deploy/awx -c awx-ee

Access AWX Container’s Shell

Here is how to access each container’s shell:

kubectl exec -ti deploy/awx  -c  awx-task -- /bin/bash
kubectl exec -ti deploy/awx  -c  awx-web -- /bin/bash
kubectl exec -ti deploy/awx  -c  awx-ee -- /bin/bash
kubectl exec -ti deploy/awx  -c  redis -- /bin/bash

Upgrading AWX Operator and instance

We have created a dedicated guide for upgrading the Operator and AWX instance:

Step 6: Access Ansible AWX Dashboard

List all available services and check awx-service Nodeport

$ kubectl get svc
NAME                                              TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)        AGE
awx-operator-controller-manager-metrics-service   ClusterIP   10.233.25.242   <none>        8443/TCP       64m
awx-postgres-13                                   ClusterIP   None            <none>        5432/TCP       41m
awx-service                                       NodePort    10.233.28.124   <none>        80:30080/TCP   38m

From the output the service type is set to NodePort. Provide one of the cluster’s node IP address and port to access AWX web console.

http://hostip_or_hostname:30080

On accessing AWX web portal you are presented with the welcome dashboard similar to one below.

image

The login username is admin. To get the password run the commands below:

kubectl get secret awx-admin-password -o go-template='{{range $k,$v := .data}}{{printf "%s: " $k}}{{if not $v}}{{$v}}{{else}}{{$v | base64decode}}{{end}}{{"\n"}}{{end}}'

Login with admin username and decoded password:

image 3

The new AWX interface is beautifully designed with Love. It is a serious redesign with good polishing.

image 2

Step 7: Using LoadBalancer Service (Optional)

We can create service configuration for load balancer service. Ensure AWX service is running and you have MetalLB installed and configured properly in your cluster.

$ vim awx-lb-service.yaml
apiVersion: v1
kind: Service
metadata:
  name: awx-lb-service
  namespace: awx
  labels:
    app.kubernetes.io/component: awx
    app.kubernetes.io/name: awx
    app.kubernetes.io/part-of: awx
spec:
  ports:
  - name: http
    port: 80
    protocol: TCP
    targetPort: 8052
  selector:
    app.kubernetes.io/component: awx
    app.kubernetes.io/name: awx
  sessionAffinity: None
  type: LoadBalancer

Create service using defined manifest file.

$ kubectl apply -f awx-lb-service.yaml
service/awx-lb-service created

We can confirm it works by listing service called awx-lb-service in the namespace.

$  kubectl get svc awx-lb-service
NAME             TYPE           CLUSTER-IP     EXTERNAL-IP    PORT(S)        AGE
awx-lb-service   LoadBalancer   10.233.2.203   192.168.1.32   80:30791/TCP   5m9s

Test connectivity to AWX web interface using Load Balancer IP address.

ansible awx lb ui

Step 8: Configure Ingress route

You can use an Ingress controller such as Nginx to expose AWX service, see guide in the link given below:

Books For Learning Kubernetes Administration;

Conclusion

To this end we’ve completed the installation, configuration and basic usage of Ansible AWX on Kubernetes. In summary, AWX provides a graphical interface for managing Ansible playbooks, while Ansible Operator is a way to automate the deployment and management of those playbooks using Kubernetes. In the article to follow we shall discuss in detail the use of Ingress to access AWX instance deployed.

RELATED ARTICLES

Most Popular

Recent Comments