Most engineers think…
Most engineers hear "AWX / Tower" and think it's just "a pretty web GUI that runs my playbooks for me" — a nicer button for the same ansible-playbook command, and nothing more.
Wrong — and that view will cost you in interviews and on the job. The GUI is the easy part. The real product is a control plane: RBAC (who may run what), an audit trail (who ran it, when, and the full output), encrypted credential storage with run-time injection (the vault/SSH key never sits in someone's shell history), schedules and workflows (chained jobs that fire at 2 a.m. on their own), and execution environments (a pinned container so every run uses the same Ansible and collections). The dashboard is the door; governance is the building.
① Why a platform — one laptop doesn't scale to a team
Meet Sneha, an L1 automation engineer at Infosys. She wrote a tidy backup.yml that pulls every branch router's config and saves it to Git. It runs perfectly — from her laptop, with her SSH key, when she remembers to run it. Then the team grows to six engineers, the auditors ask "who changed the Mumbai core switch last Tuesday?", and Sneha goes on leave the week the nightly backup was supposed to fire. Every one of those problems is the same problem: a single laptop is not a team.
Walk the five gaps. No RBAC: anyone with the repo and a key can run anything against production — there is no "this junior may run the backup but not the firewall push." No audit: when something breaks at 9 a.m., there is no record of who ran what overnight or what the output was. No schedule: the nightly backup depends on a human (or a fragile cron on one box that nobody owns). No secret management: the Vault password and SSH keys live in shell history, sticky notes and scattered laptops. No self-service: a NOC analyst who just needs to run one safe, approved task has to be handed root and the whole repo.
Here is the shift. AWX is the open-source upstream; Red Hat Automation Controller (the product formerly named Ansible Tower) is the supported build of the same idea. Both wrap a web UI + REST API + control plane around the very same Ansible engine. Your playbooks do not change. What changes is everything around the run: who can launch it, where the secrets live, when it fires, and what gets recorded.
The five gaps, one tap each
Tap each card — these five are exactly why teams stop running from laptops and stand up a platform.
Anyone with the key can run anything on prod. So: no way to say 'junior may back up but not push firewall rules'.
Something breaks at 9 a.m. and nobody can prove who ran what overnight. So: no rollback story and no accountability.
The nightly backup needs a human or a cron box nobody owns. So: the one night it's skipped is the night you need it.
Vault password and SSH keys in shell history and on laptops. So: one stolen laptop = one stolen production key.
A laptop run is like leaving your housing-society gate open: anyone walks in, nobody logs who came or when. The Controller is the gatekeeper with a gate-pass register — the guard (RBAC) checks who you are and whether you're allowed in, the register (audit trail) records every entry with a timestamp, and visitors only reach the flats they're cleared for (least privilege). Same building, same people — but now there's a record and a rule for every entry.
Pause & Predict
Predict: AWX and Automation Controller are 'the same Ansible underneath.' So if your playbook works on the CLI but fails inside a Job Template, where do you look FIRST — the playbook logic, or the platform plumbing? Type your guess.
Rahul at TCS says: "We have six engineers all running the same playbooks from their own laptops. Auditors keep asking who ran what and we have no answer." Which platform feature directly fixes THAT complaint?
② Core objects — Projects, Inventories, Credentials & Job Templates
The whole platform is built from a few objects that snap together. Learn these four and the rest is detail. Project = your playbooks, almost always backed by Git. Inventory = your hosts. Credential = your secrets, encrypted. Job Template = the runnable unit that binds the other three together. Let's take them one at a time, because the EX374 exam and your first day both live in this list.
A Project points at a Git repository and a branch. When you (or a schedule) hit Sync, the platform pulls the latest commit so the playbooks it runs are always the approved ones in version control. This is the part new users trip over: edit a playbook in Git, forget to Sync the Project, and your Job Template happily runs the old commit. An Inventory is the list of hosts the job targets. It can be static (hosts you type in or group by hand) or come from a dynamic source that queries a cloud account or a script and refreshes itself, so a newly built VM appears without anyone editing a file.
Credentials are where the platform earns its keep on security. They are stored encrypted and injected at run time — the engine drops the SSH key or vault password into the job's environment for the duration of the run and never shows it back in the UI. There are types that matter: a Machine credential (SSH login + become/sudo password for Linux), a Network credential (for network_cli-style device logins), a Vault credential (the password that decrypts your Ansible Vault files), and various cloud credentials (AWS, Azure, GCP keys). Pick the wrong type and the job can't authenticate even though the secret itself is correct.
Finally the Job Template ties it together: it says "run this playbook (from this Project) against this Inventory using these Credentials inside this Execution Environment," plus knobs like limit, verbosity, and optional survey prompts. Click Launch and it becomes a Job with a live, streamed log. That single bound, repeatable, logged unit is the heart of the whole product.
curl -sk -u admin:'redhat' \
https://controller.lab.local/api/v2/job_templates/ | jq '.results[] | {id, name, project, inventory}'{
"id": 14,
"name": "Nightly-Branch-Backup",
"project": 7,
"inventory": 3
}Symptom: you fixed a bug in Git, the Job Template still does the buggy thing. Cause: the Project wasn't synced, so the Template ran the previous commit. Fix: open the Project and click Sync (or set Update revision on launch so it syncs before every run). Related trap: editing the playbook directly on the controller's filesystem — that change is overwritten on the next Sync, because the Project's source of truth is Git, not the box.
Priya at HCL needs her backup Job Template to log in to Cisco routers. She attaches a plain Machine (SSH) credential and the job fails to authenticate to the devices. What's the cleanest fix?
Pause & Predict
Predict: a Credential is stored encrypted and 'injected at run time.' So after a job finishes, can another engineer open that Credential in the UI and read the SSH private key back out? Type your guess.
③ Team features — RBAC, schedules, workflows, surveys & audit
Now the features that turn "a GUI for Ansible" into "a platform a team can trust." Start with RBAC. You grant roles — like Admin, Execute or Read — on specific objects to users or teams. So a NOC analyst gets Execute on just the "Restart-Service" Job Template and Read on its inventory — nothing else. They can run the one safe thing and can't touch the firewall push. This is least privilege, enforced by the platform instead of by trust.
Schedules let a Job Template fire on its own — "run the config backup every night at 02:00." No human, no fragile cron box. Workflows go further: the Workflow Visualizer lets you chain templates with branching — run the backup, and on success run the compliance check, but on failure page the on-call. You can even drop an approval node that pauses the workflow until a human clicks Approve — a built-in change gate. Surveys add safe, parameterised self-service: instead of editing the playbook, a user is shown prompts ("which site?", "dry-run or apply?") at launch, and their answers become variables. Notifications wire job start / success / failure (and workflow approval) to Slack, Microsoft Teams, email or a webhook.
Two more. The audit trail (the activity stream plus every job's saved output) answers the auditor's question permanently: every job records who launched it, when, against which hosts, and the full log. And the Execution Environment (EE) is the container the job actually runs inside — it bundles a pinned Ansible version, the Python libraries and the collections your playbook imports. Because every run uses the same image, "works on my laptop" stops being a thing: a job either has its EE or it doesn't, the same way for everyone.
▶ Watch RBAC + a survey turn a risky task into a safe button
A NOC analyst at Wipro, Karthik, needs to restart a stuck service on one branch — but must NOT be able to touch anything else. Follow how the platform makes that safe. Press Play for the healthy path, then Break it to see the failure.
limit---
- name: Nightly branch config backup
hosts: branch_routers
gather_facts: false
connection: network_cli
tasks:
- name: Pull and save running-config
cisco.ios.ios_config:
backup: true
backup_options:
dir_path: /backups/{{ inventory_hostname }}
register: result
- name: Fail the host if 'no telnet' baseline is missing
ansible.builtin.assert:
that: "'transport input ssh' in result.backup_path | default('')"
fail_msg: "Drift: telnet not disabled on {{ inventory_hostname }}"PLAY [Nightly branch config backup] ******************************** TASK [Pull and save running-config] ******************************* changed: [br-mumbai-01] changed: [br-pune-01] TASK [Fail the host if 'no telnet' baseline is missing] *********** ok: [br-mumbai-01] failed: [br-pune-01] => Drift: telnet not disabled on br-pune-01
After granting a role, log in as that user (or use the API with their token) and check what they can see. Run curl -sk -u karthik:... https://controller.lab.local/api/v2/job_templates/ — the list should contain only the templates they have a role on. If they can see (or worse, launch) templates you didn't grant, the role was attached too high up — at the Organization or Team level — instead of on the single object. Tightest scope wins.
Meera at ICICI faces this
Meera, an L2 engineer, schedules a nightly backup Job Template. The schedule shows it 'ran' at 02:00, but the Job failed instantly with 'ERROR! couldn't resolve module/action cisco.ios.ios_config' — yet the same playbook runs fine from her laptop.
The Job Template is pinned to an Execution Environment image that doesn't contain the cisco.ios collection. On her laptop the collection is installed locally; inside the EE container it isn't. Control-plane onboarding is fine — this is purely the run environment missing content.
She reads the failed Job's output (not the playbook) and sees the 'couldn't resolve module' line — a classic missing-collection-in-EE signature, separate from any login or RBAC issue.
Automation Execution → Jobs → (the failed run) → Output → then Templates → Nightly-Branch-Backup → Edit → Execution EnvironmentPoint the Template at a network EE that bundles cisco.ios (e.g. a 'ee-network' image), or rebuild the EE with the collection added to its requirements; re-launch.
Re-run the Job → the cisco.ios.ios_config task now executes and the config files land in /backups; the next scheduled 02:00 run also succeeds and posts to Slack.
Aditya at Flipkart wants: run the backup, and ONLY if it succeeds run the compliance check; if the backup fails, page the on-call instead. Which platform feature expresses that?
Pause & Predict
Predict: a Survey lets a user supply variables at launch. So why is a Survey with a fixed dropdown ('site: Mumbai / Pune / Lucknow') safer than letting the user type the limit free-hand? Type your guess.
④ A real flow — nightly backup, scheduled, credentialed & notified
Let's assemble everything into the flow you'll genuinely build in your first weeks: a nightly config-backup that runs against a dynamic inventory of branch routers, on a schedule, with a network credential injected, and the result posted to a Slack channel. Every object from sections ② and ③ shows up here in order, so this is also your revision.
The build, step by step. 1. Create a Project pointing at your net-automation Git repo, branch main, with Update revision on launch ticked so it always runs the latest commit. 2. Create an Inventory with a dynamic Source so new routers appear automatically. 3. Create a Network Credential holding the device login (encrypted). 4. Create the Job Template binding all three plus a network Execution Environment that has cisco.ios. 5. Add a Schedule on that Template for 02:00 daily. 6. Attach a Notification (Slack/Teams webhook) on success and failure. 7. Grant the NOC team Execute via RBAC so they can launch it manually too, but can't edit it.
ansible-navigator run backup.yml \ -i inventory/branch.yml \ --execution-environment-image ee-network-2.6 \ --mode stdout --check
PLAY [Nightly branch config backup] ******************************** TASK [Pull and save running-config] ******************************* ok: [br-mumbai-01] ok: [br-pune-01] PLAY RECAP ******************************************************** br-mumbai-01 : ok=1 changed=0 unreachable=0 failed=0 br-pune-01 : ok=1 changed=0 unreachable=0 failed=0
Three gotchas that bite real teams on exactly this flow. Credential scoping: the Network credential and the Job Template must live in the same Organization (and the launching user must have a role on the credential) or the Template can't attach it. Project sync: if you forget Update revision on launch and don't Sync, the 02:00 run executes last week's playbook — schedule the Project sync too, or tick the box. EE images: a Template pinned to the wrong/old EE image fails with 'couldn't resolve module' or an ansible-runner version mismatch even though the playbook is perfect.
One sober note from 2025–2026: because the controller holds every credential and can run anything, it's a high-value target — patch it. CVE-2025-69534 is a denial-of-service in automation-controller (Ansible Automation Platform 2.6) triggered by malformed HTML-like input; Red Hat fixed it in a patch release. The lesson for you isn't the CVE number — it's that the platform that holds the keys to your whole estate has to be kept current and access-controlled, exactly the way you'd treat a Vault server.
The whole platform is a Mumbai dabbawala dispatch board. The Project is the route book (the playbooks). The Inventory is today's delivery list (the hosts). the Credential is the building gate-pass, handed to the carrier only at the door and taken back after (injected at run time). The Schedule is the fixed train time. The Notification is the SMS when lunch is delivered. And the dispatcher with the register is RBAC + audit — who carries which tiffin, and proof it was delivered.
Cold, in 30 seconds: name the four core objects and what each holds (Project=playbooks, Inventory=hosts, Credential=encrypted secrets, Job Template=the bound runnable unit); say why a Credential can be USED but not READ (encrypted + injected at run time); and explain how RBAC + a Survey let a junior run one safe task without root. If you can do that without notes, you're ready for the EX374 Controller objectives and your first platform shift.
An interviewer asks Neha: "Give me the single biggest reason a team moves config backups off engineers' laptops and into a scheduled Job Template." Best answer?
🤖 Ask the AI Tutor
Tap any question — instant, scoped to this lesson. No login, no waiting.
Pre-curated from Ansible docs + community Q&A, scoped to this lesson. For a live prod issue, paste your export into chat.techclick.in.
📝 Wrap-up assessment — six more
You've answered 4 inline. Six left. 70% (7 of 10) marks the lesson complete on your profile. Tap Submit all answers at the end.
🧠 In your own words
Type one line: In one line, why can an engineer USE a stored credential to run a job but NOT read the secret back out of the UI? Then compare to the expert version.
🗣 Teach a friend
Best way to lock it in — explain it in one line to a teammate. Tap to generate a paste-ready summary.
📖 Glossary
- AWX
- The open-source upstream project — a web UI, REST API and task engine for Ansible. Red Hat's Automation Controller is built from it.
- Automation Controller
- Red Hat's supported product (formerly Ansible Tower) that runs jobs inside Ansible Automation Platform.
- Project
- A collection of playbooks in AWX/Controller, usually synced from a Git branch. Sync pulls the latest commit.
- Inventory
- The managed hosts, grouped logically. Static (typed in) or dynamic (pulled from a live source and refreshed).
- Credential
- A stored secret (SSH key, password, token, vault password). Encrypted, injected at run time, never displayed back.
- Credential type
- What the secret is for — Machine (SSH), Network (device login), Cloud (AWS/Azure/GCP), or Vault (decrypts Ansible Vault).
- Job Template
- The runnable unit: binds a Project, Inventory, Credentials and an Execution Environment, plus options and survey prompts.
- RBAC
- Role-Based Access Control — grant roles (Admin/Execute/Read) on specific objects to users and teams. Enforces least privilege.
- Schedule
- A rule that launches a Job Template automatically (e.g. nightly at 02:00) with no human and no fragile cron box.
- Workflow
- A graph chaining templates and syncs with on-success/on-failure/always branches, plus optional human approval nodes.
- Survey
- A launch-time form whose answers become job variables — gives parameterised self-service with guardrails.
- Execution Environment (EE)
- A container image bundling a pinned Ansible version, Python libraries and collections. The job runs inside it for reproducibility.
📚 Sources
- Red Hat Ansible Automation Platform 2.5 — Using automation execution: 'Job templates' (exact UI path Automation Execution ▸ Templates ▸ Create job template; fields Name, Job type, Inventory, Project, Execution Environment, Playbook, Credentials, Labels, Forks, Limit, Verbosity, Privilege escalation, Prompt on launch). docs.redhat.com/en/documentation/red_hat_ansible_automation_platform/2.5/html/using_automation_execution/controller-job-templates
- Red Hat Ansible Automation Platform 2.5/2.6 — Using automation execution: 'Workflow job templates' (the Workflow Visualizer; chaining job templates, project/inventory syncs; on-success/on-failure/always; approval nodes; surveys, schedules and notifications on workflows). docs.redhat.com/en/documentation/red_hat_ansible_automation_platform/2.5/html/using_automation_execution/controller-workflow-job-templates
- Ansible AWX community documentation — Overview & User Guide (AWX as the open-source upstream: projects, inventories, credentials, job templates; credentials encrypted and injected at run time; RBAC; execution environments). docs.ansible.com/projects/awx/en/latest/userguide/overview.html
- AWX GitHub Issues — project sync failing inside the Control Plane / default Execution Environment after operator/CRD reapply, plus ansible-runner version mismatch and OOM (rc 137) symptoms (real EE gotchas behind 'couldn't resolve module' and failed syncs). github.com/ansible/awx/issues/12117 · github.com/ansible/awx-operator/issues/1882
- Red Hat Security — CVE-2025-69534: denial of service via malformed HTML-like sequences in automation-controller for Ansible Automation Platform 2.6 (fixed in a patch release; why the credential-holding control plane must be patched and access-controlled). access.redhat.com/security/cve/CVE-2025-69534 · docs.redhat.com/en/documentation/red_hat_ansible_automation_platform/2.5/html/release_notes/patch_releases
- Red Hat EX374 — 'Red Hat Certified Specialist in Developing Automation with Ansible Automation Platform' exam objectives (navigate the Controller UI; create job templates and workflows; manage inventories and credentials; projects from SCM; configure RBAC; create execution environments). redhat.com/en/services/training/red-hat-certified-specialist-developing-automation-ansible-automation-platform-exam
What's next?
You can now run any playbook from a governed control room. But a backup that hard-codes every device's hostname and IP doesn't scale — the next lesson makes your configs build themselves with Jinja2 templating and proves they're safe to re-run with idempotency.