Tekton Triggers EventListeners and TriggerTemplates are the glue that lets external events kick off your CI/CD pipelines.
Let’s watch a real-time example. Imagine a GitHub push event.
apiVersion: tekton.dev/v1beta1
kind: PipelineRun
metadata:
name: webhook-pipeline-run-$(body.head_commit.id)
spec:
pipelineRef:
name: simple-pipeline
params:
- name: repo-url
value: $(body.repository.clone_url)
- name: git-revision
value: $(body.head_commit.id)
workspaces:
- name: shared-data
persistentVolumeClaim:
claimName: pipeline-pvc
This PipelineRun definition is dynamically generated by a TriggerTemplate. The $(body.head_commit.id) and $(body.repository.clone_url) are variables pulled directly from the incoming webhook payload. The EventListener receives the webhook, matches it to a TriggerTemplate, and then injects these variables into the PipelineRun it creates.
The core problem Tekton Triggers solves is bridging the gap between asynchronous, event-driven systems (like webhooks from GitHub, GitLab, or even Slack messages) and Tekton’s declarative, pipeline-as-code model. Without Triggers, you’d have to manually create PipelineRun objects every time you wanted to trigger a pipeline, which is obviously not scalable for automated CI/CD.
Here’s how it all fits together:
-
EventListener: This is the network endpoint. It’s a Kubernetes Service that listens for incoming HTTP requests. It doesn’t do anything itself other than receive the request and inspect it.
-
TriggerTemplate: This is the blueprint for what to create when an event matches. It defines a
PipelineRun(or aTaskRunorPipeline) and includes parameter definitions. These parameters are placeholders that will be populated from the event payload. -
TriggerBinding: This is how you extract specific data from the event payload to populate the
TriggerTemplate’s parameters. You define "bindings" that use CEL (Common Expression Language) or JSONPath to select values from the incoming JSON payload.
The EventListener is configured with one or more Triggers. Each Trigger specifies a TriggerTemplate to use and a list of TriggerBindings to apply. When an EventListener receives a request, it iterates through its Triggers. For each Trigger, it applies the TriggerBindings. If all bindings successfully extract data, that Trigger is considered a match. The EventListener then uses the associated TriggerTemplate, populating its parameters with the data extracted by the TriggerBindings, and creates the specified Tekton resource (usually a PipelineRun).
Let’s look at a TriggerTemplate and TriggerBinding pair for a GitHub push:
TriggerTemplate:
apiVersion: tekton.dev/v1beta1
kind: TriggerTemplate
metadata:
name: github-push-template
spec:
params:
- name: git-repo-url
description: The Git repository URL
- name: git-revision
description: The Git commit SHA
resourcetemplates:
- apiVersion: tekton.dev/v1beta1
kind: PipelineRun
metadata:
generateName: github-pr-run-
spec:
pipelineRef:
name: build-and-test-pipeline
params:
- name: repo-url
value: $(params.git-repo-url)
- name: git-revision
value: $(params.git-revision)
workspaces:
- name: source-ws
persistentVolumeClaim:
claimName: my-pipeline-pvc
TriggerBinding:
apiVersion: tekton.dev/v1beta1
kind: TriggerBinding
metadata:
name: github-push-binding
spec:
params:
- name: git-repo-url
value: $(body.repository.clone_url)
- name: git-revision
value: $(body.head_commit.sha)
In this setup, when a GitHub webhook arrives at the EventListener, the github-push-binding will try to extract body.repository.clone_url and body.head_commit.sha from the JSON payload. If successful, these values will be passed as params.git-repo-url and params.git-revision to the github-push-template, which then uses them to create a PipelineRun for the build-and-test-pipeline.
The EventListener itself is exposed via a Kubernetes Service, typically of type LoadBalancer or NodePort, so it can receive external traffic.
The one thing most people don’t realize is how powerful the EventListener’s interceptor field is. You can use it to add sophisticated validation and transformation logic before the event even hits your TriggerTemplate. For example, you can use a GitHubInterceptor to verify the webhook signature, ensuring the request actually came from GitHub and wasn’t tampered with. This is crucial for security. You can also use interceptors to filter events based on criteria like branch name, event type, or even custom payload fields, preventing your pipelines from being triggered by irrelevant events.
The next step is often exploring how to use these Triggers with different event sources and implementing more advanced filtering and validation using interceptors.