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: "true"
- name: TRIVY_CACHE_DIR
value: /tmp/trivy-cache
script: |
#!/bin/sh
set -e
echo "Scanning image $(params.image-url)..."
# Perform scan and save results
trivy image --format json --output /tmp/scan-results.json $(params.image-url)
trivy image --format table $(params.image-url)
# Parse results and enforce policies
critical=$(jq '.Results[].Vulnerabilities[]? | select(.Severity=="CRITICAL") | .VulnerabilityID' /tmp/scan-results.json | wc -l || echo "0")
high=$(jq '.Results[].Vulnerabilities[]? | select(.Severity=="HIGH") | .VulnerabilityID' /tmp/scan-results.json | wc -l || echo "0")
echo "Found $critical CRITICAL and $high HIGH vulnerabilities"
# Check against thresholds
if [ "$critical" -gt "$(params.max-critical)" ]; then
echo "❌ CRITICAL vulnerabilities ($critical) exceed limit ($(params.max-critical))"
exit 1
fi
if [ "$high" -gt "$(params.max-high)" ]; then
echo "❌ HIGH vulnerabilities ($high) exceed limit ($(params.max-high))"
exit 1
fi
echo "✅ Security scan passed policy checks"
echo -n "PASSED: $critical critical, $high high vulnerabilities" > $(results.scan-result.path)
volumeMounts:
- name: trivy-cache
mountPath: /tmp/trivy-cache
volumes:
- name: trivy-cache
emptyDir: {}
kubectl apply -f /tmp/trivy-policy-task.yaml
Production security hardening
Configure network policies
Implement Kubernetes network policies to restrict traffic between pipeline components.
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: tekton-pipelines-netpol
namespace: tekton-pipelines
spec:
podSelector:
matchLabels:
app.kubernetes.io/part-of: tekton-pipelines
policyTypes:
- Ingress
- Egress
ingress:
- from:
- namespaceSelector:
matchLabels:
name: tekton-pipelines
- namespaceSelector:
matchLabels:
name: default
egress:
- to: []
ports:
- protocol: TCP
port: 53
- protocol: UDP
port: 53
- to: []
ports:
- protocol: TCP
port: 443
- protocol: TCP
port: 80
- to:
- namespaceSelector:
matchLabels:
name: tekton-pipelines
---
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: tekton-builds-netpol
namespace: default
spec:
podSelector:
matchLabels:
tekton.dev/pipeline: secure-build-deploy
policyTypes:
- Ingress
- Egress
ingress:
- from:
- namespaceSelector:
matchLabels:
name: tekton-pipelines
egress:
- to: []
ports:
- protocol: TCP
port: 443
- protocol: TCP
port: 80
- protocol: TCP
port: 53
- protocol: UDP
port: 53
kubectl apply -f /tmp/tekton-network-policy.yaml
Configure Pod Security Standards
Enforce Pod Security Standards to prevent privilege escalation and ensure secure container execution.
apiVersion: v1
kind: Namespace
metadata:
name: tekton-secure
labels:
pod-security.kubernetes.io/enforce: restricted
pod-security.kubernetes.io/audit: restricted
pod-security.kubernetes.io/warn: restricted
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: tekton-restricted-sa
namespace: tekton-secure
---
apiVersion: policy/v1beta1
kind: PodSecurityPolicy
metadata:
name: tekton-restricted-psp
spec:
privileged: false
allowPrivilegeEscalation: false
requiredDropCapabilities:
- ALL
volumes:
- 'configMap'
- 'emptyDir'
- 'projected'
- 'secret'
- 'downwardAPI'
- 'persistentVolumeClaim'
runAsUser:
rule: 'MustRunAsNonRoot'
seLinux:
rule: 'RunAsAny'
fsGroup:
rule: 'RunAsAny'
seccompProfile:
type: RuntimeDefault
kubectl apply -f /tmp/tekton-pod-security.yaml
Configure resource limits and quotas
Set resource limits to prevent resource exhaustion and ensure fair resource allocation.
apiVersion: v1
kind: ResourceQuota
metadata:
name: tekton-pipeline-quota
namespace: default
spec:
hard:
requests.cpu: "4"
requests.memory: 8Gi
limits.cpu: "8"
limits.memory: 16Gi
pods: "10"
persistentvolumeclaims: "5"
---
apiVersion: v1
kind: LimitRange
metadata:
name: tekton-pipeline-limits
namespace: default
spec:
limits:
- default:
cpu: 500m
memory: 1Gi
defaultRequest:
cpu: 100m
memory: 256Mi
type: Container
- max:
cpu: "2"
memory: 4Gi
min:
cpu: 50m
memory: 128Mi
type: Container
kubectl apply -f /tmp/tekton-resource-limits.yaml
Verify your setup
Test the complete pipeline installation and security integration:
# Check all Tekton components are running
kubectl get pods -n tekton-pipelines
kubectl get pods -n tekton-pipelines-resolvers
Verify CRDs are installed
kubectl get crd | grep tekton
Test pipeline execution
kubectl create -f - <
Check pipeline execution status:
# Monitor pipeline runs
kubectl get pipelinerun
kubectl describe pipelinerun $(kubectl get pipelinerun -o name | head -1)
View pipeline logs
tkn pipelinerun logs --last -f
Check security scan results
kubectl get taskrun -l tekton.dev/task=trivy-policy-scanner
Access the Tekton Dashboard:
# Forward dashboard port
kubectl port-forward -n tekton-pipelines svc/tekton-dashboard 9097:9097
Open browser to http://localhost:9097
Common issues
| Symptom | Cause | Fix |
|---|---|---|
| Pipeline fails with "unauthorized" error | Insufficient RBAC permissions | Check service account permissions: kubectl describe rolebinding tekton-build-binding |
| Image push fails during build | Invalid registry credentials | Verify secret: kubectl get secret docker-registry-secret -o yaml |
| Security scan task times out | Network policies blocking egress | Add registry access to network policy: kubectl edit networkpolicy tekton-builds-netpol |
| Webhook not receiving events | EventListener service not exposed | Check ingress: kubectl get ingress tekton-webhook and verify GitHub webhook URL |
| SonarQube analysis fails | Missing authentication token | Update secret: kubectl create secret generic sonarqube-auth --from-literal=token=new-token --dry-run=client -o yaml | kubectl apply -f - |
| Pod creation blocked | Pod Security Standards violation | Review security context: kubectl describe pod failing-pod-name |
Next steps
- Monitor your Kubernetes cluster with Prometheus for comprehensive pipeline observability
- Set up Istio service mesh for advanced traffic management and security
- Implement Pod Security Standards for enhanced container security
- Configure Tekton multi-cluster deployments for cross-environment automation
- Integrate External Secrets Operator for secure credential management
Running this in production?
Automated install script
Run this to automate the entire setup
#!/usr/bin/env bash
set -euo pipefail
# Tekton Pipelines 0.62 Installation Script with Security Scanning
# Usage: ./install-tekton.sh [docker-registry-url] [docker-username] [docker-password] [docker-email]
# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m'
# Configuration
TEKTON_VERSION="v0.62.0"
TRIGGERS_VERSION="v0.27.0"
DASHBOARD_VERSION="v0.43.0"
DOCKER_REGISTRY="${1:-registry.example.com}"
DOCKER_USERNAME="${2:-your-username}"
DOCKER_PASSWORD="${3:-your-password}"
DOCKER_EMAIL="${4:-your-email@example.com}"
# Cleanup function
cleanup() {
echo -e "${RED}[ERROR] Installation failed. Cleaning up...${NC}"
kubectl delete namespace tekton-pipelines --ignore-not-found=true || true
kubectl delete namespace tekton-pipelines-resolvers --ignore-not-found=true || true
exit 1
}
# Set error trap
trap cleanup ERR
# Usage message
if [[ "${1:-}" == "-h" || "${1:-}" == "--help" ]]; then
echo "Usage: $0 [docker-registry-url] [docker-username] [docker-password] [docker-email]"
echo "Example: $0 registry.example.com myuser mypass user@example.com"
exit 0
fi
# Detect distribution
if [ -f /etc/os-release ]; then
. /etc/os-release
case "$ID" in
ubuntu|debian) PKG_MGR="apt"; PKG_INSTALL="apt install -y"; PKG_UPDATE="apt update" ;;
almalinux|rocky|centos|rhel|ol|fedora) PKG_MGR="dnf"; PKG_INSTALL="dnf install -y"; PKG_UPDATE="dnf check-update || true" ;;
amzn) PKG_MGR="yum"; PKG_INSTALL="yum install -y"; PKG_UPDATE="yum check-update || true" ;;
*) echo -e "${RED}Unsupported distro: $ID${NC}"; exit 1 ;;
esac
else
echo -e "${RED}Cannot detect OS distribution${NC}"
exit 1
fi
echo -e "${GREEN}Starting Tekton Pipelines 0.62 installation...${NC}"
# Check prerequisites
echo -e "${YELLOW}[1/10] Checking prerequisites...${NC}"
if [[ $EUID -eq 0 ]]; then
echo -e "${YELLOW}Warning: Running as root${NC}"
fi
# Update package manager
$PKG_UPDATE
# Install required tools
if ! command -v kubectl &> /dev/null; then
echo "Installing kubectl..."
if [[ "$PKG_MGR" == "apt" ]]; then
$PKG_INSTALL curl apt-transport-https ca-certificates
curl -fsSL https://pkgs.k8s.io/core:/stable:/v1.29/deb/Release.key | gpg --dearmor -o /etc/apt/keyrings/kubernetes-apt-keyring.gpg
chmod 644 /etc/apt/keyrings/kubernetes-apt-keyring.gpg
echo 'deb [signed-by=/etc/apt/keyrings/kubernetes-apt-keyring.gpg] https://pkgs.k8s.io/core:/stable:/v1.29/deb/ /' > /etc/apt/sources.list.d/kubernetes.list
chmod 644 /etc/apt/sources.list.d/kubernetes.list
apt update
$PKG_INSTALL kubectl
else
cat > /etc/yum.repos.d/kubernetes.repo <<EOF
[kubernetes]
name=Kubernetes
baseurl=https://pkgs.k8s.io/core:/stable:/v1.29/rpm/
enabled=1
gpgcheck=1
gpgkey=https://pkgs.k8s.io/core:/stable:/v1.29/rpm/repodata/repomd.xml.key
EOF
chmod 644 /etc/yum.repos.d/kubernetes.repo
$PKG_INSTALL kubectl
fi
fi
# Verify kubectl access
if ! kubectl cluster-info &> /dev/null; then
echo -e "${RED}kubectl is not configured or cluster is not accessible${NC}"
exit 1
fi
# Check Kubernetes version
K8S_VERSION=$(kubectl version --short --client=false -o json | grep -o '"gitVersion":"v[0-9]*\.[0-9]*' | cut -d'"' -f4 | cut -d'v' -f2)
MIN_VERSION="1.24"
if ! printf '%s\n%s\n' "$MIN_VERSION" "$K8S_VERSION" | sort -V -C; then
echo -e "${RED}Kubernetes version $K8S_VERSION is below required $MIN_VERSION${NC}"
exit 1
fi
# Install Tekton Pipelines core
echo -e "${YELLOW}[2/10] Installing Tekton Pipelines core components...${NC}"
kubectl apply --filename "https://storage.googleapis.com/tekton-releases/pipeline/previous/${TEKTON_VERSION}/release.yaml"
# Wait for core components
echo -e "${YELLOW}[3/10] Waiting for core components to be ready...${NC}"
kubectl wait --for=condition=ready pod -l app.kubernetes.io/part-of=tekton-pipelines -n tekton-pipelines --timeout=300s
# Verify core installation
kubectl get pods --namespace tekton-pipelines
kubectl get crd | grep tekton
# Install Tekton Triggers
echo -e "${YELLOW}[4/10] Installing Tekton Triggers...${NC}"
kubectl apply --filename "https://storage.googleapis.com/tekton-releases/triggers/previous/${TRIGGERS_VERSION}/release.yaml"
kubectl apply --filename "https://storage.googleapis.com/tekton-releases/triggers/previous/${TRIGGERS_VERSION}/interceptors.yaml"
# Wait for triggers
echo -e "${YELLOW}[5/10] Waiting for trigger components...${NC}"
sleep 30
kubectl wait --for=condition=ready pod -l app.kubernetes.io/part-of=tekton-triggers -n tekton-pipelines --timeout=300s
kubectl get pods --namespace tekton-pipelines-resolvers || true
# Install Tekton Dashboard
echo -e "${YELLOW}[6/10] Installing Tekton Dashboard...${NC}"
kubectl apply --filename "https://storage.googleapis.com/tekton-releases/dashboard/previous/${DASHBOARD_VERSION}/release.yaml"
# Create dashboard service
cat > /tmp/tekton-dashboard-service.yaml <<EOF
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
EOF
chmod 644 /tmp/tekton-dashboard-service.yaml
kubectl apply -f /tmp/tekton-dashboard-service.yaml
# Configure RBAC
echo -e "${YELLOW}[7/10] Configuring RBAC...${NC}"
cat > /tmp/tekton-rbac.yaml <<EOF
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
EOF
chmod 644 /tmp/tekton-rbac.yaml
kubectl apply -f /tmp/tekton-rbac.yaml
# Create Docker registry secret
echo -e "${YELLOW}[8/10] Creating Docker registry secret...${NC}"
kubectl create secret docker-registry docker-registry-secret \
--docker-server="$DOCKER_REGISTRY" \
--docker-username="$DOCKER_USERNAME" \
--docker-password="$DOCKER_PASSWORD" \
--docker-email="$DOCKER_EMAIL" || true
kubectl patch serviceaccount tekton-build-sa -p '{"secrets":[{"name":"docker-registry-secret"}]}'
# Install security scanning tasks
echo -e "${YELLOW}[9/10] Installing security scanning tasks...${NC}"
cat > /tmp/trivy-task.yaml <<EOF
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
steps:
- name: trivy-scan
image: aquasec/trivy:latest
script: |
trivy image --exit-code 0 --severity HIGH,CRITICAL \$(params.image-url)
EOF
chmod 644 /tmp/trivy-task.yaml
kubectl apply -f /tmp/trivy-task.yaml
# Final verification
echo -e "${YELLOW}[10/10] Performing final verification...${NC}"
sleep 20
# Check all components are running
kubectl get pods -n tekton-pipelines
kubectl get pods -n tekton-pipelines-resolvers || true
# Verify CRDs
kubectl get crd | grep tekton
# Check service account
kubectl get serviceaccount tekton-build-sa -n default
# Clean up temporary files
rm -f /tmp/tekton-dashboard-service.yaml /tmp/tekton-rbac.yaml /tmp/trivy-task.yaml
echo -e "${GREEN}✅ Tekton Pipelines 0.62 installation completed successfully!${NC}"
echo -e "${GREEN}Dashboard available at: http://NODE_IP:32000${NC}"
echo -e "${GREEN}Service account 'tekton-build-sa' created with proper RBAC${NC}"
echo -e "${GREEN}Security scanning task 'trivy-scanner' installed${NC}"
Review the script before running. Execute with: bash install.sh