Category: AWX

The Two Patterns of Ansible Automation

Pipeline Execution vs Controller Execution

Most teams don’t realize they’re choosing an automation architecture every time they run a playbook. They think they’re choosing a tool. They’re actually choosing a pattern.

In my opinion, there are only two patterns that matter:

  1. Pipeline‑Driven Execution
  2. Controller‑Driven Execution (AWX/AAP)

Both work. Both fail. Both solve different problems.

This article breaks down the patterns, the guidance for using them, the anti‑patterns that cause outages, and when combining them actually makes sense.

Pattern 1: Pipeline‑Driven Execution

“Automation lives in Git. Execution happens in CI.”

This is the alleged cloud‑native. I hate the term ‘cloud-native’, it’s just a modern pattern and can equally apply to on-premises, but I’ll use it as it’s become an industry norm.

The pipeline:

  • checks out the repo
  • runs ansible-playbook directly
  • injects secrets at runtime
  • uses inventories stored in Git
  • uses vars stored in Git
  • uses execution environments defined in Git
  • tests automation before deploying
  • runs deterministically and reproducibly

This pattern treats Ansible like any other automation tool: code —> test —> deploy —> verify.

When to use it

Pipeline execution is the right answer when you need:

  • reproducibility
  • portability
  • deterministic execution
  • Git as the single source of truth
  • cloud‑neutral automation
  • ephemeral runners
  • multi‑cloud or hybrid cloud
  • developer‑friendly workflows
  • automation that can run anywhere

This is the pattern used by ‘cloud‑native’ teams, platform teams, and anyone who values Git truth over controller truth.

Strengths

  • Fully reproducible
  • Fully portable
  • Fully version‑controlled
  • No hidden state
  • No GUI configuration
  • No controller dependency
  • Works in any CI/CD system
  • Works locally
  • Works in DR
  • Works in multi‑cloud

Weaknesses

  • Pipelines must understand environment boundaries
  • Pipelines must manage secrets securely
  • Pipelines must enforce guardrails
  • Pipelines can become too flexible
  • Pipelines can accidentally bypass governance

This is why enterprises often avoid this pattern, not because it’s wrong, but because they fear losing control. The fear is real.

Pattern 2: Controller‑Driven Execution (AWX/AAP)

“Automation runs inside a governed platform.”

This is the typical enterprise pattern.

AWX/AAP:

  • pulls playbooks from Git
  • stores inventories
  • stores credentials
  • enforces RBAC
  • provides audit trails
  • standardizes execution environments
  • triggers automation from events
  • provides multi‑team visibility

This pattern treats Ansible as a governed automation platform, not a CLI tool.

When to use it

Controller execution is the right answer when you need:

  • RBAC
  • credential isolation
  • auditability
  • inventory synchronization
  • standardized execution environments
  • event‑driven automation
  • multi‑team governance
  • compliance and regulatory controls

This is the pattern used by large enterprises, regulated industries, and teams with strict governance requirements.

Strengths

  • Centralized governance
  • Centralized credentials
  • Centralized inventory
  • Centralized audit
  • Standardized execution environments
  • Event‑driven automation
  • Multi‑team visibility
  • Strong guardrails

Weaknesses

  • Hidden state
  • GUI configuration
  • Non‑portable automation
  • Not fully reproducible
  • Not fully version‑controlled
  • Controller dependency
  • Harder to test automation before deployment
  • Harder to run automation outside AWX

This is why ‘cloud‑native’ teams avoid this pattern, not because it’s wrong, but because it’s not portable.

Anti‑Patterns

These are the patterns that break automation, cause outages, and create drift.

Anti‑Pattern 1: AWX as the “automation store”

Pipelines call AWX job templates as if AWX stores automation.

It doesn’t.

AWX stores configuration, not automation.

Automation lives in Git. AWX overrides Git with controller‑side state.

This creates split‑brain automation, if you think git is the source of truth, surprise, it isn’t.

Anti‑Pattern 2: Pipelines storing credentials

This is a governance failure.

Pipelines should inject secrets at runtime, not store them.

AWX should manage credentials. Actually, just about anything else should manage credentials.

Anti‑Pattern 3: AWX storing inventories that drift from Git

Inventories should be version‑controlled.

If AWX is the inventory source of truth, Git is no longer authoritative.

This breaks reproducibility.

Anti‑Pattern 4: Pipelines bypassing RBAC

If pipelines can run any playbook against any host using any credential, you’ve lost governance.

This is dangerous in enterprise environments.

Anti‑Pattern 5: AWX storing controller‑side vars that override Git

This creates non‑deterministic execution.

Playbooks behave differently depending on controller configuration.

This breaks portability.

Does the Combination Make Sense?

Here’s the part most teams miss:

The two patterns are not mutually exclusive. They are complementary.

The Practical Guidance

Use pipeline execution when:

  • automation must be reproducible
  • automation must be portable
  • automation must be version‑controlled
  • automation must run anywhere
  • automation must be tested before deployment

Use controller execution when:

  • governance matters
  • RBAC matters
  • credential isolation matters
  • auditability matters
  • inventory sync matters
  • event‑driven automation matters

Use both when:

  • you need reproducibility and governance
  • you need portability and control
  • you need Git truth and environment truth
  • you need cloud‑native execution and enterprise guardrails

This is the two‑layer architecture.

Final Takeaway

There are two patterns.

Trying to make one do both is how teams create drift, outages, and brittle automation.

Fatal glibc error: CPU does not support x86-64-v2

I’m just writing this down in case anyone has a similar issue.

As per Building Red Hat Enterprise Linux 9 for the x86-64-v2 microarchitecture level | Red Hat Developer, back in 2020, AMD, Intel, Red Hat, and SUSE collaborated to define three x86-64 microarchitecture levels on top of the x86-64 baseline. The three microarchitectures group together CPU features roughly based on hardware release dates:

  • x86-64-v2 brings support (among other things) for vector instructions up to Streaming SIMD Extensions 4.2 (SSE4.2)  and Supplemental Streaming SIMD Extensions 3 (SSSE3), the POPCNT instruction (useful for data analysis and bit-fiddling in some data structures), and CMPXCHG16B (a two-word compare-and-swap instruction useful for concurrent algorithms).
  • x86-64-v3 adds vector instructions up to AVX2, MOVBE (for big-endian data access), and additional bit-manipulation instructions.
  • x86-64-v4 includes vector instructions from some of the AVX-512 variants.

This is a great idea and goal except when you have perfectly good old hardware that, while end-of-life is still working and you find it doesn’t support the new compile target.

This nice little awk script from the fine folks over at stackexchange will show you what microarchitecture your cpu supports by looking at the /proc/cpuinfo flags. I’ve included a local copy here and as you can see it’s pretty simple.

#!/usr/bin/awk -f

BEGIN {
    while (!/flags/) if (getline < "/proc/cpuinfo" != 1) exit 1
    if (/lm/&&/cmov/&&/cx8/&&/fpu/&&/fxsr/&&/mmx/&&/syscall/&&/sse2/) level = 1
    if (level == 1 && /cx16/&&/lahf/&&/popcnt/&&/sse4_1/&&/sse4_2/&&/ssse3/) level = 2
    if (level == 2 && /avx/&&/avx2/&&/bmi1/&&/bmi2/&&/f16c/&&/fma/&&/abm/&&/movbe/&&/xsave/) level = 3
    if (level == 3 && /avx512f/&&/avx512bw/&&/avx512cd/&&/avx512dq/&&/avx512vl/) level = 4
    if (level > 0) { print "CPU supports x86-64-v" level; exit level + 1 }
    exit 1
}

Running the awk script on my test system reveals :

$ ./testarch.awk
CPU supports x86-64-v1

The implications of this are annoying for me. I was trying to get awx to work on my little play system, but as the awx container is based on centos9 and compiled requiring at least x86-64-v2 then the awx container just wont start – yes I know there is more to awx than just this container, but it highlights the point nicely in the following command.

$ docker run --rm  ghcr.io/ansible/awx:latest
Fatal glibc error: CPU does not support x86-64-v2

This seems to have started somewhere after awx release 19.5.0

Navigation