Lab 1: Application CI Pipeline
Overview
Create a Tekton CI pipeline that clones your application source, builds and tests it, retrieves registry credentials from Vault, and pushes the container image. Then wire up Tekton Triggers to fire the pipeline automatically when code is pushed to GitLab.
Pipeline Workspace and ServiceAccount
Create a workspace PVC and a ServiceAccount for the pipeline:
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: pipeline-workspace-pvc
namespace: <your_namespace>
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 5Gi
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: pipeline
namespace: <your_namespace>
Apply them:
oc apply -f pipeline-workspace.yaml
Retrieve Registry Credentials from Vault
Create a Tekton Task that authenticates to Vault using the Kubernetes auth method configured in the Supporting Services section and writes registry credentials to the workspace:
apiVersion: tekton.dev/v1
kind: Task
metadata:
name: vault-fetch-registry-creds
namespace: <your_namespace>
spec:
workspaces:
- name: source
results:
- name: registry-server
- name: registry-username
- name: registry-password
steps:
- name: fetch
image: quay.io/curl/curl:latest
script: |
#!/bin/sh
set -e
# Authenticate to Vault using ServiceAccount token
VAULT_ADDR="http://vault.vault.svc:8200"
SA_TOKEN=$(cat /var/run/secrets/kubernetes.io/serviceaccount/token)
VAULT_TOKEN=$(curl -s --request POST \
"${VAULT_ADDR}/v1/auth/kubernetes/login" \
--data "{\"role\":\"pipeline\",\"jwt\":\"${SA_TOKEN}\"}" \
| grep -o '"client_token":"[^"]*"' | cut -d'"' -f4)
# Fetch registry credentials
CREDS=$(curl -s --header "X-Vault-Token: ${VAULT_TOKEN}" \
"${VAULT_ADDR}/v1/secret/data/registry")
echo "${CREDS}" | grep -o '"server":"[^"]*"' | cut -d'"' -f4 \
| tr -d '\n' > $(results.registry-server.path)
echo "${CREDS}" | grep -o '"username":"[^"]*"' | cut -d'"' -f4 \
| tr -d '\n' > $(results.registry-username.path)
echo "${CREDS}" | grep -o '"password":"[^"]*"' | cut -d'"' -f4 \
| tr -d '\n' > $(results.registry-password.path)
Create the Pipeline
Define the CI pipeline with four tasks: clone, build/test, fetch credentials, and build/push the container image:
apiVersion: tekton.dev/v1
kind: Pipeline
metadata:
name: parasol-ci
namespace: <your_namespace>
spec:
params:
- name: git-url
type: string
- name: git-revision
type: string
default: main
- name: image-name
type: string
workspaces:
- name: shared-workspace
tasks:
- name: clone
taskRef:
name: git-clone
kind: ClusterTask
params:
- name: url
value: $(params.git-url)
- name: revision
value: $(params.git-revision)
workspaces:
- name: output
workspace: shared-workspace
- name: build-and-test
runAfter: [clone]
taskRef:
name: maven
kind: ClusterTask
params:
- name: GOALS
value: ["package", "-DskipTests=false"]
workspaces:
- name: source
workspace: shared-workspace
- name: maven-settings
workspace: shared-workspace
- name: fetch-creds
runAfter: [clone]
taskRef:
name: vault-fetch-registry-creds
workspaces:
- name: source
workspace: shared-workspace
- name: build-image
runAfter: [build-and-test, fetch-creds]
taskRef:
name: buildah
kind: ClusterTask
params:
- name: IMAGE
value: $(params.image-name):$(params.git-revision)
workspaces:
- name: source
workspace: shared-workspace
git-clone, maven, and buildah are ClusterTasks provided by OpenShift Pipelines. Run tkn clustertask list to verify they are available.
|
Apply the tasks and pipeline:
oc apply -f vault-fetch-task.yaml
oc apply -f parasol-ci-pipeline.yaml
Test the Pipeline Manually
Run the pipeline once to verify it works before adding webhooks:
tkn pipeline start parasol-ci \
--param git-url=https://<gitlab_host>/parasol-insurance \
--param git-revision=main \
--param image-name=image-registry.openshift-image-registry.svc:5000/<your_namespace>/parasol-insurance \
--workspace name=shared-workspace,claimName=pipeline-workspace-pvc \
--serviceaccount pipeline \
--showlog
Watch the logs to confirm all tasks complete successfully.
Set Up Webhooks with Tekton Triggers
Create the trigger resources so the pipeline runs automatically when code is pushed to GitLab.
TriggerBinding
Maps fields from the GitLab webhook payload to pipeline parameters:
apiVersion: triggers.tekton.dev/v1beta1
kind: TriggerBinding
metadata:
name: gitlab-push-binding
namespace: <your_namespace>
spec:
params:
- name: git-url
value: $(body.repository.git_http_url)
- name: git-revision
value: $(body.checkout_sha)
TriggerTemplate
Creates a PipelineRun when triggered:
apiVersion: triggers.tekton.dev/v1beta1
kind: TriggerTemplate
metadata:
name: gitlab-push-template
namespace: <your_namespace>
spec:
params:
- name: git-url
- name: git-revision
resourcetemplates:
- apiVersion: tekton.dev/v1
kind: PipelineRun
metadata:
generateName: parasol-ci-
spec:
pipelineRef:
name: parasol-ci
params:
- name: git-url
value: $(tt.params.git-url)
- name: git-revision
value: $(tt.params.git-revision)
- name: image-name
value: image-registry.openshift-image-registry.svc:5000/<your_namespace>/parasol-insurance
workspaces:
- name: shared-workspace
persistentVolumeClaim:
claimName: pipeline-workspace-pvc
taskRunTemplate:
serviceAccountName: pipeline
EventListener
Exposes an HTTP endpoint that GitLab can send webhooks to:
apiVersion: triggers.tekton.dev/v1beta1
kind: EventListener
metadata:
name: gitlab-listener
namespace: <your_namespace>
spec:
serviceAccountName: pipeline
triggers:
- name: gitlab-push
bindings:
- ref: gitlab-push-binding
template:
ref: gitlab-push-template
Apply all trigger resources:
oc apply -f trigger-binding.yaml
oc apply -f trigger-template.yaml
oc apply -f event-listener.yaml
Expose the EventListener
Create a route so GitLab can reach the EventListener:
oc expose svc el-gitlab-listener -n <your_namespace>
Get the webhook URL:
echo "$(oc get route el-gitlab-listener -n <your_namespace> -o jsonpath='{.spec.host}')"
Verify the Pipeline
Push a change to your repository and confirm:
# Check for new pipeline runs
tkn pipelinerun list -n <your_namespace>
# Follow the latest run
tkn pipelinerun logs -f -n <your_namespace>
Verify the image was pushed:
oc get imagestream parasol-insurance -n <your_namespace>
You should see the image tagged with the commit SHA.
Next Steps
Proceed to Application Deployment with Argo CD.