What is Tekton?
Tekton is a powerful, cloud-native, open-source framework for creating CI/CD systems. As a Kubernetes-native solution, Tekton enables you to build, test, and deploy across cloud providers and on-premises systems by abstracting away the underlying details. Born as an open-source project under the umbrella of the Continuous Delivery Foundation (CDF), Tekton has evolved into one of the most robust and flexible CI/CD platforms available in 2025.
Tekton leverages Kubernetes Custom Resource Definitions (CRDs) to define CI/CD pipeline components as code, providing a declarative approach to DevOps automation. It brings enterprise-grade features like security, compliance, observability, and multi-cloud portability to your CI/CD workflows, making it the preferred choice for organizations adopting cloud-native methodologies.
Why Choose Tekton in 2025?
Cloud-Native Architecture : Built from the ground up for Kubernetes environments
Vendor Neutral : Works across all major cloud providers (AWS, Azure, GCP) and on-premises
Supply Chain Security : Built-in support for SLSA compliance and software supply chain security
GitOps Ready : Seamless integration with GitOps workflows and ArgoCD
Enterprise Grade : Battle-tested in production by organizations like Google, IBM, Red Hat, and VMware
Key Features and Concepts (2025)
Core Components
1. Tasks
The fundamental building blocks of a Tekton pipeline are tasks. Each task represents a specific unit of work, such as building code, running tests, or deploying an application. Tasks can be combined and reused across pipelines, promoting modularity and code sharing.
2. Pipelines
Pipelines provide a way to orchestrate tasks in a specific order to create an end-to-end CI/CD workflow. With Tekton, you can define complex pipelines that include multiple stages, parallel execution, and conditional branching.
3. PipelineRuns and TaskRuns
These are the runtime instances of Pipelines and Tasks. They represent the actual execution of your defined workflows with specific parameters and workspaces.
4. Workspaces
Workspaces allow you to share files between tasks within a pipeline. They provide a mechanism for passing data and artifacts between different stages of the CI/CD workflow. Workspaces ensure isolation and reproducibility, making it easier to manage complex pipelines.
5. Parameters and Results
Parameters enable dynamic configuration of tasks and pipelines at runtime, while Results allow tasks to output data that can be consumed by subsequent tasks.
New 2025 Features
Supply Chain Security (SLSA Compliance)
Built-in support for generating SLSA provenance
Signed task and pipeline execution attestations
Integration with Sigstore for keyless signing
Enhanced Security Model
Pod Security Standards enforcement
Service mesh integration (Istio, Linkerd)
RBAC templates for common use cases
Performance Improvements
Faster pipeline startup times (50% improvement over 2024)
Optimized resource scheduling
Better memory management for large pipelines
GitOps Integration
Native ArgoCD integration
Automated pipeline synchronization
Git-based pipeline definitions with auto-discovery
A task can consist of multiple steps, and pipeline may consist of multiple tasks. The tasks may run in parallel or in sequence
Real-World Examples (2025)
Example 1: AWS EKS CI/CD Pipeline with SLSA Compliance
This example demonstrates a complete CI/CD pipeline for deploying to AWS EKS with supply chain security features.
Copy # aws-pipeline.yaml
apiVersion: tekton.dev/v1beta1
kind: Pipeline
metadata:
name: aws-eks-pipeline
annotations:
tekton.dev/description: "Complete CI/CD pipeline for AWS EKS with SLSA compliance"
spec:
params:
- name: git-url
description: Git repository URL
type: string
- name: git-revision
description: Git revision
type: string
default: main
- name: image-tag
description: Image tag to build
type: string
- name: aws-region
description: AWS region
type: string
default: us-west-2
- name: eks-cluster-name
description: EKS cluster name
type: string
workspaces:
- name: shared-data
- name: aws-credentials
- name: signing-secrets
tasks:
- name: git-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-data
- name: security-scan
taskRef:
name: trivy-scanner
runAfter:
- git-clone
params:
- name: ARGS
value: ["fs", "--security-checks", "vuln,secret,config"]
workspaces:
- name: manifest-dir
workspace: shared-data
- name: build-and-push
taskRef:
name: buildah
kind: ClusterTask
runAfter:
- security-scan
params:
- name: IMAGE
value: "$(params.image-tag)"
- name: DOCKERFILE
value: "./Dockerfile"
workspaces:
- name: source
workspace: shared-data
- name: sign-image
taskRef:
name: cosign-sign
runAfter:
- build-and-push
params:
- name: image
value: "$(params.image-tag)"
workspaces:
- name: source
workspace: shared-data
- name: cosign-keys
workspace: signing-secrets
- name: generate-slsa-provenance
taskRef:
name: slsa-provenance
runAfter:
- sign-image
params:
- name: image
value: "$(params.image-tag)"
- name: git-url
value: "$(params.git-url)"
- name: git-revision
value: "$(params.git-revision)"
workspaces:
- name: source
workspace: shared-data
- name: deploy-to-eks
taskRef:
name: aws-eks-deploy
runAfter:
- generate-slsa-provenance
params:
- name: cluster-name
value: "$(params.eks-cluster-name)"
- name: region
value: "$(params.aws-region)"
- name: image
value: "$(params.image-tag)"
workspaces:
- name: source
workspace: shared-data
- name: aws-credentials
workspace: aws-credentials
Example 2: Azure AKS Multi-Environment Pipeline
This pipeline demonstrates deploying to multiple Azure environments with approval gates.
Copy # azure-pipeline.yaml
apiVersion: tekton.dev/v1beta1
kind: Pipeline
metadata:
name: azure-aks-multienv
annotations:
tekton.dev/description: "Multi-environment deployment to Azure AKS"
spec:
params:
- name: git-url
type: string
- name: git-revision
type: string
default: main
- name: app-name
type: string
- name: registry-url
type: string
- name: dev-cluster
type: string
- name: prod-cluster
type: string
- name: resource-group
type: string
workspaces:
- name: shared-workspace
- name: azure-credentials
tasks:
- name: fetch-source
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: run-tests
taskRef:
name: golang-test
kind: ClusterTask
runAfter:
- fetch-source
params:
- name: package
value: "./..."
- name: flags
value: "-v -race -coverprofile=coverage.out"
workspaces:
- name: source
workspace: shared-workspace
- name: build-image
taskRef:
name: kaniko
kind: ClusterTask
runAfter:
- run-tests
params:
- name: IMAGE
value: "$(params.registry-url)/$(params.app-name):$(params.git-revision)"
- name: DOCKERFILE
value: "./Dockerfile"
workspaces:
- name: source
workspace: shared-workspace
- name: dockerconfig
workspace: azure-credentials
- name: deploy-to-dev
taskRef:
name: azure-aks-deploy
runAfter:
- build-image
params:
- name: cluster-name
value: "$(params.dev-cluster)"
- name: resource-group
value: "$(params.resource-group)"
- name: image
value: "$(params.registry-url)/$(params.app-name):$(params.git-revision)"
- name: environment
value: "development"
workspaces:
- name: source
workspace: shared-workspace
- name: azure-credentials
workspace: azure-credentials
- name: integration-tests
taskRef:
name: integration-test
runAfter:
- deploy-to-dev
params:
- name: test-endpoint
value: "https://$(params.app-name)-dev.azurewebsites.net"
workspaces:
- name: source
workspace: shared-workspace
- name: manual-approval
taskRef:
name: manual-approval-task
runAfter:
- integration-tests
params:
- name: message
value: "Approve deployment to production?"
- name: timeout
value: "3600" # 1 hour timeout
- name: deploy-to-prod
taskRef:
name: azure-aks-deploy
runAfter:
- manual-approval
params:
- name: cluster-name
value: "$(params.prod-cluster)"
- name: resource-group
value: "$(params.resource-group)"
- name: image
value: "$(params.registry-url)/$(params.app-name):$(params.git-revision)"
- name: environment
value: "production"
workspaces:
- name: source
workspace: shared-workspace
- name: azure-credentials
workspace: azure-credentials
Example 3: GCP Cloud Run Serverless Pipeline
This example shows a serverless deployment pipeline for Google Cloud Run with automated scaling.
Copy # gcp-pipeline.yaml
apiVersion: tekton.dev/v1beta1
kind: Pipeline
metadata:
name: gcp-cloudrun-pipeline
annotations:
tekton.dev/description: "Serverless deployment to Google Cloud Run"
spec:
params:
- name: git-url
type: string
- name: git-revision
type: string
default: main
- name: service-name
type: string
- name: project-id
type: string
- name: region
type: string
default: us-central1
- name: max-instances
type: string
default: "100"
workspaces:
- name: source-workspace
- name: gcp-credentials
tasks:
- name: clone-repo
taskRef:
name: git-clone
kind: ClusterTask
params:
- name: url
value: $(params.git-url)
- name: revision
value: $(params.git-revision)
workspaces:
- name: output
workspace: source-workspace
- name: lint-code
taskRef:
name: eslint
runAfter:
- clone-repo
params:
- name: args
value: ["src/", "--ext", ".js,.ts"]
workspaces:
- name: source
workspace: source-workspace
- name: unit-tests
taskRef:
name: npm
kind: ClusterTask
runAfter:
- lint-code
params:
- name: ARGS
value: ["test"]
workspaces:
- name: source
workspace: source-workspace
- name: build-container
taskRef:
name: gcp-cloud-build
runAfter:
- unit-tests
params:
- name: project-id
value: "$(params.project-id)"
- name: image-name
value: "gcr.io/$(params.project-id)/$(params.service-name):$(params.git-revision)"
- name: dockerfile
value: "Dockerfile"
workspaces:
- name: source
workspace: source-workspace
- name: credentials
workspace: gcp-credentials
- name: security-scan-image
taskRef:
name: gcp-container-analysis
runAfter:
- build-container
params:
- name: project-id
value: "$(params.project-id)"
- name: image-url
value: "gcr.io/$(params.project-id)/$(params.service-name):$(params.git-revision)"
workspaces:
- name: credentials
workspace: gcp-credentials
- name: deploy-cloud-run
taskRef:
name: gcp-cloud-run-deploy
runAfter:
- security-scan-image
params:
- name: service-name
value: "$(params.service-name)"
- name: project-id
value: "$(params.project-id)"
- name: region
value: "$(params.region)"
- name: image
value: "gcr.io/$(params.project-id)/$(params.service-name):$(params.git-revision)"
- name: max-instances
value: "$(params.max-instances)"
- name: cpu-limit
value: "1000m"
- name: memory-limit
value: "512Mi"
workspaces:
- name: source
workspace: source-workspace
- name: credentials
workspace: gcp-credentials
- name: smoke-tests
taskRef:
name: curl-test
runAfter:
- deploy-cloud-run
params:
- name: url
value: "$(tasks.deploy-cloud-run.results.service-url)/health"
- name: expected-status
value: "200"
---
# Custom Task for GCP Cloud Run Deployment
apiVersion: tekton.dev/v1beta1
kind: Task
metadata:
name: gcp-cloud-run-deploy
spec:
params:
- name: service-name
type: string
- name: project-id
type: string
- name: region
type: string
- name: image
type: string
- name: max-instances
type: string
default: "100"
- name: cpu-limit
type: string
default: "1000m"
- name: memory-limit
type: string
default: "512Mi"
workspaces:
- name: source
- name: credentials
results:
- name: service-url
description: The URL of the deployed Cloud Run service
steps:
- name: authenticate
image: gcr.io/google.com/cloudsdktool/cloud-sdk:latest
script: |
#!/bin/bash
gcloud auth activate-service-account --key-file=$(workspaces.credentials.path)/key.json
gcloud config set project $(params.project-id)
- name: deploy
image: gcr.io/google.com/cloudsdktool/cloud-sdk:latest
script: |
#!/bin/bash
set -e
gcloud run deploy $(params.service-name) \
--image=$(params.image) \
--region=$(params.region) \
--platform=managed \
--allow-unauthenticated \
--max-instances=$(params.max-instances) \
--cpu=$(params.cpu-limit) \
--memory=$(params.memory-limit) \
--port=8080 \
--set-env-vars="ENVIRONMENT=production" \
--format="value(status.url)" > /tmp/service-url
# Output the service URL
echo -n "$(cat /tmp/service-url)" | tee $(results.service-url.path)
Example 4: Multi-Cloud GitOps Pipeline
This advanced example demonstrates a GitOps pipeline that can deploy to multiple cloud providers.
Copy # multi-cloud-gitops.yaml
apiVersion: tekton.dev/v1beta1
kind: Pipeline
metadata:
name: multi-cloud-gitops
annotations:
tekton.dev/description: "GitOps pipeline for multi-cloud deployment"
spec:
params:
- name: app-git-url
type: string
- name: config-git-url
type: string
- name: git-revision
type: string
default: main
- name: target-clouds
type: array
description: "Array of target clouds: aws, azure, gcp"
- name: registry-url
type: string
workspaces:
- name: app-source
- name: config-source
- name: cloud-credentials
tasks:
- name: fetch-app-source
taskRef:
name: git-clone
kind: ClusterTask
params:
- name: url
value: $(params.app-git-url)
- name: revision
value: $(params.git-revision)
workspaces:
- name: output
workspace: app-source
- name: fetch-config-source
taskRef:
name: git-clone
kind: ClusterTask
params:
- name: url
value: $(params.config-git-url)
- name: revision
value: main
workspaces:
- name: output
workspace: config-source
- name: build-universal-image
taskRef:
name: buildah
kind: ClusterTask
runAfter:
- fetch-app-source
params:
- name: IMAGE
value: "$(params.registry-url)/multi-cloud-app:$(params.git-revision)"
- name: DOCKERFILE
value: "./Dockerfile"
workspaces:
- name: source
workspace: app-source
- name: update-manifests
taskRef:
name: yq-replace
runAfter:
- build-universal-image
- fetch-config-source
params:
- name: files
value: ["./aws/deployment.yaml", "./azure/deployment.yaml", "./gcp/deployment.yaml"]
- name: expression
value: ".spec.template.spec.containers[0].image"
- name: value
value: "$(params.registry-url)/multi-cloud-app:$(params.git-revision)"
workspaces:
- name: source
workspace: config-source
- name: deploy-to-clouds
taskRef:
name: multi-cloud-deploy
runAfter:
- update-manifests
params:
- name: target-clouds
value: $(params.target-clouds)
workspaces:
- name: config-source
workspace: config-source
- name: credentials
workspace: cloud-credentials
- name: commit-changes
taskRef:
name: git-commit-push
runAfter:
- deploy-to-clouds
params:
- name: message
value: "Update image to $(params.git-revision)"
- name: git-url
value: $(params.config-git-url)
workspaces:
- name: source
workspace: config-source
Pipeline Triggers and EventListeners (2025)
Modern webhook configuration for GitLab, GitHub, and Azure DevOps:
Copy # modern-triggers.yaml
apiVersion: triggers.tekton.dev/v1beta1
kind: EventListener
metadata:
name: modern-webhook-listener
spec:
serviceAccountName: tekton-triggers-sa
triggers:
- name: github-push
interceptors:
- ref:
name: "github"
params:
- name: "secretRef"
value:
secretName: github-secret
secretKey: token
- name: "eventTypes"
value: ["push", "pull_request"]
- ref:
name: "cel"
params:
- name: "filter"
value: "body.ref.startsWith('refs/heads/main') || body.action == 'opened'"
bindings:
- ref: github-binding
template:
ref: aws-eks-pipeline-template
- name: gitlab-webhook
interceptors:
- ref:
name: "gitlab"
params:
- name: "secretRef"
value:
secretName: gitlab-secret
secretKey: token
- name: "eventTypes"
value: ["Push Hook", "Merge Request Hook"]
bindings:
- ref: gitlab-binding
template:
ref: azure-aks-pipeline-template
---
apiVersion: triggers.tekton.dev/v1beta1
kind: TriggerBinding
metadata:
name: github-binding
spec:
params:
- name: git-url
value: $(body.repository.clone_url)
- name: git-revision
value: $(body.after)
- name: repository-name
value: $(body.repository.name)
---
apiVersion: triggers.tekton.dev/v1beta1
kind: TriggerTemplate
metadata:
name: aws-eks-pipeline-template
spec:
params:
- name: git-url
- name: git-revision
- name: repository-name
resourcetemplates:
- apiVersion: tekton.dev/v1beta1
kind: PipelineRun
metadata:
generateName: aws-pipeline-run-
labels:
tekton.dev/pipeline: aws-eks-pipeline
spec:
pipelineRef:
name: aws-eks-pipeline
params:
- name: git-url
value: $(tt.params.git-url)
- name: git-revision
value: $(tt.params.git-revision)
- name: image-tag
value: "your-registry.com/$(tt.params.repository-name):$(tt.params.git-revision)"
- name: eks-cluster-name
value: "production-cluster"
workspaces:
- name: shared-data
volumeClaimTemplate:
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 5Gi
- name: aws-credentials
secret:
secretName: aws-credentials
- name: signing-secrets
secret:
secretName: cosign-keys
These examples showcase:
SLSA Compliance : Supply chain security with image signing and provenance generation
Multi-Environment Deployments : Proper staging with approval gates
Serverless Deployments : Cloud Run with auto-scaling configuration
GitOps Integration : Configuration management with automated updates
Modern Webhooks : Advanced event filtering and processing
Security Scanning : Container vulnerability assessments
Multi-Cloud Support : Unified pipelines across cloud providers
Installation Guide (2025)
Prerequisites
Kubernetes cluster 1.28+ (recommended: 1.29 or later)
kubectl configured to access your cluster
Cluster-admin permissions
At least 2GB of available memory and 2 CPU cores
Installing Tekton Pipelines (v0.55.0+)
To install Tekton Pipelines on a Kubernetes cluster:
Install the latest stable release:
Copy # Install Tekton Pipelines
kubectl apply --filename https://storage.googleapis.com/tekton-releases/pipeline/latest/release.yaml
# Verify installation
kubectl get pods --namespace tekton-pipelines
For specific versions or alternative installations:
Copy # Install specific version (example: v0.55.0)
kubectl apply --filename https://storage.googleapis.com/tekton-releases/pipeline/previous/v0.55.0/release.yaml
# Install nightly build (for testing latest features)
kubectl apply --filename https://storage.googleapis.com/tekton-releases-nightly/pipeline/latest/release.yaml
# For environments without image digest support
kubectl apply --filename https://storage.googleapis.com/tekton-releases/pipeline/latest/release.notags.yaml
Monitor the installation:
Copy kubectl get pods --namespace tekton-pipelines --watch
When all components show 1/1
under the READY
column, the installation is complete.
Installing Tekton Triggers (v0.26.0+)
Install Tekton Triggers for webhook and event-driven pipelines:
Copy # Install Triggers
kubectl apply --filename https://storage.googleapis.com/tekton-releases/triggers/latest/release.yaml
# Install Interceptors
kubectl apply --filename https://storage.googleapis.com/tekton-releases/triggers/latest/interceptors.yaml
# Verify installation
kubectl get pods --namespace tekton-pipelines
Installing Tekton Dashboard (v0.40.0+)
Install the web-based dashboard:
Copy # Install Dashboard
kubectl apply --filename https://storage.googleapis.com/tekton-releases/dashboard/latest/release.yaml
# Access the dashboard (port-forward)
kubectl port-forward -n tekton-pipelines svc/tekton-dashboard 9097:9097
Installing Tekton CLI (tkn) v0.35.0+
Copy # Linux (x86_64)
curl -LO https://github.com/tektoncd/cli/releases/latest/download/tkn_Linux_x86_64.tar.gz
sudo tar xvzf tkn_Linux_x86_64.tar.gz -C /usr/local/bin/ tkn
# macOS (Intel)
brew install tektoncd-cli
# macOS (ARM64)
curl -LO https://github.com/tektoncd/cli/releases/latest/download/tkn_Darwin_arm64.tar.gz
sudo tar xvzf tkn_Darwin_arm64.tar.gz -C /usr/local/bin/ tkn
# Windows (PowerShell)
choco install tektoncd-cli
# Verify installation
tkn version
Installation on Different Operating Systems
Linux Installation
Copy # Prerequisites
sudo apt update
sudo apt install -y curl kubectl
# Install kubectl if not present
curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl"
sudo install -o root -g root -m 0755 kubectl /usr/local/bin/kubectl
# Install Tekton CLI
curl -LO https://github.com/tektoncd/cli/releases/latest/download/tkn_Linux_x86_64.tar.gz
sudo tar xvzf tkn_Linux_x86_64.tar.gz -C /usr/local/bin/ tkn
WSL (Windows Subsystem for Linux) Installation
Copy # Update WSL package list
sudo apt update
# Install dependencies
sudo apt install -y curl wget
# Install kubectl
curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl"
sudo install -o root -g root -m 0755 kubectl /usr/local/bin/kubectl
# Install Tekton CLI
curl -LO https://github.com/tektoncd/cli/releases/latest/download/tkn_Linux_x86_64.tar.gz
sudo tar xvzf tkn_Linux_x86_64.tar.gz -C /usr/local/bin/ tkn
# Verify installations
kubectl version --client
tkn version
NixOS Installation
Copy # Configuration.nix approach
{ config, pkgs, ... }:
{
environment.systemPackages = with pkgs; [
kubectl
tektoncd-cli
# Additional tools for Tekton development
yq-go
jq
git
docker
];
# Enable Docker for building containers
virtualisation.docker.enable = true;
# Add user to docker group
users.users.yourusername.extraGroups = [ "docker" ];
}
# Using nix-shell for development
nix-shell -p kubectl tektoncd-cli yq-go jq git docker
# Using Home Manager (home.nix)
{ config, pkgs, ... }:
{
home.packages = with pkgs; [
kubectl
tektoncd-cli
yq-go
jq
];
programs.git.enable = true;
}
Best Practices for Tekton in 2025
Security First
Always use signed images and SLSA provenance
Implement proper RBAC and security contexts
Regularly scan for vulnerabilities
Resource Management
Use resource quotas and limits
Implement proper workspace management
Monitor pipeline performance
GitOps Integration
Store pipeline definitions in Git
Use automated synchronization
Implement proper branching strategies
Observability
Enable comprehensive logging
Implement monitoring and alerting
Getting Started with Your First Pipeline
Copy # Create a new namespace
kubectl create namespace tekton-getting-started
# Create a simple task
cat <<EOF | kubectl apply -f -
apiVersion: tekton.dev/v1beta1
kind: Task
metadata:
name: hello-world
namespace: tekton-getting-started
spec:
steps:
- name: echo
image: alpine
script: |
#!/bin/sh
echo "Hello World from Tekton!"
echo "Current date: \$(date)"
echo "Environment: \$(env | sort)"
EOF
# Run the task
cat <<EOF | kubectl apply -f -
apiVersion: tekton.dev/v1beta1
kind: TaskRun
metadata:
name: hello-world-run
namespace: tekton-getting-started
spec:
taskRef:
name: hello-world
EOF
# Check the results
tkn taskrun logs hello-world-run -n tekton-getting-started
DevOps Joke : Why did the developer choose Tekton over other CI/CD tools? Because they wanted their pipelines to be as declarative as their love for Kubernetes - and just like their relationship status, everything had to be defined in YAML! 😄
At least with Tekton, when your pipeline fails, you can blame it on the cluster and not your code... most of the time!
Last updated 11 hours ago