Skip to main content
This guide shows how to create an Argo Events EventSource that exposes an HTTP webhook, how the webhook maps to CloudEvents-style payloads, and how to verify the EventSource and Service inside your Kubernetes cluster. Use this tutorial to receive webhooks from external systems (GitHub, GitLab, CI/CD tools, custom services) and forward them into Argo’s eventing pipeline. Argo Events supports many sources (AWS SNS, SQS, Azure services, calendar events, GCP Pub/Sub, GitHub, GitLab, Bitbucket, MinIO, Kafka, and more). For this demo we use the webhook EventSource, which runs an HTTP server and transforms incoming requests into CloudEvents-style envelopes.

CloudEvents envelope examples

A typical CloudEvents-style envelope produced by Argo Events contains a context and data section:
When the webhook receives an HTTP request, the event payload typically includes the request headers and body:
Note: the exact structure may vary depending on how the EventSource is configured (e.g., static payloads, custom converters, or secret mappings).
The webhook EventSource listens on the configured port and endpoint. By default, Argo Events will create a Kubernetes Service that exposes the same port. If you want traffic from outside the cluster to reach the webhook, expose the Service using a suitable type for your environment (LoadBalancer, NodePort, Ingress, etc.).

Prerequisites

  • A Kubernetes cluster with kubectl configured to access it.
  • Argo Events (controller, eventbus, etc.) installed into a namespace (commonly argo-events).
  • Optional: an Ingress or LoadBalancer if you need external, public endpoints.

Install Argo Events (if needed)

Apply the upstream manifests to install Argo Events and an example Sensor. Adjust URLs if you use local manifests:

Example EventSource manifest (webhook)

Below is an example EventSource that creates:
  • A webhook listener on port 13000.
  • An endpoint at /push which accepts only POST requests.
  • A generated ClusterIP Service exposing port 13000.
Key fields explained: Apply the manifest (for example save as webhook-eventsource.yaml):
If you created the EventSource via the Argo UI, the same resources are created in the selected namespace.

Verify the EventSource and Service

List resources in the argo-events namespace to confirm the EventSource pod and Service are running:
Example output (trimmed for clarity):
This confirms:
  • The webhook EventSource pod is running.
  • A ClusterIP Service (service/webhook-eventsource-svc) exposes port 13000.
Additional useful commands:
  • Inspect the EventSource resource:
  • View cluster events:

Test the webhook locally (port-forward)

If you don’t have a LoadBalancer or Ingress, port-forward to the Service/pod and test with curl:
  1. Port-forward the Service (or pod) to localhost:
  2. In another terminal, POST a test payload:
  3. Check the EventSource logs to see the incoming request being wrapped into a CloudEvents-style envelope:
Replace the label selector with the exact Pod/Deployment name if needed.

How the flow works

  • External systems POST to http://<cluster-ip-or-loadbalancer>:13000/push (or your public ingress URL).
  • The EventSource receives the request, wraps it into a CloudEvents-like envelope (context + data), and forwards the event onto the configured EventBus.
  • Sensors in Argo Events consume these events and trigger Argo Workflows, notifications, or other actions.
In the Argo UI (Event Flow or Event Sources view) you should see the new “my-webhook” event source after creation.

Quick troubleshooting

If you expose a webhook endpoint to the public internet, secure it: use TLS, require authentication or tokens, validate payloads, and restrict source IPs where possible. An unprotected webhook can be abused or flood your cluster with requests.
Use this pattern as a base to extend the webhook EventSource with authentication, custom converters, static payloads, or multiple endpoints per EventSource.

Watch Video