ops-demo/docs/04-tekton-pipeline.md
Paul Harkink fb2edcac9e feat(ex04): Tekton pipeline — GitOps image-tag bump loop
- apps/ci/tekton.yaml: installs Tekton v0.65.1 via kustomize remote ref
- apps/ci/pipeline.yaml: deploys pipeline resources via ArgoCD
- manifests/ci/tekton/kustomization.yaml: points to upstream release
- manifests/ci/pipeline/serviceaccount.yaml: pipeline-runner SA
- manifests/ci/pipeline/pipeline.yaml: 4-task Pipeline (clone, validate, bump, push)
- manifests/ci/pipeline/pipelinerun.yaml: bumps podinfo 6.6.2 → 6.7.0
- scripts/set-git-credentials.sh: creates git-credentials Secret (not in git)
- docs/04-tekton-pipeline.md: Exercise 04 participant guide
2026-02-28 15:32:39 +01:00

5.4 KiB
Raw Blame History

Exercise 04 — Tekton Pipeline (GitOps Loop)

Time: ~45 min Goal: Build an automated pipeline that bumps the podinfo image tag in Git and watches ArgoCD roll out the new version — the full GitOps CI/CD loop.


What you'll learn

  • Tekton concepts: Task, Pipeline, PipelineRun, Workspace
  • How a pipeline commits to Git to trigger a GitOps deployment (no container registry needed)
  • The full loop: pipeline push → ArgoCD detects → rolling update → new version in browser

The loop visualised

You trigger PipelineRun
        │
        ▼
Task 1: clone repo
Task 2: validate manifests (kubectl dry-run)
Task 3: bump image tag  →  deployment.yaml: 6.6.2 → 6.7.0
Task 4: git commit + push
        │
        ▼
ArgoCD polls repo (or click Refresh)
        │
        ▼
ArgoCD syncs podinfo Deployment
        │
        ▼
Rolling update → podinfo v6.7.0 in your browser

Prerequisites

Exercises 0103 complete. podinfo is reachable at http://podinfo.192.168.56.200.nip.io and shows version 6.6.2.

You need:

  • A GitHub account with write access to the ops-demo repo
  • A GitHub Personal Access Token (PAT) with repo scope

Steps

1. Verify Tekton is installed

The apps/ci/tekton.yaml and apps/ci/pipeline.yaml ArgoCD Applications are already in the repo. ArgoCD is installing Tekton via a kustomize remote reference.

Wait for the install to complete (~35 min after the app appears in ArgoCD):

kubectl get pods -n tekton-pipelines
# NAME                                         READY   STATUS    RESTARTS
# tekton-pipelines-controller-xxx              1/1     Running   0
# tekton-pipelines-webhook-xxx                 1/1     Running   0

Also check that the pipeline resources are synced:

kubectl get pipeline -n tekton-pipelines
# NAME                 AGE
# gitops-image-bump    Xm

2. Set up Git credentials

The pipeline needs to push a commit to GitHub. Create a Personal Access Token:

  1. Go to GitHub → Settings → Developer settings → Personal access tokens → Fine-grained tokens (or classic with repo scope)
  2. Give it write access to the ops-demo repository

Then create the Kubernetes Secret (this command replaces the placeholder Secret if it already exists):

./scripts/set-git-credentials.sh <your-github-username> <your-pat>

Verify:

kubectl get secret git-credentials -n tekton-pipelines
# NAME              TYPE     DATA   AGE
# git-credentials   Opaque   2      5s

3. Trigger the pipeline

Apply the PipelineRun (this is the only kubectl apply you'll run in this exercise):

kubectl apply -f manifests/ci/pipeline/pipelinerun.yaml

Watch it run:

kubectl get pipelinerun -n tekton-pipelines -w

Or follow the logs with tkn (Tekton CLI, optional):

# If tkn is installed:
tkn pipelinerun logs -f -n tekton-pipelines bump-podinfo-to-670

Or follow individual TaskRun pods:

kubectl get pods -n tekton-pipelines -w
# Once a pod appears, you can:
kubectl logs -n tekton-pipelines <pod-name> -c step-bump --follow

The PipelineRun should complete in ~23 minutes.


4. Verify the commit

# Inside the VM — check the latest commit on the remote
git fetch origin
git log origin/main --oneline -3
# You should see something like:
# a1b2c3d chore(pipeline): bump podinfo to 6.7.0
# ...

Or check GitHub directly in your browser.


5. Watch ArgoCD sync

In the ArgoCD UI, click Refresh on the podinfo application.

ArgoCD will detect that manifests/apps/podinfo/deployment.yaml changed and start a rolling update.

kubectl rollout status deployment/podinfo -n podinfo
# deployment "podinfo" successfully rolled out

6. Confirm in the browser

Open http://podinfo.192.168.56.200.nip.io — you should now see version 6.7.0.

curl http://podinfo.192.168.56.200.nip.io | jq .version
# "6.7.0"

The full loop is complete.


Expected outcome

PipelineRun STATUS: Succeeded
deployment.yaml image tag: 6.7.0
podinfo UI version: 6.7.0

Re-running the pipeline

The PipelineRun name must be unique. To run again:

# Option A: delete and re-apply with same name
kubectl delete pipelinerun bump-podinfo-to-670 -n tekton-pipelines
kubectl apply -f manifests/ci/pipeline/pipelinerun.yaml

# Option B: create a new run with a different name
kubectl create -f manifests/ci/pipeline/pipelinerun.yaml

Troubleshooting

Symptom Fix
PipelineRun stuck in "Running" forever kubectl describe pipelinerun -n tekton-pipelines bump-podinfo-to-670
git-credentials Secret not found Run ./scripts/set-git-credentials.sh first
Push fails: 403 Forbidden PAT has insufficient scope — needs repo write access
Push fails: remote already has this commit Image tag already at 6.7.0; the pipeline is idempotent (nothing to push)
ArgoCD not syncing after push Click Refresh in the UI; default poll interval is 3 min
Validate task fails Check kubectl apply --dry-run=client -f manifests/apps/podinfo/ manually

What's next

Exercise 05 is a quick wrap-up: you'll look at the full picture of what you built and optionally trigger another upgrade cycle to cement the GitOps loop.

If you have time, try the Bonus Exercise 06: deploy Prometheus + Grafana and see cluster and podinfo metrics in a live dashboard.