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

216 lines
5.4 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 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):
```bash
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:
```bash
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):
```bash
./scripts/set-git-credentials.sh <your-github-username> <your-pat>
```
Verify:
```bash
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):
```bash
kubectl apply -f manifests/ci/pipeline/pipelinerun.yaml
```
Watch it run:
```bash
kubectl get pipelinerun -n tekton-pipelines -w
```
Or follow the logs with tkn (Tekton CLI, optional):
```bash
# If tkn is installed:
tkn pipelinerun logs -f -n tekton-pipelines bump-podinfo-to-670
```
Or follow individual TaskRun pods:
```bash
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
```bash
# 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.
```bash
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**.
```bash
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:
```bash
# 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.