Running from AAP
Every phase runs two ways — as a Claude Code skill on a laptop, and as an AAP
job template — driving the same playbooks/<phase>.yml. The AAP objects are
config-as-code in
inventory/group_vars/aap/,
applied by playbooks/config.yml like everything else.
Measured against main on 2026-09-11: 33 job templates and 5 workflows.
The counts here come from controller_templates.yml and
controller_workflows.yml, ignoring entries carrying state: absent — those
are tombstones that delete superseded objects, not things AAP runs.
The five workflows
A workflow is the entry point. Launch the workflow, not the templates inside it — the survey collects every input once and the nodes chain on success.
Cluster Day 0
Bare cluster to demo-ready.
Cluster Day 0 - 1 Install OpenShift Virtualization
└─> Golden Image - Link RHEL 9 CIS L1
└─> Cluster Day 0 - 2 Verify Environment
Linux Day 1 - 0 Workflow
Linux Day 1 - 1 Provision
└─> Linux Day 1 - 2 Register
└─> Linux Day 1 - 3 Configure
└─> Linux Day 1 - 4 Compliance Scan
└─> Linux Day 1 - 5 Check
Windows Day 1 - 0 Workflow
Same shape, with a patch stage where Linux registers:
Windows Day 1 - 1 Provision
└─> Windows Day 1 - 2 Patch
└─> Windows Day 1 - 3 Configure
└─> Windows Day 1 - 4 Compliance Scan
└─> Windows Day 1 - 5 Check
AAP Ecosystem - Deploy Automation Orchestrator
Install and configure AO in one button:
AAP Ecosystem - Install Automation Orchestrator
└─> AAP Ecosystem - Configure Automation Orchestrator
Windows Day 2 - 0 Break Fix
The compliance story — scan either side of a deliberate regression, so the audience sees the score move rather than being told it would:
Windows Day 2 - Break Compliance
└─> Windows Day 2 - Compliance Scan (the broken score)
└─> Windows Day 2 - Fix Compliance
└─> Windows Day 2 - Compliance Scan (the restored score)
Job templates by family
| Family | Count | Covers |
|---|---|---|
Cluster Day 0 |
3 | Install CNV, verify the environment, probe capacity |
Golden Image |
2 | Link the RHEL 9 and Windows 2022 CIS L1 images |
Linux Day 1 |
7 | Provision, register, configure, scan, check, repair, teardown |
Windows Day 1 |
7 | Provision, patch, configure, scan, check, repair, teardown |
Windows Day 2 |
6 | Break/fix compliance, scan, patch, check SMB, .NET patch report |
AAP Ecosystem |
4 | Install AO, configure AO, self-service portal, MCP server |
AAP Observability |
2 | Deploy Alloy, deploy dashboards |
Self-Service |
2 | Request a Linux or Windows server via the portal |
Every template maps to one playbook. A few playbooks back more than one
template — provision_vm.yml serves both the Linux and Windows provision
steps, teardown.yml both teardowns, and windows_compliance_scan.yml is
reused at three points in the Windows story.
One working inventory, not two
Sales Demo VMs holds both populations: sandbox-local / demo-local, synced
from the repo's own inventory/hosts.yml by an SCM inventory source, and the
demo VMs registered at run time. That sync is what lets a job template use
connection.yml instead of a second copy of every hostname.
Sales Demo VMs - Control holds no VM hosts, and only teardown points at
it — two templates, Linux Day 1 - Teardown and Windows Day 1 - Teardown.
Teardown cannot run in the inventory whose hosts it deletes; AAP holds a
running-job lock on that inventory. From controller_inventories.yml:
Nothing but teardown should reference this. If another job template points here, that is a bug.
How AAP reaches the VMs
Plain ssh on port 22. AAP runs on the same cluster, each VM has a
headless Service giving it stable in-cluster DNS, and there is no NetworkPolicy
between the namespaces. No bastion is involved, and virtctl is not either —
that is the laptop path, and the execution environment does not ship the
binary. The only requirement is the Sales Demos - Linux Machine credential,
holding the private half of demo_ssh_public_key.
demo_ssh_public_key must not be empty
cloud-init then emits ssh_pwauth: true with no authorized key and no
password, and the guest has no credentials at all. Because cloud-init writes
authorized keys only on first boot, a VM created that way must be
re-created, not restarted.
Testing a job template before its playbook has merged
A job template validates playbook: against the project's current checkout, so
an unmerged playbook cannot otherwise be wired up. Override the project branch:
ansible-playbook playbooks/config.yml -i inventory --limit sandbox \
-e target_env=sandbox -e sales_demos_branch=my-branch \
--vault-id sales.demos@~/secrets/.vault_pass_sales_demos
Re-apply without the override before calling anything done.