More

    AWX on Kubernetes/OpenShift

    Ansible AWX provides a RESTful API, web interface and a task engine that is built on top of Ansible. It is the upstream project for Red Hat Ansible Automation Platform.

    Persistent Volume

    We need storage to persist AWX data. There is no limitation on the type of storage that has already been integrated with the OpenShift or K8 cluster.

    Storage class

    A K8 StorageClass describes and classifies storage that can be requested, as well as provides a means for passing parameters for dynamically provisioned storage on demand – it abstract the details of underlying storage in a simple fashion.

    Query the current storage classes from your cluster:

    oc get sc
    NAME                                  PROVISIONER                                 RECLAIMPOLICY   VOLUMEBINDINGMODE      ALLOWVOLUMEEXPANSION   AGE
    cephfs                                ceph.com/cephfs                             Delete          Immediate              false                  712d
    nfs                                   cluster.local/wso2-nfs-server-provisioner   Delete          Immediate              true                   49d
    ocs-storagecluster-cephfs (default)   openshift-storage.cephfs.csi.ceph.com       Delete          Immediate              true                   299d
    
    

     

    In our case, we shall use ocs-storagecluster-cephfs (default) StorageClass.

    Tools

    Make Tools and Git

    Ensure that you have installed Git and Make Tools on your bastion host that you’re using to interact with your OpenShift/K8 cluster.

    RHEL based systems

    #RHEL based systems #
    
    sudo yum install curl jq
    
    
    Updated:
      git.x86_64 0:1.8.3.1-25.el7_9                                                                                                                                      
    
    Dependency Updated:
      perl-Git.noarch 0:1.8.3.1-25.el7_9                                                                                                                                 
    
    Complete!
    

    Dev Tools

    sudo yum group install "Development Tools"
    
    
    Installing for group install "Development Tools":
     bison                                         x86_64                          3.0.4-2.el7                                    base                             674 k
     byacc                                         x86_64                          1.9.20130304-3.el7                             base                              65 k
     cscope                                        x86_64                          15.8-10.el7                                    base                             203 k
     ctags                                         x86_64                          5.8-13.el7                                     base                             155 k
     diffstat                                      x86_64                          1.57-4.el7                                     base                              35 k
     doxygen                                       x86_64                          1:1.8.5-4.el7                                  base                             3.6 M
    
    ...
    
    Installed:
      bison.x86_64 0:3.0.4-2.el7            byacc.x86_64 0:1.9.20130304-3.el7                 cscope.x86_64 0:15.8-10.el7           ctags.x86_64 0:5.8-13.el7           
      diffstat.x86_64 0:1.57-4.el7          doxygen.x86_64 1:1.8.5-4.el7                      elfutils.x86_64 0:0.176-5.el7         flex.x86_64 0:2.5.37-6.el7          
      gcc-gfortran.x86_64 0:4.8.5-44.el7    indent.x86_64 0:2.2.11-13.el7                     intltool.noarch 0:0.50.2-7.el7        patchutils.x86_64 0:0.3.3-5.el7_9   
      rcs.x86_64 0:5.9.0-7.el7              redhat-rpm-config.noarch 0:9.1.0-88.el7.centos    rpm-build.x86_64 0:4.11.3-48.el7_9    rpm-sign.x86_64 0:4.11.3-48.el7_9   
      subversion.x86_64 0:1.7.14-16.el7     swig.x86_64 0:2.0.10-5.el7                        systemtap.x86_64 0:4.0-13.el7        
    
    Dependency Installed:
      boost-date-time.x86_64 0:1.53.0-28.el7                    bzip2.x86_64 0:1.0.6-13.el7                           dwz.x86_64 0:0.11-3.el7                           
      dyninst.x86_64 0:9.3.1-3.el7                              efivar-libs.x86_64 0:36-12.el7                        emacs-filesystem.noarch 1:24.3-23.el7_9.1         
      gdb.x86_64 0:7.6.1-120.el7                                gettext-common-devel.noarch 0:0.19.8.1-3.el7          gettext-devel.x86_64 0:0.19.8.1-3.el7             
      kernel-debug-devel.x86_64 0:3.10.0-1160.95.1.el7          libdwarf.x86_64 0:20130207-4.el7                      libgfortran.x86_64 0:4.8.5-44.el7                 
      libmodman.x86_64 0:2.0.1-8.el7                            libproxy.x86_64 0:0.4.11-11.el7                       libquadmath.x86_64 0:4.8.5-44.el7                 
      libquadmath-devel.x86_64 0:4.8.5-44.el7                   mokutil.x86_64 0:15-8.el7                             neon.x86_64 0:0.30.0-4.el7                        
      pakchois.x86_64 0:0.4-10.el7                              perl-XML-Parser.x86_64 0:2.41-10.el7                  perl-srpm-macros.noarch 0:1-8.el7                 
      python-srpm-macros.noarch 0:3-34.el7                      subversion-libs.x86_64 0:1.7.14-16.el7                systemtap-client.x86_64 0:4.0-13.el7              
      systemtap-devel.x86_64 0:4.0-13.el7                       systemtap-runtime.x86_64 0:4.0-13.el7                
    
    Complete!
    

     

    Debian

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

     

    AWX Installation on OpenShift/K8

    Download the AWX Operator

    git clone to download the operator to your host.

    [root@svdt8bastion ~]# git clone https://github.com/ansible/awx-operator.git
    
    Cloning into 'awx-operator'...
    remote: Enumerating objects: 9223, done.
    remote: Counting objects: 100% (1938/1938), done.
    remote: Compressing objects: 100% (287/287), done.
    remote: Total 9223 (delta 1745), reused 1702 (delta 1647), pack-reused 7285
    Receiving objects: 100% (9223/9223), 2.47 MiB | 0 bytes/s, done.
    Resolving deltas: 100% (5331/5331), done.
    

     

    Create AWX namespace

    OpenShift

    export NAMESPACE=ansible-awx
    oc create ns ${NAMESPACE}
    
    
    

     

    K8s

    export NAMESPACE=ansible-awx
    kubectl create ns ${NAMESPACE}

     

    Switch to the created namespace

    # oc project ${NAMESPACE}
    Now using project "ansible-awx" on server "https://api.ocp.technnix.net:6443".

     

    Release tag

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

     

    Expected output

    # git checkout $AWX_RELEASE_TAG
    Note: checking out '2.5.2'.
    
    You are in 'detached HEAD' state. You can look around, make experimental
    changes and commit them, and you can discard any commits you make in this
    state without impacting any branches by performing another checkout.
    
    If you want to create a new branch to retain commits you create, you may
    do so (now or later) by using -b with the checkout command again. Example:
    
      git checkout -b new_branch_name
    
    HEAD is now at 7012a6a... Modify how pg password is set in postgres pod (#1540)

     

    Deploy AWS operator to the OpenShift/K8s cluster

    export NAMESPACE=ansible-awx
    make deploy

     

    Expected output

    usage: git ls-remote [--heads] [--tags]  [-u <exec> | --upload-pack <exec>]
                         [-q|--quiet] [--exit-code] [--get-url] [<repository> [<refs>...]]
    Warning: kubectl apply should be used on resource created by either kubectl create --save-config or kubectl apply
    namespace/ansible-awx configured
    customresourcedefinition.apiextensions.k8s.io/awxbackups.awx.ansible.com configured
    customresourcedefinition.apiextensions.k8s.io/awxrestores.awx.ansible.com configured
    customresourcedefinition.apiextensions.k8s.io/awxs.awx.ansible.com configured
    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 unchanged
    clusterrole.rbac.authorization.k8s.io/awx-operator-proxy-role unchanged
    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 configured
    configmap/awx-operator-awx-manager-config created
    service/awx-operator-controller-manager-metrics-service created
    deployment.apps/awx-operator-controller-manager created

     

    After successful deployment of the operator, check the running pods

    oc get po
    NAME                                               READY   STATUS                   RESTARTS   AGE
    awx-operator-controller-manager-6544864fcd-rdpzr   2/2     Running                  0          2m12s
    awx-operator-controller-manager-6544864fcd-sb6sm   0/2     ContainerStatusUnknown   2          3m48s
    

     

    Install AWX on OpenShift

    PVC

    cat <<EOF | kubectl create -f -
    apiVersion: v1
    kind: PersistentVolumeClaim
    metadata:
      name: awx-data-pvc
      namespace: ansible-awx
    spec:
      accessModes:
        - ReadWriteMany
      storageClassName: ocs-storagecluster-cephfs
      resources:
        requests:
          storage: 10Gi
    EOF

     

    Expected output

    persistentvolumeclaim/awx-data-pvc created

     

    PVC created successfully

    oc get pvc
    
    NAME           STATUS   VOLUME                                     CAPACITY   ACCESS MODES   STORAGECLASS                AGE
    awx-data-pvc   Bound    pvc-8ea4b8c1-535e-4bcc-b129-95e6b6e2268e   10Gi       RWX            ocs-storagecluster-cephfs   94s

     

    Create AWX deployment File

    Lets deploy AWX instance by creating an ansible-awx.yaml file with following content.

    vim ansible-awx-deployment.yaml

    ---
    apiVersion: awx.ansible.com/v1beta1
    kind: AWX
    metadata:
      name: ansible-awx
    spec:
      service_type: ClusterIP
      projects_persistence: true
      projects_storage_access_mode: ReadWriteMany
      web_extra_volume_mounts: |
        - name: static-data
          mountPath: /var/lib/projects
      extra_volumes: |
        - name: static-data
          persistentVolumeClaim:
            claimName:  awx-data-pvc

     

    Deploy

    #  oc apply -f ansible-awx-deployment.yaml
    
    awx.awx.ansible.com/ansible-awx created

     

    Check pods

    oc get po
    
    NAME                                               READY   STATUS    RESTARTS   AGE
    ansible-awx-postgres-13-0                          1/1     Running   0          14h
    ansible-awx-task-675bb6846d-7lhgj                  4/4     Running   0          13h
    ansible-awx-web-66d967d896-7h7tk                   3/3     Running   0          12h
    awx-operator-controller-manager-6544864fcd-rdpzr   2/2     Running   0          21h

     

     

    Access AWX Container Shell

    Get the deployment

    oc get deployment
    
    NAME                              READY   UP-TO-DATE   AVAILABLE   AGE
    ansible-awx-task                  1/1     1            1           16h
    ansible-awx-web                   1/1     1            1           16h
    awx-operator-controller-manager   1/1     1            1           21h
    

     

    Access container shell

     

    oc exec -ti deploy/ansible-awx-task -c  ansible-awx-task -- /bin/bash
    oc exec -ti deploy/ansible-awx-web -c  ansible-awx-web -- /bin/bash
    
    

     

    Expose the AWX service

    A K8 service is an abstraction layer that defines a logical set of pods and enables external traffic exposure, service discovery and load balancing for those pods.

    Check the services in the ansible-awx namespace. Take a keen interest in the ansible-awx-service through the ClusterIP.

    oc get svc
    
    NAME                                              TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)    AGE
    ansible-awx-postgres-13                           ClusterIP   None             <none>        5432/TCP   2d18h
    ansible-awx-service                               ClusterIP   172.30.251.48    <none>        80/TCP     2d18h
    awx-operator-controller-manager-metrics-service   ClusterIP   172.30.227.128   <none>        8443/TCP   2d22h
    

     

    At this stage, the assumption is that you already have an OpenShift/K8 cluster with an ingress controller. We can epose the servie through a route using the ingress .

    Check the DNS records for the OpenShift ingress.

    # nslookup *.apps.devocp.technnix.net
    
    Server:		xx.xx.xx.xx
    Address:	xx.xx.xx.xx#53
    
    Name:	*.apps.devocp.technnix.net
    Address: 10.196.101.31
    

     

    To display your default OpenShift ingress domain, run the following command:

    # oc get ingresses.config/cluster -o jsonpath={.spec.domain}
    
    apps.devocp.technnix.net
    

     

    Create route configuration manifest for AWX. A route allows us to host our application(AWX) at a public URL.

    Please note the following elements in the manifest:

    spec:
      host: ansible-awx.apps.devocp.technnix.net
      to:
        kind: Service
        name: ansible-awx-service
        weight: 100
      port:
        targetPort: http
    

     

    YAML AWX Route Manifest Definition:

    kind: Route
    apiVersion: route.openshift.io/v1
    metadata:
      name: ansible-awx
      managedFields:
        - manager: OpenAPI-Generator
          operation: Update
          apiVersion: route.openshift.io/v1
          fieldsType: FieldsV1
    
        - manager: openshift-router
          operation: Update
          apiVersion: route.openshift.io/v1
      namespace: ansible-awx
      labels:
        app.kubernetes.io/component: awx
        app.kubernetes.io/managed-by: awx-operator
        app.kubernetes.io/operator-version: 2.2.1
        app.kubernetes.io/part-of: ansible-awx
    spec:
      host: ansible-awx.apps.devocp.technnix.net
      to:
        kind: Service
        name: ansible-awx-service
        weight: 100
      port:
        targetPort: http
      tls:
        termination: edge
        insecureEdgeTerminationPolicy: Redirect
      wildcardPolicy: None
    status:
      ingress:
        - host: ansible-awx.apps.devocp.technnix.net
          routerName: default
          wildcardPolicy: None
          routerCanonicalHostname: router-default.apps.devocp.technnix.net
    

     

    Deploy the route yaml file

    oc apply -f awx-route.yaml
    
    route.route.openshift.io/ansible-awx created

     

    Validate the created route

    oc get routes
    
    NAME                  HOST/PORT                                                   PATH   SERVICES              PORT   TERMINATION     WILDCARD
    ansible-awx           ansible-awx.apps.devocp.technnix.net                              ansible-awx-service   http   edge/Redirect   None
    ansible-awx-service   ansible-awx-service-ansible-awx.apps.devocp.technnix.net          ansible-awx-service   http                   None
    

     

    Access the AWX Web console

    Access the web console from the URL above:  http://ansible-awx.apps.devocp.technnix.net .

    AWX Dashboard
    AWX Dashboard

    Extract the admin password

    From your namespace, lets extract the admin password

    # oc get secrets | grep -i admin-password
    
    ansible-awx-admin-password                        Opaque                                1      18h
    

     

    # oc get secret ansible-awx-admin-password -o jsonpath="{.data.password}" -n awx | base64 --decode ; echo
    
    ru0Wq6LP9dAJrbZZTI4tX7IH4WVBGaSk
    
    

    Use the password displayed to login to the Dashboard

    Username : admin

    Password : <password>

    Recent Articles

    Related Articles

    Leave A Reply

    Please enter your comment!
    Please enter your name here