Tekton Triggers in der Praxis
Dieser Artikel ist Teil einer Reihe, die sich mit Tekton CI/CD und dem praktischen Einsatz beschäftigt.
Im ersten Artikel haben wir die Installation vorgenommen und die erste Pipeline erstellt. Im zweiten Artikel haben wir die Vorteile von Tekton durch den geschickten Einsatz der wiederverwendbaren Komponenten erleben können. Dieser Artikel beschäftigt sich mit der Einbettung von Tekton in einen Projektkontext. Das Ziel für diesen Artikel ist erstmal die Grundlagen dafür zu schaffen. Wir werden mit Tekton Triggers ein WebHook Interface öffnen und ein Gitlab-WebHook-JSON-Objekt schicken, das einen Build in der Tekton-Installation startet.
Möglicher Einsatz
Was meine ich an der Stelle mit einem „Projektkontext“? Bisher haben wir Tekton in einem isolierten Setup laufen lassen, was in der Praxis nicht hilfreich ist, denn damit geht die Sichtbarkeit auf die eigene Arbeit schnell verloren. Die Gesamtsicht ist über mindestens zwei Systeme verteilt, welche untereinander nicht verknüpft sind. Schlimmer sogar, die Tekton muss bisher manuell gestartet werden.
Warum nicht einfach das Integrierte nutzen?
Der Trend bei den großen Plattformen wie GitHub oder Gitlab ist die Integration der Entwicklungstools. Angefangen vom Git Repository über eine Pipeline-Lösung wie GitHub Actions , über das Container Repository bis hin zur Integration der Organisationstools . Der dahinterstehende Grund dabei ist die Transparenz zu erhöhen.
Dem entgegen steht die Nutzung von Tekton für den Aspekt der CI/CD-Ausführung. Sinn ergibt das, wenn der Wunsch der Compliance, Wiederverwendbarkeit und vermeintlicher Zukunftsfähigkeit steigt. Die richtungsweisende Vision ist die API-Kompatibilität in die Breite zu tragen und ein nachhaltiges Öko-System aufzubauen. Dies ist natürlich erstmal der Beginn einer Reise und es bleibt abzuwarten, ob dies realistisch ist. Bei Entscheidungen die das CI/CD-System betreffen ist die Zukunftsfähigkeit aus meiner Sicht ein interessantes Kriterium.
Schreibt gerne eure Meinung in die Kommentare oder gebt gerne per Twitter Feedback.
Triggers Installation
Tekton Triggers sind eine weitere Komponente, die im Cluster installiert sein muss. Hierzu können wir der Installationsanleitung im GitHub – Projekt folgend die notwendigen Manifeste einspielen. Im Kapitel „Setting Up Tekton Triggers “ findet man die beiden Dateien, welche über das Tool der Wahl eingespielt werden können.
Die Datei mit dem Namen release.yaml beinhaltet die gesamte Triggers-Basisinstallation und die interceptors.yaml-Datei bringt Interceptoren für die einfache Anbindung von Systemen wie gitlab, github oder bitbucket mit. Diese sollten ebenfalls installiert werden, denn wir werden einen installierten ClusterInterceptor
später noch benutzen. Im nächsten Abschnitt beschreibe ich, welchen Zweck diese haben.
An dieser Stelle der kurze Hinweis, dass die Tekton-Installation inklusive der Tekton Triggers in meinem GitHub Projekt fertig aufgebaut ist. Einfach klonen und testen. Alles Wichtige ist in der README.md oder auch in der github Action zu finden, die den Code bei jedem Push testet. Mehr zu diesem Projekt ist im Softwerker Vol. 19 zu finden, denn dort beschreibe ich das gesamte Projekt in der Tiefe und zeige die Zusammenhänge auf.
Triggers-API-Objekte
Die Triggers API sieht auf den ersten Blick sehr kompliziert aus, jedenfalls ist es mir so gegangen. Am besten wir gehen Schritt für Schritt durch und verstehen, wofür das jeweilige Objekt genutzt wird. Hier meine kurze Remarkable-Notiz die mir bei der Orientierung sehr geholfen hat:
EventListener
Unser Ziel ist einen WebHook von außen zu empfangen. Auf Seite von Kubernetes bedeutet dies, dass ein Service einen TCP-Port zur Verfügung stellt, der dafür genutzt werden kann. Als Anker wird der EventListener genutzt und mit den weiteren Objekten verknüpft. Neben dem zu verwendenden ServiceAccount
werden an dieser Stelle die Trigger angehängt. Hinter einem EventListener können beliebig viele Trigger auf unterschiedliche Anfragen lauschen.
Durch Erstellung des EventListeners wird automatisch der beschriebene Service erstellt. Nur kurz zur Einordnung: Dieser Service ist nur im Cluster verfügbar und kann je nach Use Case z. B. durch ein Ingress
für andere Applikationen außerhalb des Clusters sichtbar gemacht werden.
Trigger
Die Aufgabe des Triggers ist darauf aufbauend die Anfragen zuzuordnen und durch die Verwendung von Interceptoren, TriggerBindings und TriggerTemplates zu verarbeiten. Der Trigger hat einen Namen und alles weitere wird in den genutzten Objekten verwendet.
Interceptor
WebHooks werden häufig durch bestimmte Systeme aufgerufen. Im Falle von Tekton sind dies Git Repositories wie z. B. Gitlab oder Github. Die Formate des Aufrufs und die genutzten Sicherheitsmechanismen unterscheiden sich zwischen den Systemen.
Ein WebHook von Github wird z. B. mit einem HMAC des Payloads und mithilfe eines geheimen Strings abgesichert, wohingegen durch Gitlab ein X-Gitlab-Token
HTTP Header mit einem Secret hinzugefügt wird.
Wir können den passenden Interceptor nutzen, das notwendige Secret und den Event-Type definieren.
TriggerBinding
Mit diesem Binding greifen wir auf den JSON Body der Anfrage zu und extrahieren die notwendigen Informationen, wie z. B. die URL des git repositories und den Branch-Namen.
Die extrahierten Werte sind dann als Parameter verwendbar und können im letzten Objekt verwendet werden.
TriggerTemplate
An dieser Stelle wird jetzt der eigentlich Aufruf vorgenommen, und zwar werden hier die extrahierten Parameter referenziert und einem Template, z. B. einem PipelineRun, zur Verfügung gestellt. Der PipelineRun wird bei einem WebHook-Aufruf gestartet und das Wissen aus den ersten Artikeln greift hier wieder.
Praktische Umsetzung im Sample Projekt
Hier das komplette Beispiel aus dem Demo-Projekt , welches die angesprochenen Objekte nutzt:
1apiVersion: triggers.tekton.dev/v1beta1 2kind: EventListener 3metadata: 4 name: gitlab-listener 5spec: 6 serviceAccountName: tekton-triggers-gitlab-sa 7 triggers: 8 - name: gitlab-push-events-trigger 9 interceptors: 10 - name: "verify-gitlab-payload" 11 ref: 12 name: "gitlab" 13 kind: ClusterInterceptor 14 params: 15 - name: secretRef 16 value: 17 secretName: "gitlab-secret" 18 secretKey: "secretToken" 19 - name: eventTypes 20 value: 21 - "Push Hook" 22 bindings: 23 - name: git-revision 24 value: $(body.checkout_sha) 25 - name: git-repository-url 26 value: $(body.repository.git_http_url) 27 template: 28 spec: 29 params: 30 - name: git-revision 31 - name: git-repository-url 32 resourcetemplates: 33 - apiVersion: tekton.dev/v1beta1 34 kind: PipelineRun 35 metadata: 36 generateName: show-parameter-triggered-pipeline- 37 spec: 38 pipelineRef: 39 name: show-parameter-pipeline 40 params: 41 - name: image 42 value: test-image-build-by-buildpack-and-triggered:latest 43 - name: git-repository-url 44 value: $(tt.params.git-repository-url) 45 - name: git-revision 46 value: $(tt.params.git-revision)
In dem Beispiel-Projekt wird der Aufruf durch eine Gitlab-Instanz durch einen curl simuliert. Der Aufruf enthält, wie bei den Interceptoren beschrieben, das notwendige Secret und die eigentlichen Daten des Aufrufs.
1curl -v \ 2-H 'X-GitLab-Token: 1234567' \ 3-H 'X-Gitlab-Event: Push Hook' \ 4-H 'Content-Type: application/json' \ 5--data-binary "@gitlab-push-event.json" \ 6http://localhost:8081
In diesem kurzen Ausschnitt möchte ich beschreiben, wie eine Zuordnung zum Aufruf stattfinden kann, denn auf der einen Seite ist dieser Aufruf ein Fire-and-Forget-Lösung, doch auf der anderen Seite kann es notwendig sein, im Rahmen einer Fehlersuche die Verarbeitung nachzuvollziehen. Möglich ist dies, weil Tekton Triggers ein JSON-Objekt zurückliefert, welches eine Event-ID definiert. Diese Event-ID wird als Label an den PipelineRun weitergegeben, der dann darüber identifiziert werden kann. Im folgenden Snippet ist dies in der Praxis dargestellt und komplett hier zu finden .
EVENT_ID=$(./trigger-tekton.sh | jq -r '.eventID')
echo "EVENT-ID found in the response of the web-hook call${EVENT_ID}"
# Wait for the triggered PipelineRun to complete
kubectl -n tekton-pipelines wait --for=condition=SUCCEEDED=True --timeout=60s pipelineruns.tekton.dev -l triggers.tekton.dev/triggers-eventid==$EVENT_ID
Zusammenfassung und Ausblick
Dieser Artikel zeigt anhand eines praktischen Beispiels, wie Tekton in eine vorhandene Umgebung eingebunden und genutzt werden kann. An dieser Stelle haben wir ein CI-System aufgebaut, das automatisch Pipelines startet wenn ein Push stattgefunden hat.
Wie geht die Serie weiter? Wie angekündigt wird ein Post folgen, der die Integration mit Gitlab praktisch darstellt – und zwar auf Basis eines AWS EKS Clusters. Was danach kommt ist noch offen: Möglich wäre es z. B., einen eigenen Task zu entwickeln und zur Verfügung zu stellen oder auch in die Richtung der Supply Chain Security abzubiegen.
Wenn ihr Fragen oder Anmerkungen zu dem Post habt, freue ich mich über Rückmeldungen von euch hier auf dem Blog, per E-Mail oder gerne auf Twitter .
Weitere Beiträge
von Marco Paga
Dein Job bei codecentric?
Jobs
Agile Developer und Consultant (w/d/m)
Alle Standorte
Weitere Artikel in diesem Themenbereich
Entdecke spannende weiterführende Themen und lass dich von der codecentric Welt inspirieren.
Gemeinsam bessere Projekte umsetzen.
Wir helfen deinem Unternehmen.
Du stehst vor einer großen IT-Herausforderung? Wir sorgen für eine maßgeschneiderte Unterstützung. Informiere dich jetzt.
Hilf uns, noch besser zu werden.
Wir sind immer auf der Suche nach neuen Talenten. Auch für dich ist die passende Stelle dabei.
Blog-Autor*in
Marco Paga
Senior Solution Architect
Du hast noch Fragen zu diesem Thema? Dann sprich mich einfach an.
Du hast noch Fragen zu diesem Thema? Dann sprich mich einfach an.