The Argo Ecosystem
The CAPA exam tests Argo Workflows, Argo CD, Argo Rollouts and Argo Events as four separate blueprint domains — 36%, 34%, 18% and 12% — and that framing is correct as far as it goes. What it doesn't have room to explain is the architecture underneath: why these four things share a name and a CNCF graduation but ship as four completely independent binaries, four separate Helm charts, and four separate release trains that nobody keeps in lockstep. This page goes past the exam blueprint into the family relationship itself — the one API group and control-loop philosophy every project inherits, what "installed separately" actually means operationally, and the mechanism by which all four compose into a single delivery loop without any of them ever calling another one directly. None of this is examinable on its own. All of it is what separates someone who passed CAPA from someone who can actually design a delivery platform on top of it.
Picture four siblings who all grew up in the same house and still share the family last name — but each one moved into their own apartment, has their own job, and comes and goes on their own schedule. One (Workflows) runs the family's errands, in whatever order gets everything done fastest. One (CD) keeps checking the family's plans against a shared notebook and quietly fixes anything that's drifted. One (Rollouts) is cautious by nature — never lets a new idea take over everything at once, only a little bit at a time, watching closely. One (Events) is the one who notices when something happens outside and calls the others. They don't share an apartment, a lease, or a work schedule. They just share a name, an upbringing, and a habit of leaving notes for each other in the same shared notebook instead of shouting through the wall.
One name, four separate projects
☺ Like you're 10: "Argo" isn't one robot with four settings — it's four different robots that happen to share a family name.
It is easy to meet Argo CD first — most platform engineers do — and quietly assume the others are features of it. They are not. Argo CD, Argo Workflows, Argo Rollouts and Argo Events are four separate open-source projects, each with its own GitHub repository, its own maintainer group, its own versioning scheme, and its own release cadence. Argo Workflows shipped first, in 2017, as a way to run finite, dependency-ordered jobs on Kubernetes rather than on a bespoke CI agent fleet. Argo CD followed in 2018, applying the same "everything is a Kubernetes object" instinct to continuous delivery. Argo Rollouts and Argo Events arrived after, each solving one problem the other two didn't: progressive delivery with automated analysis, and reacting to things that happen outside the cluster. All four were later brought under one umbrella and accepted into the CNCF together, graduating as a single CNCF-graduated project in December 2022 — one of the relatively small number of CNCF projects that is, formally, a federation of several codebases rather than one.
"The Argo Project" is a governance and community umbrella, not a product name. The CNCF's Technical Oversight Committee voted on one project, but what you install, upgrade, and page someone about is always one of four separately shipped pieces of software. Knowing which of the four owns a given problem — a stuck pipeline is Workflows, a stuck sync is CD, a stuck canary is Rollouts, nothing firing at all is Events — is worth more in an incident than knowing the umbrella exists.
The shared spine: one API group, one control-loop philosophy
☺ Like you're 10: All four write their notes in the same shared notebook — the argoproj.io API group — even though none of them lives in the same room.
What actually ties the family together isn't shared code, it's a shared design decision made independently by each project: everything is a Kubernetes custom resource, reconciled by a controller running a control loop. There is no separate Argo database, no separate Argo scheduler, no separate Argo message queue that all four share. A Workflow, an Application, a Rollout and a Sensor are all just objects the Kubernetes API server already knows how to store, version, watch and diff — the same substrate a Deployment or a ConfigMap uses. Each project's controller is a program that watches its own kinds, compares the declared spec against the observed world, and nudges reality toward the spec — the same reconcile-loop shape that every controller in this course, from Kyverno's admission webhook to the raw Kubernetes controller manager, is built on. Every CRD any of the four projects installs lives in the same argoproj.io API group, at whatever version each project is currently on (v1alpha1 is common across all four at the time of writing) — a naming convention, not a technical dependency.
The design payoff of that shared philosophy is bigger than the naming convention suggests. Because every project's unit of work is "just a Kubernetes object," any tool that already knows how to apply, diff, and watch Kubernetes objects — kubectl, Argo CD itself, a policy engine like Kyverno — works on all four families for free, with zero project-specific integration code. CNCF Project Maturity & Graduation covers what graduation actually certifies about a project's governance; Multi-Project Platform Thinking covers why "everything is a CR reconciled by a controller" is the load-bearing idea across the whole CNCF landscape, not just inside Argo.
Installed separately, versioned separately, upgraded separately
☺ Like you're 10: Running Argo CD doesn't come with the other three siblings pre-installed — you have to invite each one to the cluster yourself, and they each keep their own calendar.
This is the operational fact the shared name obscures, and it is the single most common source of confusion for someone who learned one Argo project well and assumes they know the family. Installing Argo CD does not install Argo Workflows, Rollouts, or Events — each is its own manifest set or Helm chart, typically landing in its own namespace, with its own CRDs to apply, its own controller pod to run, and its own resource requests to size. None of the four requires any of the others to function: a cluster can run Argo Workflows alone for CI-style job orchestration with no Argo CD anywhere in sight, and plenty of clusters do.
Independence extends to the release calendar. Argo CD, Argo Workflows, Argo Rollouts and Argo Events each publish their own version numbers, their own deprecation windows, and their own breaking-change notes, on schedules that do not line up. Upgrading Argo CD from one minor version to the next has no bearing on whether Argo Rollouts needs an upgrade this quarter — read each project's own release notes before touching it, not the others'. The one genuine cross-project dependency worth knowing is internal to Argo Events itself, not between projects: the EventBus component (typically NATS or JetStream under the hood) is Events' own transport between its EventSource and Sensor objects, and if it is down, nothing in that project fires — but Workflows, CD and Rollouts have no idea it exists and are entirely unaffected.
Knowing Argo CD's Application spec cold tells you nothing about Argo Workflows' dag templates, and knowing Argo Rollouts' canary steps tells you nothing about how Argo Events wires an EventSource to a Sensor. Budget separate study and separate production hours for each one you actually plan to run — the CAPA blueprint's own domain split (36/34/18/12) is a reasonable proxy for how much there is to learn in each, not for how much overlaps.
How the four compose into one delivery loop
☺ Like you're 10: None of the four siblings ever picks up the phone to call another one directly — they leave notes in the shared notebook (Git) or drop something on the shared table (the Kubernetes API), and whoever's turn it is next just happens to notice.
The payoff for understanding the family as four decoupled projects rather than one integrated product is seeing how a real platform wires them together — because the wiring is not a special integration feature any of the four ships. It is the same reconcile-loop mechanism each one already uses on its own, pointed at objects the others happen to have touched. A complete build-to-production loop looks like this: a webhook fires on a merged pull request, and an Argo Events EventSource picks it up and publishes it to the EventBus; a Sensor subscribed to that dependency matches its filter and fires its trigger, which submits an Argo Workflow; that workflow builds and tests the image, pushes it to a registry, and — as its final step — commits a new image tag into a Git repository that holds the cluster's desired state; Argo CD, watching that repository, detects the drift between the new commit and the live cluster and syncs; what it applies is not a bare Deployment but a Rollout object, so Argo Rollouts takes over the release, shifting traffic in the small steps its canary strategy defines, pausing at each one for an AnalysisRun to query a metrics provider and decide whether to continue or automatically roll back.
The detail worth sitting with is what step five actually requires of Argo CD: almost nothing project-specific. Argo CD does not ship a "Rollouts integration" in the sense of driving a canary, calling into Argo Rollouts' controller, or knowing what a setWeight step is — it renders whatever is in the Git path it's pointed at and applies it, the exact same sync code path whether that manifest declares a Deployment, a ConfigMap, or a Rollout. The one narrow exception, worth naming precisely because it's the only one: Argo CD does ship a small piece of built-in health-check logic that knows how to read a Rollout object's own status fields and translate them into the Healthy/Progressing/Degraded vocabulary Argo CD's UI already speaks — otherwise a Rollout stuck mid-canary would just show as an opaque "Unknown" to anyone watching the Argo CD dashboard. That's display-layer awareness, not control-layer awareness — Argo CD still never touches a canary step, a traffic weight, or an AnalysisRun. The moment the object lands, it is Argo Rollouts' own controller — watching independently, with no awareness that Argo CD was involved — that notices a Rollout exists or changed and actually drives it. That's the entire trick behind every composition in this ecosystem: real coordination happens through the Kubernetes API server and Git, and the one built-in exception only makes the result legible in a dashboard — it never becomes a second place that decides anything.
# Argo CD's Application points at a path in Git and applies whatever
# it finds there generically — the only Rollout-specific code Argo CD
# runs at all is a built-in health check, purely for the status badge.
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: checkout-service
namespace: argocd
spec:
project: default
source:
repoURL: https://github.com/acme/platform-config.git
targetRevision: main
path: apps/checkout
destination:
server: https://kubernetes.default.svc
namespace: checkout
syncPolicy:
automated: { prune: true, selfHeal: true }
---
# apps/checkout/rollout.yaml — the file Argo CD applies generically.
# argo-rollouts' own controller, watching independently, is what
# actually notices this kind and drives the canary — not Argo CD.
apiVersion: argoproj.io/v1alpha1
kind: Rollout
metadata:
name: checkout-service
spec:
replicas: 6
strategy:
canary:
steps:
- setWeight: 20
- pause: { duration: 10m }
- analysis:
templates:
- templateName: checkout-success-rate
- setWeight: 100"The first time I traced a deploy end to end I expected to find some real 'Argo integration layer' stitching the four together, and I basically never found one. Argo CD applied a YAML file it barely understood the contents of — the only thing it recognized was enough to color a status badge in its own UI — and Argo Rollouts picked up the actual work because it happened to be watching that kind independently. It's not glue code driving anything. It's four controllers all reading the same table, with one of them squinting hard enough at a neighbor's homework to grade it 'looks fine so far.'"
The anti-pattern: skipping Git to save a step
☺ Like you're 10: It's tempting to have the messenger sibling just walk straight into the reconciler's room and change the plan by hand — but then the shared notebook stops being the truth, and everyone's confused about what actually happened.
Because Argo Events' Sensor can trigger any Kubernetes object through its generic k8s trigger — not only submitting a Workflow — it is technically capable of patching an Argo CD Application directly, or writing straight to a Rollout, bypassing Git entirely. It is also, on its own, a live demonstration of why the loop is designed to route through Git in the first place. The moment a Sensor writes to the cluster without a corresponding commit, the cluster's live state and the Git repository disagree, and the very tool built to notice and fix that disagreement — Argo CD's selfHeal — will treat the Sensor's own change as unauthorized drift and quietly revert it on the next reconcile pass. Two systems built to keep everything honest end up fighting each other, and the failure mode is confusing precisely because both sides are working exactly as designed.
Any component that mutates a cluster Argo CD manages — including another Argo project — has to either write to Git first, or be explicitly told to keep its hands off via ignoreDifferences, or expect to be reverted. This is the practical edge of the idea covered in full on GitOps Philosophy: the git-as-single-source-of-truth model isn't a preference, it's the thing that makes automated selfHeal safe to leave switched on at all.
What Argo does not do — and composes with instead
☺ Like you're 10: None of the four siblings can actually shift real network traffic, watch a metrics dashboard, or lock the front door themselves — for that, they call in a specialist from outside the family.
Understanding the ecosystem's edges matters as much as understanding its center, because every one of the four projects deliberately delegates a whole category of work to a specialist tool rather than reinventing it — the same "compose, don't absorb" instinct that runs through the rest of the CNCF landscape.
| What Argo doesn't do itself | Who it hands off to | Where in this course |
|---|---|---|
| Actually move network traffic for a canary | A traffic router — an ingress controller, a service mesh's proxy layer, or the Gateway API. Argo Rollouts sets a target weight; the router is what makes packets follow it. | Service Mesh Architecture, Istio |
| Collect or store the metrics an AnalysisRun judges a canary against | An external metrics provider — commonly Prometheus, but also Datadog, CloudWatch or others. Argo Rollouts only queries; it never scrapes. | The Prometheus Model, Prometheus |
| Decide whether a manifest is even allowed to be applied | An admission policy engine sitting in front of the API server. Argo CD will happily apply something a policy engine would have rejected, unless one is actually installed and enforcing. | Policy-as-Code Philosophy, Kyverno |
| Keep secrets out of the Git repository it syncs from | A secrets-management layer — sealed secrets, an external-secrets operator, or SOPS-encrypted values — so the "everything in Git" model doesn't mean plaintext credentials in Git. | Secrets Management (Platform Engineering) |
This is also the shape of the answer to "why does CAPA only cover four projects when the CNCF landscape has hundreds": CAPA examines one tightly-scoped family, and every boundary in the table above is a seam where a different certification picks up — service mesh for traffic, PCA for metrics, KCA for policy. Multi-Project Platform Thinking walks through this composition instinct as a general pattern rather than an Argo-specific one, and the same reconcile-loop design this page describes for Argo's four CRDs is the identical mechanism the core Kubernetes course covers for the built-in controllers CKA examines directly.
The family, side by side
☺ Like you're 10: One table, four rows — everything worth remembering about who's who in the family.
| Project | First shipped | Primary kinds | Typical namespace | Is emphatically NOT |
|---|---|---|---|---|
| 🐙 Argo Workflows | 2017 | Workflow, WorkflowTemplate, CronWorkflow | argo | A CI product with build agents — every step is a plain pod |
| 🤖 Argo CD | 2018 | Application, AppProject, ApplicationSet | argocd | A build system — it never builds an image, only reconciles what's already in a registry |
| 🦫 Argo Rollouts | 2019 | Rollout, AnalysisTemplate, AnalysisRun | argo-rollouts | A traffic router — it sets a weight and delegates the actual shift |
| 🐦 Argo Events | 2018–19 | EventSource, EventBus, Sensor | argo-events | A message queue — it's a thin trigger layer sitting on top of one (usually NATS) |
Without looking back at the diagrams above, sketch the six-step loop from memory: webhook → ? → ? → Git → ? → ?. Label which of the four Argo projects owns each step, and name the one non-Argo component (the traffic router or metrics provider) each step secretly depends on. If you can draw it cold, you understand the ecosystem at the level this page is aiming for — past the exam blueprint and into the architecture.
Foxy: Wait — so if I already know Argo CD really well, I basically already know the other three?
Olly: Not even close, Foxy. Same last name, four completely different jobs. I run Workflows — dependency graphs, parallel pods, artifacts. None of that overlaps with what Recon does.
Recon: BEEP. Confirmed. I reconcile Application objects against Git, forever. I have never once looked inside a Workflow spec in my life.
Benny: And I don't even know Recon applied anything! My controller just notices a Rollout exists and starts stepping through the canary. Nobody told me — I watched.
Gizmo: Boring, all this "watching." Why not have the Sensor just patch the live Rollout directly the second the webhook fires? Skip the whole Git detour. So much faster! 😈
Timmy: Because the second you do that, Gizmo, Recon's selfHeal sees an object that doesn't match Git and reverts your "fast" change right back. You'd be racing your own reconciler and losing.
Ellie: And whatever Benny's AnalysisRun decides is only as honest as the metrics feeding it. Break my scrape config and the canary promotes on bad data, quietly, no matter how carefully the other three behaved.
Olly: That's the whole lesson in one scene. Four siblings, four controllers, zero direct phone calls between them — just a shared notebook and a shared table, and everyone reading off the same one.
1. "The Argo Project" graduated the CNCF as one project — what does that actually mean operationally, and what does it not mean? 2. What single design idea do all four projects share that the shared argoproj.io API group is a symptom of, rather than the cause of? 3. Name one genuine cross-project dependency inside Argo Events itself, and explain why it does not extend to the other three projects. 4. Walk the six-step delivery loop from a webhook to a promoted canary, naming which Argo project owns each handoff. 5. In what narrow sense does Argo CD have special handling for the Rollout kind, and why doesn't that count as Argo CD "driving" a canary? 6. Explain, mechanically, why a Sensor patching a live Rollout directly tends to get reverted. 7. Name two things Argo Rollouts explicitly delegates to an outside tool rather than building itself.
Check your answers
- It means the CNCF's Technical Oversight Committee evaluated and accepted governance, community health and maturity for the umbrella as a whole, in December 2022. It does not mean the four projects share a codebase, a release schedule, or a single binary — each still ships, versions and is upgraded completely independently.
- The idea that everything is a Kubernetes custom resource, reconciled by a controller running a control loop toward a declared spec. The shared
argoproj.ioAPI group is simply where each project's CRDs happen to live as a result of that shared design choice — not a technical dependency between the projects. - Argo Events' EventBus (typically NATS or JetStream) is the transport its own
EventSourceandSensorobjects depend on — if it's down, nothing in that project fires. It doesn't extend to Workflows, CD or Rollouts because none of them are aware the EventBus exists; it is purely internal plumbing for Argo Events. - ① a webhook triggers an Argo Events
EventSource; ② itsSensorfires a trigger that submits an Argo Workflow, which builds, tests and pushes an image; ③ the workflow commits a new tag to a Git config repo; ④ Argo CD detects the drift and syncs, applying aRolloutobject; ⑤/⑥ Argo Rollouts' own controller notices theRolloutand steps through the canary, using anAnalysisRunagainst an external metrics provider to promote or auto-abort. - Argo CD ships one narrow, display-only exception: built-in health-check logic that reads a
Rollout's own status fields and maps them onto Argo CD'sHealthy/Progressing/Degradedvocabulary, so the dashboard doesn't show a stuck canary as opaque "Unknown." That's it — Argo CD's sync/apply path treats theRolloutmanifest exactly like any other object, and it never touches a canary step, a traffic weight, or anAnalysisRun. Driving the actual canary is entirely Argo Rollouts' own independent controller, watching separately. - Argo CD's
selfHealcontinuously compares the live cluster against Git. A Sensor patching the liveRolloutdirectly creates a live object that no longer matches the last Git commit — which is exactly the conditionselfHealexists to detect and correct, so it reverts the Sensor's change on the next reconcile pass. - Any two of: shifting real network traffic during a canary (delegated to a traffic router — ingress, mesh, or the Gateway API); collecting or storing the metrics an
AnalysisRunjudges against (delegated to an external provider such as Prometheus); enforcing whether a manifest is even allowed to be applied (delegated to a policy engine such as Kyverno).