Setup Tekton Pipelines 0.62 for Kubernetes CI/CD with security scanning integration

Advanced 45 min Apr 25, 2026 559 views
Ubuntu 24.04 Debian 12 AlmaLinux 9 Rocky Linux 9

Configure Tekton Pipelines for cloud-native CI/CD with automated security scanning, Git webhooks, and production-ready RBAC policies. Build secure container pipelines with integrated vulnerability detection and compliance checks.

Prerequisites

  • Running Kubernetes cluster (1.24+) with cluster-admin access
  • kubectl configured and authenticated
  • Container registry credentials
  • Git repository with application source code

What this solves

Tekton Pipelines provides Kubernetes-native CI/CD automation with reusable tasks, parallel execution, and built-in security scanning. Unlike traditional CI/CD tools, Tekton runs entirely on Kubernetes, scaling automatically and integrating deeply with container workflows. This tutorial sets up Tekton 0.62 with security scanning, Git triggers, and production hardening for enterprise container deployments.

Prerequisites

  • Running Kubernetes cluster (1.24+) with cluster-admin access
  • kubectl configured to access your cluster
  • Git repository with container application source code
  • Docker registry credentials for image storage

Step-by-step installation

Install Tekton Pipelines core components

Deploy the Tekton Pipelines operator and CRDs to your Kubernetes cluster.

kubectl apply --filename https://storage.googleapis.com/tekton-releases/pipeline/previous/v0.62.0/release.yaml

Verify the installation completed successfully:

kubectl get pods --namespace tekton-pipelines
kubectl get crd | grep tekton

Install Tekton Triggers for Git webhook integration

Tekton Triggers enables automatic pipeline execution from Git events like push and pull requests.

kubectl apply --filename https://storage.googleapis.com/tekton-releases/triggers/previous/v0.27.0/release.yaml
kubectl apply --filename https://storage.googleapis.com/tekton-releases/triggers/previous/v0.27.0/interceptors.yaml

Wait for all trigger components to be ready:

kubectl get pods --namespace tekton-pipelines-resolvers
kubectl get pods --namespace tekton-pipelines

Install Tekton Dashboard for web interface

The dashboard provides a graphical interface for managing pipelines and viewing execution logs.

kubectl apply --filename https://storage.googleapis.com/tekton-releases/dashboard/previous/v0.43.0/release.yaml

Create a service to access the dashboard:

apiVersion: v1
kind: Service
metadata:
  name: tekton-dashboard-external
  namespace: tekton-pipelines
spec:
  type: NodePort
  ports:
  - port: 9097
    targetPort: 9097
    nodePort: 32000
  selector:
    app.kubernetes.io/name: dashboard
    app.kubernetes.io/component: dashboard
kubectl apply -f /tmp/tekton-dashboard-service.yaml

Configure RBAC for pipeline execution

Create service accounts with minimal permissions for secure pipeline runs.

apiVersion: v1
kind: ServiceAccount
metadata:
  name: tekton-build-sa
  namespace: default
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  namespace: default
  name: tekton-build-role
rules:
- apiGroups: [""]
  resources: ["pods", "services", "endpoints", "persistentvolumeclaims", "configmaps", "secrets"]
  verbs: ["get", "list", "create", "update", "delete"]
- apiGroups: ["apps"]
  resources: ["deployments", "replicasets"]
  verbs: ["get", "list", "create", "update", "delete"]
- apiGroups: [""]
  resources: ["pods/log"]
  verbs: ["get", "list"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: tekton-build-binding
  namespace: default
subjects:
- kind: ServiceAccount
  name: tekton-build-sa
  namespace: default
roleRef:
  kind: Role
  name: tekton-build-role
  apiGroup: rbac.authorization.k8s.io
kubectl apply -f /tmp/tekton-rbac.yaml

Create Docker registry secret

Configure credentials for pushing built images to your container registry.

kubectl create secret docker-registry docker-registry-secret \
  --docker-server=registry.example.com \
  --docker-username=your-username \
  --docker-password=your-password \
  --docker-email=your-email@example.com

Link the secret to the service account:

kubectl patch serviceaccount tekton-build-sa -p '{"secrets":[{"name":"docker-registry-secret"}]}'

Install security scanning tasks

Add Tekton tasks for container vulnerability scanning with Trivy and code analysis with SonarQube.

apiVersion: tekton.dev/v1beta1
kind: Task
metadata:
  name: trivy-scanner
  namespace: default
spec:
  description: Scan container images for vulnerabilities using Trivy
  params:
  - name: image-url
    description: Image URL to scan
    type: string
  - name: severity
    description: Severity levels to report
    default: "HIGH,CRITICAL"
    type: string
  steps:
  - name: scan
    image: aquasec/trivy:latest
    command:
    - trivy
    args:
    - image
    - --severity
    - $(params.severity)
    - --no-progress
    - --format
    - table
    - $(params.image-url)
---
apiVersion: tekton.dev/v1beta1
kind: Task
metadata:
  name: sonarqube-scanner
  namespace: default
spec:
  description: Analyze code quality with SonarQube
  params:
  - name: sonar-host-url
    description: SonarQube server URL
    type: string
  - name: sonar-project-key
    description: Project key in SonarQube
    type: string
  workspaces:
  - name: source
    description: Source code workspace
  steps:
  - name: scan
    image: sonarsource/sonar-scanner-cli:latest
    workingDir: $(workspaces.source.path)
    env:
    - name: SONAR_HOST_URL
      value: $(params.sonar-host-url)
    - name: SONAR_SCANNER_OPTS
      value: "-Xmx512m"
    command:
    - sonar-scanner
    args:
    - -Dsonar.projectKey=$(params.sonar-project-key)
    - -Dsonar.sources=.
kubectl apply -f /tmp/security-tasks.yaml

Create build and test tasks

Define reusable tasks for Git operations, container building, and application testing.

apiVersion: tekton.dev/v1beta1
kind: Task
metadata:
  name: git-clone
  namespace: default
spec:
  description: Clone Git repository
  params:
  - name: url
    description: Git repository URL
    type: string
  - name: revision
    description: Git revision to check out
    default: main
    type: string
  workspaces:
  - name: output
    description: Cloned repository output
  steps:
  - name: clone
    image: alpine/git:latest
    workingDir: $(workspaces.output.path)
    command:
    - git
    args:
    - clone
    - --branch
    - $(params.revision)
    - --single-branch
    - --depth
    - "1"
    - $(params.url)
    - .
---
apiVersion: tekton.dev/v1beta1
kind: Task
metadata:
  name: kaniko-build
  namespace: default
spec:
  description: Build and push container image using Kaniko
  params:
  - name: image
    description: Name of the image to build
    type: string
  - name: dockerfile
    description: Path to Dockerfile
    default: ./Dockerfile
    type: string
  workspaces:
  - name: source
    description: Source code workspace
  steps:
  - name: build-and-push
    image: gcr.io/kaniko-project/executor:latest
    workingDir: $(workspaces.source.path)
    env:
    - name: DOCKER_CONFIG
      value: /kaniko/.docker
    command:
    - /kaniko/executor
    args:
    - --dockerfile=$(params.dockerfile)
    - --context=dir://$(workspaces.source.path)
    - --destination=$(params.image)
    - --cache=true
    - --compressed-caching
    volumeMounts:
    - name: docker-config
      mountPath: /kaniko/.docker
  volumes:
  - name: docker-config
    secret:
      secretName: docker-registry-secret
      items:
      - key: .dockerconfigjson
        path: config.json
---
apiVersion: tekton.dev/v1beta1
kind: Task
metadata:
  name: run-tests
  namespace: default
spec:
  description: Run application unit tests
  params:
  - name: test-command
    description: Command to run tests
    default: "npm test"
    type: string
  workspaces:
  - name: source
    description: Source code workspace
  steps:
  - name: test
    image: node:18-alpine
    workingDir: $(workspaces.source.path)
    command:
    - sh
    args:
    - -c
    - |
      npm install
      $(params.test-command)
kubectl apply -f /tmp/build-tasks.yaml

Create CI/CD pipeline with security integration

Define a complete pipeline that clones code, runs tests, builds images, performs security scans, and deploys to staging.

apiVersion: tekton.dev/v1beta1
kind: Pipeline
metadata:
  name: secure-build-deploy
  namespace: default
spec:
  description: Secure CI/CD pipeline with vulnerability scanning
  params:
  - name: git-url
    description: Git repository URL
    type: string
  - name: git-revision
    description: Git revision
    default: main
    type: string
  - name: image-name
    description: Container image name
    type: string
  - name: sonar-host
    description: SonarQube server URL
    type: string
  - name: sonar-project
    description: SonarQube project key
    type: string
  workspaces:
  - name: shared-data
    description: Shared workspace for pipeline data
  tasks:
  - name: fetch-source
    taskRef:
      name: git-clone
    workspaces:
    - name: output
      workspace: shared-data
    params:
    - name: url
      value: $(params.git-url)
    - name: revision
      value: $(params.git-revision)
  
  - name: code-analysis
    taskRef:
      name: sonarqube-scanner
    runAfter:
    - fetch-source
    workspaces:
    - name: source
      workspace: shared-data
    params:
    - name: sonar-host-url
      value: $(params.sonar-host)
    - name: sonar-project-key
      value: $(params.sonar-project)
  
  - name: run-unit-tests
    taskRef:
      name: run-tests
    runAfter:
    - fetch-source
    workspaces:
    - name: source
      workspace: shared-data
    params:
    - name: test-command
      value: "npm test -- --coverage"
  
  - name: build-image
    taskRef:
      name: kaniko-build
    runAfter:
    - code-analysis
    - run-unit-tests
    workspaces:
    - name: source
      workspace: shared-data
    params:
    - name: image
      value: $(params.image-name):$(params.git-revision)
  
  - name: security-scan
    taskRef:
      name: trivy-scanner
    runAfter:
    - build-image
    params:
    - name: image-url
      value: $(params.image-name):$(params.git-revision)
    - name: severity
      value: "HIGH,CRITICAL"
  
  - name: deploy-staging
    runAfter:
    - security-scan
    taskSpec:
      params:
      - name: image
        type: string
      steps:
      - name: deploy
        image: bitnami/kubectl:latest
        command:
        - kubectl
        args:
        - set
        - image
        - deployment/app-staging
        - app=$(params.image)
        - --namespace=staging
    params:
    - name: image
      value: $(params.image-name):$(params.git-revision)
kubectl apply -f /tmp/secure-pipeline.yaml

Configure Git webhook triggers

Set up automatic pipeline execution when code is pushed to your Git repository.

apiVersion: triggers.tekton.dev/v1beta1
kind: EventListener
metadata:
  name: github-listener
  namespace: default
spec:
  serviceAccountName: tekton-build-sa
  triggers:
  - name: github-push-trigger
    interceptors:
    - ref:
        name: "github"
      params:
      - name: "secretRef"
        value:
          secretName: github-webhook-secret
          secretKey: secretToken
      - name: "eventTypes"
        value: ["push"]
    bindings:
    - ref: github-push-binding
    template:
      ref: secure-pipeline-template
---
apiVersion: triggers.tekton.dev/v1beta1
kind: TriggerBinding
metadata:
  name: github-push-binding
  namespace: default
spec:
  params:
  - name: git-url
    value: $(body.repository.clone_url)
  - name: git-revision
    value: $(body.head_commit.id)
  - name: image-name
    value: registry.example.com/myapp
  - name: sonar-host
    value: https://sonarqube.example.com
  - name: sonar-project
    value: myapp
---
apiVersion: triggers.tekton.dev/v1beta1
kind: TriggerTemplate
metadata:
  name: secure-pipeline-template
  namespace: default
spec:
  params:
  - name: git-url
    description: Git repository URL
  - name: git-revision
    description: Git revision
  - name: image-name
    description: Container image name
  - name: sonar-host
    description: SonarQube server URL
  - name: sonar-project
    description: SonarQube project key
  resourcetemplates:
  - apiVersion: tekton.dev/v1beta1
    kind: PipelineRun
    metadata:
      generateName: secure-build-deploy-run-
      namespace: default
    spec:
      serviceAccountName: tekton-build-sa
      pipelineRef:
        name: secure-build-deploy
      params:
      - name: git-url
        value: $(tt.params.git-url)
      - name: git-revision
        value: $(tt.params.git-revision)
      - name: image-name
        value: $(tt.params.image-name)
      - name: sonar-host
        value: $(tt.params.sonar-host)
      - name: sonar-project
        value: $(tt.params.sonar-project)
      workspaces:
      - name: shared-data
        volumeClaimTemplate:
          spec:
            accessModes:
            - ReadWriteOnce
            resources:
              requests:
                storage: 2Gi
kubectl apply -f /tmp/git-trigger.yaml

Create GitHub webhook secret

Configure webhook authentication for secure communication between GitHub and Tekton.

kubectl create secret generic github-webhook-secret \
  --from-literal=secretToken=$(openssl rand -hex 20)

Get the webhook secret for GitHub configuration:

kubectl get secret github-webhook-secret -o jsonpath='{.data.secretToken}' | base64 -d

Expose webhook endpoint

Create an ingress or service to make the EventListener accessible from GitHub.

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: tekton-webhook
  namespace: default
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /
    cert-manager.io/cluster-issuer: letsencrypt-prod
spec:
  tls:
  - hosts:
    - tekton-webhooks.example.com
    secretName: tekton-webhook-tls
  rules:
  - host: tekton-webhooks.example.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: el-github-listener
            port:
              number: 8080
kubectl apply -f /tmp/webhook-ingress.yaml

Configure monitoring and alerting

Set up Prometheus monitoring for pipeline metrics and failure alerts.

apiVersion: v1
kind: ServiceMonitor
metadata:
  name: tekton-pipelines
  namespace: tekton-pipelines
  labels:
    app: tekton-pipelines
spec:
  selector:
    matchLabels:
      app.kubernetes.io/name: controller
  endpoints:
  - port: http-metrics
    path: /metrics
---
apiVersion: monitoring.coreos.com/v1
kind: PrometheusRule
metadata:
  name: tekton-pipeline-alerts
  namespace: tekton-pipelines
spec:
  groups:
  - name: tekton.rules
    rules:
    - alert: TektonPipelineFailure
      expr: increase(tekton_pipelinerun_count{status="failed"}[5m]) > 0
      for: 0m
      labels:
        severity: warning
      annotations:
        summary: "Tekton pipeline failure detected"
        description: "Pipeline {{ $labels.pipeline }} has failed in namespace {{ $labels.namespace }}"
    - alert: TektonHighFailureRate
      expr: |
        (
          rate(tekton_pipelinerun_count{status="failed"}[30m]) /
          rate(tekton_pipelinerun_count[30m])
        ) > 0.5
      for: 10m
      labels:
        severity: critical
      annotations:
        summary: "High Tekton pipeline failure rate"
        description: "Pipeline failure rate is {{ $value | humanizePercentage }} over the last 30 minutes"
kubectl apply -f /tmp/tekton-monitoring.yaml

Configure security scanning integration

Set up SonarQube integration

Configure SonarQube authentication and quality gates for automated code analysis.

kubectl create secret generic sonarqube-auth \
  --from-literal=token=your-sonarqube-token

Update the SonarQube scanner task with authentication:

apiVersion: tekton.dev/v1beta1
kind: Task
metadata:
  name: sonarqube-scanner
  namespace: default
spec:
  description: Analyze code quality with SonarQube authentication
  params:
  - name: sonar-host-url
    description: SonarQube server URL
    type: string
  - name: sonar-project-key
    description: Project key in SonarQube
    type: string
  workspaces:
  - name: source
    description: Source code workspace
  steps:
  - name: scan
    image: sonarsource/sonar-scanner-cli:latest
    workingDir: $(workspaces.source.path)
    env:
    - name: SONAR_HOST_URL
      value: $(params.sonar-host-url)
    - name: SONAR_TOKEN
      valueFrom:
        secretKeyRef:
          name: sonarqube-auth
          key: token
    - name: SONAR_SCANNER_OPTS
      value: "-Xmx1024m"
    command:
    - sonar-scanner
    args:
    - -Dsonar.projectKey=$(params.sonar-project-key)
    - -Dsonar.sources=.
    - -Dsonar.qualitygate.wait=true
kubectl apply -f /tmp/sonarqube-auth-patch.yaml

Configure vulnerability scanning policies

Set up Trivy scanning with severity thresholds and policy enforcement. Learn more about container security in our Trivy security scanning guide.

apiVersion: tekton.dev/v1beta1
kind: Task
metadata:
  name: trivy-policy-scanner
  namespace: default
spec:
  description: Scan images and enforce security policies
  params:
  - name: image-url
    description: Image URL to scan
    type: string
  - name: fail-on-severity
    description: Fail pipeline on severity level
    default: "CRITICAL"
    type: string
  - name: max-critical
    description: Maximum critical vulnerabilities allowed
    default: "0"
    type: string
  - name: max-high
    description: Maximum high vulnerabilities allowed
    default: "5"
    type: string
  results:
  - name: scan-result
    description: Scan result summary
  steps:
  - name: scan
    image: aquasec/trivy:latest
    env:
    - name: TRIVY_NO_PROGRESS
      value: 

Automated install script

Run this to automate the entire setup

Don't want to manage this yourself?

We handle infrastructure for businesses that depend on uptime. Fully managed, with one fixed contact who knows your setup.

You get one fixed contact who knows your setup

Rotterdam 01:28 · reachable in a message, no ticket form