Tekton is a Kubernetes native framework for building CI CD. It defines pipelines as Tasks and PipelineRuns that execute in your cluster. The Pipelines with Tekton plugin brings those runs into Backstage so you can see what shipped, when it ran, and how it went. In the CI CD tab you get a list of PipelineRuns with status, task state, start time, and duration. Open a run to see the task graph and step details. You can read logs without leaving Backstage.
The plugin helps teams keep an eye on build and release health across services. It can show a summary of image vulnerabilities when your pipeline emits scan results. It can surface a link to an SBOM produced by a task. It can render reports from Enterprise Contract or Advanced Cluster Security when those are exposed in logs. PipelineRun results that do not fit those views still appear in a simple output panel. This makes Backstage a single place to review what a service built and whether it meets your checks.
Installation Instructions
These instructions apply to self-hosted Backstage only.
Install the frontend plugin
-
Add the plugin to the app workspace
yarn workspace app add @backstage-community/plugin-tekton
-
Show PipelineRuns in the entity CI CD tab
Edit the Entity page in your app
// packages/app/src/components/catalog/EntityPage.tsx import React from 'react'; import { EntitySwitch } from '@backstage/core-components'; import { isTektonCIAvailable, TektonCI, } from '@backstage-community/plugin-tekton'; const cicdContent = ( <EntitySwitch> {/* other cases */} <EntitySwitch.Case if={isTektonCIAvailable}> <TektonCI /> </EntitySwitch.Case> </EntitySwitch> ); // make sure cicdContent is rendered under the entity CI CD tab in your page layout
Install and configure the Kubernetes backend
The Tekton UI reads data through the Kubernetes backend plugin. Install it and set up access to your clusters.
New backend system
-
Add the backend plugin
yarn workspace backend add @backstage/plugin-kubernetes-backend
-
Register the backend plugin
// packages/backend/src/index.ts import { createBackend } from '@backstage/backend-defaults'; const backend = createBackend(); // other backend plugins backend.add(import('@backstage/plugin-kubernetes-backend')); backend.start();
Legacy backend system
-
Add the backend plugin
yarn workspace backend add @backstage/plugin-kubernetes-backend
-
Create the router module
// packages/backend/src/plugins/kubernetes.ts import { Router } from 'express'; import { createRouter } from '@backstage/plugin-kubernetes-backend'; import type { PluginEnvironment } from '../types'; export default async function createPlugin( env: PluginEnvironment, ): Promise<Router> { return await createRouter({ logger: env.logger, config: env.config, discovery: env.discovery, tokenManager: env.tokenManager, catalogApi: env.catalogClient, permissions: env.permissions, }); }
-
Mount the router
// packages/backend/src/index.ts import { Router } from 'express'; import kubernetes from './plugins/kubernetes'; // create env the same way as in your app const apiRouter = Router(); // other routers apiRouter.use('/kubernetes', await kubernetes(env)); // expose under /api app.use('/api', apiRouter);
Configure app config for Tekton resources
Add Tekton custom resources so the Kubernetes plugin can query them.
# app-config.yaml
kubernetes:
# your cluster configuration goes here
customResources:
- group: 'tekton.dev'
apiVersion: 'v1'
plural: 'pipelineruns'
- group: 'tekton.dev'
apiVersion: 'v1'
plural: 'taskruns'
Grant cluster access
Backstage needs read access to Tekton resources and pod logs. Bind these rules to the service account used by your Backstage backend.
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: backstage-read-only
rules:
- apiGroups:
- ""
resources:
- pods/log
verbs:
- get
- list
- watch
- apiGroups:
- tekton.dev
resources:
- pipelineruns
- taskruns
verbs:
- get
- list
Bind this role to the service account that the backend uses.
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: backstage-read-only-binding
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: backstage-read-only
subjects:
- kind: ServiceAccount
name: <service-account-name>
namespace: <service-account-namespace>
Annotate entities in the catalog
Add annotations to each entity that should show Tekton data.
Enable Tekton features on the entity
# catalog-info.yaml for the entity
metadata:
name: <BACKSTAGE_ENTITY_NAME>
annotations:
tekton.dev/cicd: "true"
Link the entity to Kubernetes resources by id
metadata:
annotations:
backstage.io/kubernetes-id: <BACKSTAGE_ENTITY_NAME>
Optionally fix the namespace
metadata:
annotations:
backstage.io/kubernetes-namespace: <RESOURCE_NS>
Optionally use a label selector on the cluster side
metadata:
annotations:
backstage.io/kubernetes-label-selector: 'app=my-app,component=front-end'
Label your Kubernetes resources with the same id
metadata:
labels:
backstage.io/kubernetes-id: <BACKSTAGE_ENTITY_NAME>
When you use a label selector the labels must exist on the resources.
Set permissions when using the permissions framework
Grant these permission names to the user or group that will view Tekton data
kubernetes.clusters.read
kubernetes.resources.read
What you should see in the UI
- Open a component in the catalog, then go to the CI CD tab
- You will see a list of PipelineRuns with name, status, task status, started, and duration
- Expand a row to see the graph for that PipelineRun
Optional UI actions and results
Enable the Vulnerabilities column. Your pipelines must write a result in the PipelineRun that ends with SCAN_OUTPUT. The value is JSON with counts.
# part of a PipelineRun status
status:
results:
- name: 'MY_SCAN_OUTPUT'
value: >
{"vulnerabilities":{"critical":0,"high":9,"medium":2,"low":13,"unknown":0},
"unpatched_vulnerabilities":{"critical":0,"high":1,"medium":0,"low":1}}
Enable the SBOM action. Add these annotations on the SBOM task and write a LINK_TO_SBOM result.
apiVersion: tekton.dev/v1
kind: Task
metadata:
name: export-sbom-task
annotations:
task.output.location: results
task.results.format: application/text
task.results.type: external-link
task.results.key: LINK_TO_SBOM
Write the result in the task
echo 'https://sbom-viewer.example.test/item/123' | tee $(results.LINK_TO_SBOM.path)
Enable the Output action for reports written to pod logs. Add annotations on tasks that emit JSON reports.
Enterprise contract example
apiVersion: tekton.dev/v1
kind: Task
metadata:
name: enterprise-contract-task
annotations:
task.results.format: application/json
task.results.type: ec
task.output.location: logs
task.results.container: step-report-json
ACS image scan example
apiVersion: tekton.dev/v1
kind: Task
metadata:
name: acs-image-scan
annotations:
task.results.format: application/json
task.results.type: roxctl-image-scan
task.results.key: SCAN_OUTPUT
task.output.location: logs
task.results.container: step-report
ACS image check example
apiVersion: tekton.dev/v1
kind: Task
metadata:
name: acs-image-check
annotations:
task.results.format: application/json
task.results.type: roxctl-image-check
task.results.key: SCAN_OUTPUT
task.output.location: logs
task.results.container: step-report
ACS deployment check example
apiVersion: tekton.dev/v1
kind: Task
metadata:
name: acs-deployment-check
annotations:
task.results.format: application/json
task.results.type: roxctl-deployment-check
task.results.key: SCAN_OUTPUT
task.output.location: logs
task.results.container: step-report
PipelineRun level results appear in the Others section of the Output modal.
Changelog
This changelog is produced from commits made to the Pipelines with Tekton plugin since 6 months ago, and based on the code located here. It may not contain information about all commits. Releases and version bumps are intentionally omitted. This changelog is generated by AI.
Breaking changes
- None
Features
Improvements
- Standardize i18n behavior to match Backstage docs #5562 merged 2 days ago
- Improve pod log fetching with TanStack Query. Cache results for faster renders. Reduce errors when pods are not ready #3572 merged 6 months ago
- Use useKubernetesObjects from plugin kubernetes react in place of local hook. Remove unused deps #4851 merged 1 month ago
Bug fixes
- Show Task Status horizontal bars again #4627 merged 2 months ago
- Show a loading state while the permission API loads #4809 merged 2 months ago
- Replace downloadLogFile helper with a local version to fix log downloads and remove shared react dependency #4262 merged 4 months ago
Documentation
- Fix Tekton and Feedback links in the NFS compatibility table #5518 merged 5 days ago
Maintenance
- Remove product theme from dev dependencies and the dev app #4803 merged 2 months ago
- Remove support and lifecycle keywords from plugin metadata. Clean up dynamic plugin app configs #4302 merged 3 months ago
Dependencies
- Update start server and test to 2.1.2 #5279 merged 5 days ago
- Update testing library jest dom to 6.8.0 #5252 merged 20 days ago
- Update testing library jest dom to 6.7.0 #4988 merged 1 month ago
- Update testing library jest dom to 6.6.4 #4843 merged 2 months ago
- Update Material UI packages to 5.18.0 #4396 merged 2 months ago
- Update start server and test to 2.0.13 #4895 merged 2 months ago
- Update types lodash to 4.17.20 #4338 merged 3 months ago
- Update types lodash to 4.17.17 #4145 merged 4 months ago
- Update start server and test to 2.0.12 #4028 merged 4 months ago
Set up Backstage in minutes with Roadie
Focus on using Backstage, rather than building and maintaining it.