Tekton Triggers with GitHub
Tekton Triggers allow us to automate the instantiation of pipelines based on external events. This means, for instance, we can start a pipeline every time a new pull request is created in our GitHub repository. This is the power of CI/CD in action!
Before we can create a trigger we need to install tekton, triggers and interceptors
kubectl apply --filename https://storage.googleapis.com/tekton-releases/pipeline/latest/release.yaml
kubectl apply --filename https://storage.googleapis.com/tekton-releases/triggers/latest/release.yaml
kubectl apply -f https://storage.googleapis.com/tekton-releases/triggers/latest/release.yaml
kubectl apply --filename https://storage.googleapis.com/tekton-releases/triggers/latest/interceptors.yaml
First we need to create the service account and the permissions:
apiVersion: v1
kind: ServiceAccount
metadata:
name: tekton-service-account
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: tekton-triggers-minimal
rules:
# EventListeners need to be able to fetch all namespaced resources
- apiGroups: ["triggers.tekton.dev"]
resources: ["eventlisteners", "triggerbindings", "triggertemplates", "triggers", "interceptors"]
verbs: ["get", "list", "watch"]
- apiGroups: [""]
# configmaps is needed for updating logging config
resources: ["configmaps"]
verbs: ["get", "list", "watch"]
# Permissions to create resources in associated TriggerTemplates
- apiGroups: ["tekton.dev"]
resources: ["pipelineruns", "pipelineresources", "taskruns"]
verbs: ["create"]
- apiGroups: [""]
resources: ["serviceaccounts"]
verbs: ["impersonate"]
- apiGroups: ["policy"]
resources: ["podsecuritypolicies"]
resourceNames: ["tekton-triggers"]
verbs: ["use"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: tekton-triggers-binding
subjects:
- kind: ServiceAccount
name: tekton-service-account
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: tekton-triggers-minimal
---
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: tekton-triggers-clusterrole
rules:
# EventListeners need to be able to fetch any clustertriggerbindings
- apiGroups: ["triggers.tekton.dev"]
resources: ["clustertriggerbindings", "clusterinterceptors", "interceptors"]
verbs: ["get", "list", "watch"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: tekton-triggers-clusterbinding
subjects:
- kind: ServiceAccount
name: tekton-service-account
namespace: default
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: tekton-triggers-clusterrole
That we apply with
kubectl apply -f rbac.yaml
After that we are going to create the pipeline that we will use later when we trigger the event.
apiVersion: tekton.dev/v1beta1
kind: Pipeline
metadata:
name: github-echo-pipeline
spec:
tasks:
- name: echo-message
taskSpec:
steps:
- name: echo
image: ubuntu
script: |
#!/bin/bash
echo "Pipeline triggered by a GitHub pull request!"
Let’s execute with
kubectl apply -f pipelines.yaml
Now we check the pipeline with
tkn pipeline list
Triggers in Tekton mainly consist of three components:
TriggerBinding
: Extracts data from the event payload.TriggerTemplate
: Uses the data to create Tekton resources.EventListener
: Listens for the external events."
Our EventListener
will listen for GitHub webhook events and use the TriggerBinding
and TriggerTemplate
to execute our pipeline.
apiVersion: triggers.tekton.dev/v1beta1
kind: EventListener
metadata:
name: github-pr
spec:
serviceAccountName: tekton-service-account
triggers:
- name: pr-trigger
bindings:
- ref: github-pr-trigger-binding
template:
ref: github-pr-trigger-template
resources:
kubernetesResource:
serviceType: LoadBalancer
Now we execute
kubectl apply -f evenlistener.yaml
We can check with
tkn eventlistener list
Now we get the service with
kubectl get svc
And we check the pod created with
kubectl get pods
Let's define our TriggerBinding
to extract the necessary information from GitHub's webhook payload
apiVersion: triggers.tekton.dev/v1beta1
kind: TriggerBinding
metadata:
name: github-pr-trigger-binding
spec:
params:
- name: revision
value: $(body.pull_request.head.sha)
- name: repo-url
value: $(body.repository.clone_url)
This binding extracts the git revision and repository URL from the event
kubectl apply -f trigerbinding.yaml
Now we check the pipeline with
tkn triggerbinding list
Now, let's define how the extracted data will be used to instantiate our pipeline
apiVersion: triggers.tekton.dev/v1beta1
kind: TriggerTemplate
metadata:
name: github-pr-trigger-template
spec:
params:
- name: revision
default: main
- name: repo-url
resourcetemplates:
- apiVersion: tekton.dev/v1beta1
kind: PipelineRun
metadata:
generateName: my-pipeline-
spec:
pipelineRef:
name: github-echo-pipeline
params:
- name: repo-url
value: $(tt.params.repo-url)
- name: revision
value: $(tt.params.revision)
This template will create a unique PipelineRun
for each event using the $(uid)
variable.
kubectl apply -f trigger.yaml
And now we can check the event trigger with
tkn triggertemplate list
Now we are going to need to know how connect to this trigger and to do that we are going to use the Load Balancer service that was created when the eventlistener was created.
curl -vvv http://IP:8080
Next step is setup GitHub with this IP to the event listener
Go to your GitHub repository:
Navigate to
Settings
>Webhooks
>Add webhook
.Paste the
ngrok
URL into thePayload URL
field.Set the
Content type
toapplication/json
.For events, select
Pull requests
.Save the webhook.
Let's test our setup. Create a new pull request in your GitHub repository. This should automatically trigger
When the PR is create if we execute
tkn pipeline list
We can see that the pipeline has started and it is running and after a few seconds if we check again pipeline is done and Succeeded. Now we can see the logs with
tkn pipeline logs
And as you can see our echo in the pipeline has been executed!
We hope you found this tutorial insightful. Until next time, happy coding!
Here' the same article in video form for your convenience: