Auto‑Trigger Tekton Pipelines with GitLab Webhooks: A Step‑by‑Step Guide
This article explains how to use Tekton Trigger to automatically start PipelineRuns from GitLab webhook events, covering the core components, CRD definitions, installation steps, and detailed configurations of TriggerTemplate, TriggerBinding, EventListener, ServiceAccount, Ingress, and secret management, enabling fully automated CI/CD on Kubernetes.
What Is Tekton Trigger?
Tekton Trigger is a Tekton component that detects events from various sources, extracts required information, and runs
TaskRunand
PipelineRunobjects, passing the extracted data to satisfy different execution requirements.
The core components are:
EventListener – the external event entry point, usually exposed via HTTP for webhook integration.
Trigger – defines what happens when an EventListener detects an event; it references a TriggerBinding, TriggerTemplate, and optional Interceptor.
TriggerTemplate – templates resources; parameters received from the event are used to instantiate Tekton objects such as
TaskRunor
PipelineRun.
TriggerBinding – captures fields from the event and stores them as parameters for the TriggerTemplate.
ClusterTriggerBinding – similar to TriggerBinding but scoped at the cluster level.
Interceptor – runs before TriggerBinding to filter, validate, or transform the event payload.
Trigger CRD Objects
TriggerTemplate
TriggerTemplate modularizes Tekton resources, allowing parameters to be used anywhere in the resource template. Example:
<code>apiVersion: triggers.tekton.dev/v1beta1
kind: TriggerTemplate
metadata:
name: pipeline-template
spec:
params:
- name: gitrevision
description: The git revision
default: main
- name: gitrepositoryurl
description: The git repository url
- name: message
description: The message to print
default: This is the default message
- name: contenttype
description: The Content-Type of the event
resourcetemplates:
- apiVersion: tekton.dev/v1beta1
kind: PipelineRun
metadata:
generateName: simple-pipeline-run-
spec:
pipelineRef:
name: simple-pipeline
params:
- name: message
value: $(tt.params.message)
- name: contenttype
value: $(tt.params.contenttype)
resources:
- name: git-source
resourceSpec:
type: git
params:
- name: revision
value: $(tt.params.gitrevision)
- name: url
value: $(tt.params.gitrepositoryurl)</code>The
resourcetemplatesfield defines the actual Tekton object (here a
PipelineRun) that will be created, and the
paramsfield lists the parameters extracted from the event.
TriggerBinding
TriggerBinding captures fields from the event and stores them as parameters:
<code>apiVersion: triggers.tekton.dev/v1beta1
kind: TriggerBinding
metadata:
name: pipeline-binding
spec:
params:
- name: gitrevision
value: $(body.head_commit.id)
- name: gitrepositoryurl
value: $(body.repository.url)
- name: contenttype
value: $(header.Content-Type)</code>The values are extracted using
$(...)JSONPath expressions.
Trigger
Defines the binding, template, and optional interceptors:
<code>apiVersion: triggers.tekton.dev/v1beta1
kind: Trigger
metadata:
name: trigger
spec:
interceptors:
- ref:
name: "cel"
params:
- name: "filter"
value: "header.match('X-GitHub-Event', 'pull_request')"
- name: "overlays"
value:
- key: extensions.truncated_sha
expression: "body.pull_request.head.sha.truncate(7)"
bindings:
- ref: pipeline-binding
template:
ref: pipeline-template</code>When the EventListener receives an event, the Trigger runs the interceptors first, then passes the data to the binding and template.
ClusterTriggerBinding
Works like TriggerBinding but is cluster‑scoped:
<code>apiVersion: triggers.tekton.dev/v1beta1
kind: ClusterTriggerBinding
metadata:
name: pipeline-clusterbinding
spec:
params:
- name: gitrevision
value: $(body.head_commit.id)
- name: gitrepositoryurl
value: $(body.repository.url)
- name: contenttype
value: $(header.Content-Type)</code>Interceptor
Interceptors process the event before the binding. Tekton provides several built‑in interceptors, such as Webhook, Github, Gitlab, Bitbucket, and CEL. Example of a GitLab interceptor:
<code>interceptors:
- ref:
name: "gitlab"
params:
- name: "secretRef"
value:
secretName: foo
secretKey: bar
- name: "eventTypes"
value: ["Push Hook"]</code>EventListener
EventListener is a Kubernetes object that listens on a port for HTTP events and forwards them to the defined triggers:
<code>apiVersion: triggers.tekton.dev/v1alpha1
kind: EventListener
metadata:
name: gitlab-listener
spec:
serviceAccountName: tekton-triggers-example-sa
triggers:
- name: foo-trig
interceptors:
- gitlab:
secretRef:
secretName: foo
secretKey: bar
eventTypes:
- "Push Hook"
bindings:
- ref: pipeline-binding
template:
ref: pipeline-template</code>Installing Tekton Trigger
Apply the official manifests (or a custom mirror if the network blocks the download):
<code>kubectl apply --filename https://storage.googleapis.com/tekton-releases/triggers/latest/release.yaml
kubectl apply --filename https://storage.googleapis.com/tekton-releases/triggers/latest/interceptors.yaml</code>After installation, the following pods should be running in the
tekton-pipelinesnamespace:
<code># kubectl get po -n tekton-pipelines
NAME READY STATUS RESTARTS AGE
tekton-dashboard-565c78b68d-6fjdz 1/1 Running 12 32d
tekton-pipelines-controller-75c456df85-qxvq2 1/1 Running 5 32d
tekton-pipelines-webhook-5bc8d6b7c4-w6pdn 1/1 Running 5 32d
tekton-triggers-controller-686c6c8f79-fp7wd 1/1 Running 0 9m37s
tekton-triggers-core-interceptors-5d77595f79-8q9hb 1/1 Running 0 10s
tekton-triggers-webhook-76c55d6799-h997b 1/1 Running 0 9m36s</code>Using Tekton Trigger for Automatic CI/CD
Define TriggerTemplate
The pipeline defined in the earlier "Tekton practice" article expects parameters such as
revision,
git_url,
imageUrl,
imageTag, and
namespace. The TriggerTemplate passes these parameters to a
PipelineRun:
<code>apiVersion: triggers.tekton.dev/v1beta1
kind: TriggerTemplate
metadata:
name: trigger-rd-pipeline-template
spec:
params:
- name: gitrevision
description: The git revision
default: master
- name: gitrepositoryurl
description: The git repository url
- name: namespace
description: The namespace to create the resources
default: tekton-devops-pipeline
- name: projectname
description: The project name
- name: imagetag
description: The image tag
default: latest
resourcetemplates:
- apiVersion: tekton.dev/v1alpha1
kind: PipelineRun
metadata:
name: rd-pipeline-run-$(uid)
namespace: $(tt.params.namespace)
spec:
serviceAccountName: tekton-build-sa
params:
- name: revision
value: $(tt.params.gitrevision)
- name: git_url
value: $(tt.params.gitrepositoryurl)
- name: imageUrl
value: registry.cn-hangzhou.aliyuncs.com/coolops/$(tt.params.projectname)
- name: imageTag
value: $(tt.params.imagetag)
- name: pathToDockerfile
value: Dockerfile
- name: chart_username
value: xxx
- name: chart_password
value: xxx
- name: app_name
value: hello-world
- name: sonar_url
value: http://sonarqube.coolops.cn
pipelineRef:
name: rd-pipeline
workspaces:
- name: rd-repo-pvc
volumeClaimTemplate:
spec:
accessModes:
- ReadWriteOnce
storageClassName: local
resources:
requests:
storage: 1Gi
- name: docker-config
secret:
secretName: docker-config
- name: kubernetes-config
secret:
secretName: kubernetes-config</code>Define TriggerBinding
Map fields from a GitLab push event to the parameters expected by the TriggerTemplate:
<code>apiVersion: triggers.tekton.dev/v1beta1
kind: TriggerBinding
metadata:
name: trigger-rd-pipeline-bingding
namespace: tekton-devops-pipeline
spec:
params:
- name: gitrevision
value: $(body.ref)
- name: namespace
value: tekton-devops-pipeline
- name: gitrepositoryurl
value: $(body.project.git_http_url)
- name: projectname
value: $(body.project.name)</code>Define EventListener
Connect the TriggerTemplate and TriggerBinding:
<code>apiVersion: triggers.tekton.dev/v1beta1
kind: EventListener
metadata:
name: trigger-rd-pipeline-eventlistener
spec:
serviceAccountName: tekton-triggers-gitlab-sa
triggers:
- bindings:
- ref: trigger-rd-pipeline-bingding
template:
ref: trigger-rd-pipeline-template</code>ServiceAccount and RBAC
Create a ServiceAccount with the minimal permissions required by the EventListener and bind it to a ClusterRole:
<code>apiVersion: v1
kind: ServiceAccount
metadata:
name: tekton-triggers-gitlab-sa
secrets:
- name: gitlab-secret
- name: gitlab-auth
---
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: tekton-triggers-gitlab-minimal
rules:
- apiGroups: ["triggers.tekton.dev"]
resources: ["eventlisteners","triggerbindings","triggertemplates","clustertriggerbindings","clusterinterceptors","triggers"]
verbs: ["get","list","watch"]
- apiGroups: [""]
resources: ["configmaps","secrets","serviceaccounts"]
verbs: ["get","list","watch"]
- apiGroups: ["tekton.dev"]
resources: ["pipelineruns","pipelineresources","taskruns"]
verbs: ["create"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: tekton-triggers-gitlab-binding
subjects:
- kind: ServiceAccount
name: tekton-triggers-gitlab-sa
namespace: tekton-devops-pipeline
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: tekton-triggers-gitlab-minimal</code>Create GitLab Secret Token
<code>apiVersion: v1
kind: Secret
metadata:
name: gitlab-secret
type: Opaque
stringData:
secretToken: "coolops"</code>Expose EventListener via Ingress
<code>apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: el-trigger-test-eventlistener
spec:
rules:
- host: hello-word.webhook.coolops.cn
http:
paths:
- backend:
serviceName: el-trigger-rd-pipeline-eventlistener
servicePort: 8080</code>Create GitLab Webhook
Configure the webhook in GitLab to point to the Ingress URL and use the secret token defined above. After pushing code, GitLab sends a payload like the following:
<code>{
"object_kind": "push",
"event_name": "push",
"ref": "refs/heads/master",
"checkout_sha": "ac84d875c6094b5feebd477809a2021fd745c9df",
"project": {
"name": "Devops Hello World",
"git_http_url": "http://192.168.205.128/root/devops-hello-world.git"
},
"commits": [
{
"id": "ac84d875c6094b5feebd477809a2021fd745c9df",
"message": "ceshi ",
"added": [],
"modified": ["Jenkinsfile"],
"removed": []
}
]
}</code>The TriggerBinding extracts
$(body.ref),
$(body.project.git_http_url), and
$(body.project.name)from this payload, which are then passed to the TriggerTemplate to instantiate a
PipelineRun. The pipeline runs automatically, as shown in the following screenshot:
With these resources in place, any code push to GitLab triggers a Tekton PipelineRun via the configured webhook, achieving fully automated continuous deployment on Kubernetes.
Ops Development Stories
Maintained by a like‑minded team, covering both operations and development. Topics span Linux ops, DevOps toolchain, Kubernetes containerization, monitoring, log collection, network security, and Python or Go development. Team members: Qiao Ke, wanger, Dong Ge, Su Xin, Hua Zai, Zheng Ge, Teacher Xia.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.