Argo Workflows and Argo Events
Argo Workflows runs each step of a pipeline as a Kubernetes pod, and Argo Events starts those pipelines when something happens. This guide shows how the templates, artifacts, sensors and triggers fit together.
Where each Argo project fits
The Argo family is a set of Kubernetes-native tools, each solving a different problem:
| Project | Purpose |
|---|---|
| Argo CD | GitOps delivery of manifests |
| Argo Rollouts | Canary and blue/green releases |
| Argo Workflows | Run multi-step jobs as pods |
| Argo Events | React to external events and trigger actions |
This guide covers the last two. Argo Workflows is a container-native workflow engine where every step runs as a pod, which makes it a good fit for CI pipelines, data processing, batch jobs and machine-learning pipelines. Argo Events is an event-driven automation framework that can start workflows (or create any Kubernetes object) when something happens elsewhere.
Workflow basics and template types
A Workflow is a Kubernetes custom resource. Its spec names an entrypoint and a list of templates; the entrypoint is the template that starts the run.
apiVersion: argoproj.io/v1alpha1
kind: Workflow
metadata:
generateName: hello-
spec:
entrypoint: say-hello
templates:
- name: say-hello
container:
image: alpine:3.20
command: [echo]
args: ["hello world"]
Submit with argo submit -n argo --watch hello.yaml or kubectl create -f. Use argo list, argo get and argo logs to inspect runs. The main template types:
- container: run an image. The most common type.
- script: like a container, but with an inline
sourcescript; its stdout becomes the step's result. - resource: create, patch or delete a Kubernetes object from a manifest.
- suspend: pause for a duration or until someone resumes it, useful for manual approval gates.
- steps and dag: orchestration templates that call other templates (next section).
Steps and DAGs
A steps template is a list of stages. Stages run in order; steps inside the same stage run in parallel.
- name: pipeline
steps:
- - name: build
template: build-image
- - name: unit-tests
template: run-tests
- name: lint
template: run-lint
- - name: publish
template: push-image
A DAG template declares tasks and their dependencies, and the controller runs everything whose dependencies are met, as early as possible. That suits fan-out and fan-in graphs, for example a diamond where A runs first, B and C run in parallel, and D waits for both.
- name: diamond
dag:
tasks:
- name: A
template: echo
- name: B
dependencies: [A]
template: echo
- name: C
dependencies: [A]
template: echo
- name: D
dependencies: [B, C]
template: echo
Use steps for simple linear pipelines and dag when dependencies are irregular. Both support when conditions, withItems and withParam loops for fan-out, and retry strategies on a template.
Parameters and artifacts
Parameters are small string values. Workflow-level arguments are read as {{workflow.parameters.name}}; a template takes inputs.parameters and may expose outputs.parameters that later steps read as {{steps.build.outputs.parameters.tag}}.
Artifacts are files or directories passed between steps or stored for later, via an artifact repository such as an S3-compatible bucket, GCS or similar. A template declares an output artifact from a path; a later template declares an input artifact that references it.
- name: produce
container:
image: alpine:3.20
command: [sh, -c]
args: ["echo report > /tmp/report.txt"]
outputs:
artifacts:
- name: report
path: /tmp/report.txt
- name: consume
inputs:
artifacts:
- name: report
path: /tmp/in.txt
container:
image: alpine:3.20
command: [cat, /tmp/in.txt]
In a DAG you wire them with arguments.artifacts using from: "{{tasks.produce.outputs.artifacts.report}}". Configure the default artifact repository once for the installation; credentials for it should come from a Kubernetes Secret.
WorkflowTemplates and CronWorkflows
A WorkflowTemplate is a stored, reusable set of templates, either namespaced or cluster-wide (ClusterWorkflowTemplate). Create a run from it with argo submit --from workflowtemplate/ci-pipeline -p branch=main, or reference one of its templates from another workflow through templateRef:
- name: call-shared
templateRef:
name: common-tasks
template: notify
A CronWorkflow wraps a workflow spec with a cron schedule, a concurrency policy and history limits, for nightly or periodic jobs.
Argo Events architecture
Argo Events has four pieces that cooperate:
- EventSource: connects to the outside world and turns activity into events. Supported sources include webhooks, schedules, GitHub and other Git hosts, object-storage notifications, message queues such as Kafka, NATS and SQS, and cloud pub/sub services.
- EventBus: the transport between sources and sensors. It is backed by a message system such as NATS JetStream or Kafka, and the EventBus controller deploys it when you create an EventBus resource.
- Sensor: declares which events it depends on and what to do when they arrive. Dependencies can be combined with conditions (for example, require both of two events).
- Trigger: the action a sensor fires: create an Argo Workflow or any Kubernetes resource, call an HTTP endpoint, send to a message queue, invoke a serverless function, and more.
Flow: external system, EventSource, EventBus, Sensor, Trigger.
Wiring an event to a workflow
First an EventSource exposing a webhook endpoint:
apiVersion: argoproj.io/v1alpha1
kind: EventSource
metadata:
name: webhook
spec:
webhook:
build:
port: "12000"
endpoint: /build
method: POST
Then a Sensor that depends on it and submits a workflow, passing part of the event payload in as a parameter:
apiVersion: argoproj.io/v1alpha1
kind: Sensor
metadata:
name: webhook-sensor
spec:
dependencies:
- name: build-dep
eventSourceName: webhook
eventName: build
triggers:
- template:
name: run-workflow
argoWorkflow:
operation: submit
source:
resource:
apiVersion: argoproj.io/v1alpha1
kind: Workflow
metadata:
generateName: from-event-
spec:
entrypoint: main
arguments:
parameters:
- name: message
value: placeholder
templates:
- name: main
inputs:
parameters:
- name: message
container:
image: alpine:3.20
command: [echo, "{{inputs.parameters.message}}"]
parameters:
- src:
dependencyName: build-dep
dataKey: body
dest: spec.arguments.parameters.0.value
The parameters block maps data from the event into a field of the resource before it is created. Expose the webhook Service through an Ingress or gateway, and protect it, since anyone who can reach it can start work.
Practical tips
- The Workflows and Events controllers need RBAC. Give the workflow ServiceAccount only the permissions its steps need, and a separate, narrow one for sensors.
- Set
ttlStrategyand pod garbage collection so completed workflows do not pile up in etcd. - Set resource requests and limits on step containers, and an
activeDeadlineSecondsto stop runaway jobs. - Large fan-outs create many pods quickly. Use
parallelismlimits at workflow or template level. - Keep workflows and sensors in Git and deploy them with a GitOps tool, so changes are reviewed like any other code.
- Prefer artifacts for files and parameters for short strings; passing large data through parameters hits size limits.