Ansible OEL 8 DevOps · OEL 8 · CI/CD

AnsibleAWX & Ansible Automation Platform

When the CLI isn't enough — AWX gives you a multi-user web UI, RBAC, scheduling, audit logs, surveys, and workflow templates. The architecture, the deploy on Kubernetes, and the AAP vs AWX commercial choice.

Running ansible-playbook from a laptop works for a single operator. The moment you have a team of 10, or compliance needs an audit trail, or junior engineers need to launch a deploy without SSH access to production — the CLI hits its limits. AWX (open source) and Ansible Automation Platform (Red Hat's commercial version) wrap Ansible with the multi-user infrastructure most teams need.

AWX / Ansible Automation Platform — multi-user, audited Users via browser / API AWX cluster (Kubernetes) Web + REST API RBAC, audit log Scheduler cron · webhooks · API Job queue (Redis) PostgreSQL state Execution Pod 1 runs ansible-playbook Execution Pod 2 scales horizontally Execution Pod N isolated · ephemeral SSH db1 target web1 target app1 target RBAC · approvals · scheduling · vault integration · multi-team isolation AWX = open source · Ansible Automation Platform = Red Hat commercial version
AWX (open source)AAP (commercial)
LicenseFree, Apache 2.0Red Hat subscription
SupportCommunity (GitHub issues)24×7 Red Hat support
InstallerOperator on Kubernetes onlyRPM installer · Kubernetes · OpenShift
UI / APIIdenticalIdentical (same codebase)
Certified collectionsNoYes — vendor-tested + supported
Insights / AnalyticsNoYes — automation analytics dashboard
Best forInternal tooling, labs, learningRegulated industries, large enterprises
💡 Tip: Most non-regulated companies run AWX in production successfully. The codebase is identical to AAP's. The differences are support and the curated collection content. Start with AWX, upgrade to AAP if you need the support contract.
ConceptEquivalent on the CLI
ProjectA git repo containing playbooks/roles
InventoryThe same hosts.ini / dynamic inventory
CredentialsVaulted SSH keys, vault passwords, cloud creds — managed centrally
Job TemplateA pre-configured ansible-playbook invocation
SurveyA form attached to a job template — collect input from non-Ansible users
ScheduleCron entries managed in the UI
Workflow TemplateDAG of job templates with success/failure branches
NotificationSlack / email / webhook on job events

AWX runs natively on Kubernetes via the AWX Operator. Once the operator is installed, you create a single AWX Custom Resource and the operator does the rest — deploys PostgreSQL, Redis, the web UI, and the execution pods.

BASH — install the AWX Operator
# 1. Clone the operator repo
git clone https://github.com/ansible/awx-operator.git
cd awx-operator

# 2. Pin to a stable release
git checkout 2.19.1

# 3. Install the operator into the awx namespace
export NAMESPACE=awx
make deploy

# 4. Watch the operator pod come up
kubectl -n awx get pods
# NAME                                   READY   STATUS    RESTARTS
# awx-operator-controller-manager-xxx    2/2     Running   0
YAML — kubectl apply this AWX CR
---
apiVersion: awx.ansible.com/v1beta1
kind: AWX
metadata:
  name: awx
  namespace: awx
spec:
  service_type: NodePort
  nodeport_port: 30080

  # PostgreSQL — operator deploys & manages
  postgres_storage_class: longhorn
  postgres_storage_requirements:
    requests:
      storage: 20Gi

  # Web replica count
  web_replicas: 2

  # Persistent project storage (your git checkouts)
  projects_persistence: true
  projects_storage_class: longhorn
  projects_storage_size: 10Gi

  # Default admin password — pulled from a Secret
  admin_user: admin
  admin_password_secret: awx-admin-password
BASH — admin password secret + first login
# Create the admin password secret BEFORE applying the AWX CR
kubectl -n awx create secret generic awx-admin-password \
  --from-literal=password="$(openssl rand -base64 24)"

# Apply the AWX CR (operator creates DB, redis, web, task pods)
kubectl apply -f awx.yml

# Wait ~5 minutes — watch progress
kubectl -n awx get pods -w

# Pull the admin password back out
kubectl -n awx get secret awx-admin-password \
  -o jsonpath="{.data.password}" | base64 -d

# Browse to: http://<node-ip>:30080

Click-ops in AWX is a trap — within a year the UI state drifts from what's in git. The awx.awx collection lets you declare every project, inventory, credential, and job template in YAML and apply it via Ansible. The UI then becomes read-only and audit-friendly.

YAML — bootstrap AWX config from inventory + roles
---
- name: Configure AWX from code
  hosts: localhost
  gather_facts: false
  collections:
    - awx.awx

  tasks:
    - name: Create the organisation
      organization:
        name: Vriddh-DBA
        description: Database team
        state: present

    - name: Register the playbook git repo as a Project
      project:
        name: db-automation
        organization: Vriddh-DBA
        scm_type: git
        scm_url: git@github.com:vriddh/db-automation.git
        scm_branch: main
        scm_credential: github-deploy-key
        scm_update_on_launch: true     # always pull latest before each job

    - name: Define the production inventory (sourced from project)
      inventory:
        name: production
        organization: Vriddh-DBA

    - name: Add SSH credential
      credential:
        name: ssh-deploy
        organization: Vriddh-DBA
        credential_type: Machine
        inputs:
          username: deploy
          ssh_key_data: "{{{{ lookup('file', 'deploy_key') }}}}"

    - name: Add Vault credential
      credential:
        name: vault-prod
        organization: Vriddh-DBA
        credential_type: Vault
        inputs:
          vault_password: "{{{{ vault_prod_password }}}}"
          vault_id: prod

    - name: Create the rolling-restart job template
      job_template:
        name: rolling_mysql_restart
        project: db-automation
        playbook: playbooks/rolling_restart_mysql.yml
        inventory: production
        credentials:
          - ssh-deploy
          - vault-prod
        ask_variables_on_launch: true

    - name: Schedule a nightly backup
      schedule:
        name: nightly_backups
        unified_job_template: nightly_db_backup
        rrule: "DTSTART:20260101T020000Z RRULE:FREQ=DAILY"

A junior on-call doesn't need to know Ansible vars. They click "Run rolling restart", fill out a 2-question form (which environment? which database?), hit submit. AWX runs the playbook with their answers as extra_vars:

YAML — survey definition
---
- name: Add a survey to the rolling-restart job template
  awx.awx.job_template:
    name: rolling_mysql_restart
    survey_enabled: true
    survey_spec:
      name: Rolling MySQL Restart
      description: Drains, restarts, and verifies one host at a time.
      spec:
        - question_name: Target environment
          variable: target_env
          type: multiplechoice
          choices:
            - dev
            - staging
            - production
          required: true

        - question_name: Restart all replicas or just one?
          variable: serial_count
          type: multiplechoice
          choices: ["1", "all"]
          default: "1"
          required: true

        - question_name: Reason for restart (audit log)
          variable: change_reason
          type: text
          required: true

For multi-step changes (deploy app, run migrations, restart services, run smoke tests), a workflow template chains job templates with success / failure branches:

YAML — declare a deploy workflow
---
- name: Define release workflow
  awx.awx.workflow_job_template:
    name: full_release
    organization: Vriddh-DBA
    workflow_nodes:
      - identifier: deploy_code
        unified_job_template:
          name: deploy_app
          type: job_template

      - identifier: run_migrations
        unified_job_template:
          name: run_db_migrations
          type: job_template
        related:
          success_nodes: []
          failure_nodes: []
          parents:
            - identifier: deploy_code   # only after deploy_code succeeds

      - identifier: rolling_restart
        unified_job_template:
          name: rolling_mysql_restart
          type: job_template
        related:
          parents:
            - identifier: run_migrations

      - identifier: smoke_tests
        unified_job_template:
          name: app_smoke_tests
          type: job_template
        related:
          parents:
            - identifier: rolling_restart

      - identifier: rollback
        unified_job_template:
          name: emergency_rollback
          type: job_template
        related:
          parents:
            - identifier: smoke_tests
              run: failure          # fires only on failure
RoleWhat they can do
System AdministratorEverything · global
Organisation AdminAll resources within an org
Project AdminEdit a specific project's job templates
Inventory AdminManage one inventory
Job Template ExecutorLaunch (but not edit) a specific job template
AuditorRead-only access to logs and configs
⚠ Warning: Tie AWX to your SSO (LDAP, SAML, OIDC) on day one. Don't create local users — when someone leaves, you want their access revoked from the central directory, not from a forgotten AWX user list.
✅ Tip: AWX turns Ansible from a single-operator tool into a team platform. Junior engineers run jobs through forms, scheduled tasks fire reliably, and every action is in the audit log. Combined with git-driven config, the whole platform is reproducible.