Chapter 1. Understanding OpenShift Pipelines
OpenShift Pipelines is a Technology Preview feature only. Technology Preview features are not supported with Red Hat production service level agreements (SLAs) and might not be functionally complete. Red Hat does not recommend using them in production. These features provide early access to upcoming product features, enabling customers to test functionality and provide feedback during the development process.
For more information about the support scope of Red Hat Technology Preview features, see https://access.redhat.com/support/offerings/techpreview/.
Red Hat OpenShift Pipelines is a cloud-native, continuous integration and continuous delivery (CI/CD) solution based on Kubernetes resources. It uses Tekton building blocks to automate deployments across multiple platforms by abstracting away the underlying implementation details. Tekton introduces a number of standard Custom Resource Definitions (CRDs) for defining CI/CD pipelines that are portable across Kubernetes distributions.
1.1. Key features
- Red Hat OpenShift Pipelines is a serverless CI/CD system that runs Pipelines with all the required dependencies in isolated containers.
- Red Hat OpenShift Pipelines are designed for decentralized teams that work on microservice-based architecture.
- Red Hat OpenShift Pipelines use standard CI/CD pipeline definitions that are easy to extend and integrate with the existing Kubernetes tools, enabling you to scale on-demand.
- You can use Red Hat OpenShift Pipelines to build images with Kubernetes tools such as Source-to-Image (S2I), Buildah, Buildpacks, and Kaniko that are portable across any Kubernetes platform.
- You can use the OpenShift Container Platform Developer Console to create Tekton resources, view logs of Pipeline runs, and manage pipelines in your OpenShift Container Platform namespaces.
1.2. Red Hat OpenShift Pipelines concepts
Red Hat OpenShift Pipelines provide a set of standard Custom Resource Definitions (CRDs) that act as the building blocks from which you can assemble a CI/CD pipeline for your application.
- Task
- A Task is the smallest configurable unit in a Pipeline. It is essentially a function of inputs and outputs that form the Pipeline build. It can run individually or as a part of a Pipeline. A Pipeline includes one or more Tasks, where each Task consists of one or more Steps. Steps are a series of commands that are sequentially executed by the Task.
- Pipeline
- A Pipeline consists of a series of Tasks that are executed to construct complex workflows that automate the build, deployment, and delivery of applications. It is a collection of PipelineResources, parameters, and one or more Tasks. A Pipeline interacts with the outside world by using PipelineResources, which are added to Tasks as inputs and outputs.
- PipelineRun
- A PipelineRun is the running instance of a Pipeline. A PipelineRun initiates a Pipeline and manages the creation of a TaskRun for each Task being executed in the Pipeline.
- TaskRun
- A TaskRun is automatically created by a PipelineRun for each Task in a Pipeline. It is the result of running an instance of a Task in a Pipeline. It can also be manually created if a Task runs outside of a Pipeline.
- Workspace
- A Workspace is a storage volume that a Task requires at runtime to receive input or provide output. A Task or Pipeline declares the Workspace, and a TaskRun or PipelineRun provides the actual location of the storage volume, which mounts on the declared Workspace. This makes the Task flexible, reusable, and allows the Workspaces to be shared across multiple Tasks.
- Trigger
- A Trigger captures an external event, such as a Git pull request and processes the event payload to extract key pieces of information. This extracted information is then mapped to a set of predefined parameters, which trigger a series of tasks that may involve creation and deployment of Kubernetes resources. You can use Triggers along with Pipelines to create full-fledged CI/CD systems where the execution is defined entirely through Kubernetes resources.
- Condition
-
A Condition refers to a validation or check, which is executed before a Task is run in your Pipeline. Conditions are like
if
statements which perform logical tests, with a return value ofTrue
orFalse
. A Task is executed if all Conditions returnTrue
, but if any of the Conditions fail, the Task and all subsequent Tasks are skipped. You can use Conditions in your Pipeline to create complex workflows covering multiple scenarios.
1.3. Detailed OpenShift Pipeline Concepts
This guide provides a detailed view of the various Pipeline concepts.
1.3.1. Tasks
Tasks are the building blocks of a Pipeline and consist of sequentially executed Steps. Tasks are reusable and can be used in multiple Pipelines.
Steps are a series of commands that achieve a specific goal, such as building an image. Every Task runs as a pod and each Step runs in its own container within the same pod. Because Steps run within the same pod, they have access to the same volumes for caching files, ConfigMaps, and Secrets.
The following example shows the apply-manifests
Task.
apiVersion: tekton.dev/v1beta1 1 kind: Task 2 metadata: name: apply-manifests 3 spec: 4 params: - default: k8s description: The directory in source that contains yaml manifests name: manifest_dir type: string steps: - args: - |- echo Applying manifests in $(inputs.params.manifest_dir) directory oc apply -f $(inputs.params.manifest_dir) echo ----------------------------------- command: - /bin/bash - -c image: quay.io/openshift/origin-cli:latest name: apply workingDir: /workspace/source workspaces: - name: source
This Task starts the pod and runs a container inside that pod using the maven:3.6.0-jdk-8-slim
image to run the specified commands. It receives an input directory called workspace-git
that contains the source code of the application.
The Task only declares the placeholder for the Git repository, it does not specify which Git repository to use. This allows Tasks to be reusable for multiple Pipelines and purposes.
Red Hat OpenShift Pipelines 1.3 and earlier versions in Technology Preview (TP) allowed users to create a task without verifying their Security Context Constraints (SCC). Thus, any authenticated user could create a task using a container running with a privileged SCC.
To avoid such security issues in the production scenario, do not use Pipelines versions that are in TP. Instead, consider upgrading the Operator to generally available versions such as Pipelines 1.4 or later.
1.3.2. TaskRun
A TaskRun instantiates a Task for execution with specific inputs, outputs, and execution parameters on a cluster. It can be invoked on its own or as part of a PipelineRun.
A Task consists of one or more Steps that execute container images, and each container image performs a specific piece of build work. A TaskRun executes the Steps in a Task in the specified order, until all Steps execute successfully or a failure occurs.
The following example shows a TaskRun that runs the apply-manifests
Task with the relevant input parameters:
apiVersion: tekton.dev/v1beta1 1 kind: TaskRun 2 metadata: name: apply-manifests-taskrun 3 spec: 4 serviceAccountName: pipeline taskRef: 5 kind: Task name: apply-manifests workspaces: 6 - name: source persistentVolumeClaim: claimName: source-pvc
- 1
- TaskRun API version
v1beta1
. - 2
- Specifies the type of Kubernetes object. In this example,
TaskRun
. - 3
- Unique name to identify this TaskRun.
- 4
- Definition of the TaskRun. For this TaskRun, the Task and the required workspace are specified.
- 5
- Name of the Task reference used for this TaskRun. This TaskRun executes the
apply-manifests
Task. - 6
- Workspace used by the TaskRun.
1.3.3. Pipelines
A Pipeline is a collection of Task
resources arranged in a specific order of execution. You can define a CI/CD workflow for your application using pipelines containing one or more tasks.
A Pipeline
resource definition consists of a number of fields or attributes, which together enable the pipeline to accomplish a specific goal. Each Pipeline
resource definition must contain at least one Task
resource, which ingests specific inputs and produces specific outputs. The pipeline definition can also optionally include Conditions, Workspaces, Parameters, or Resources depending on the application requirements.
The following example shows the build-and-deploy
pipeline, which builds an application image from a Git repository using the buildah
ClusterTask
resource:
apiVersion: tekton.dev/v1beta1 1 kind: Pipeline 2 metadata: name: build-and-deploy 3 spec: 4 workspaces: 5 - name: shared-workspace params: 6 - name: deployment-name type: string description: name of the deployment to be patched - name: git-url type: string description: url of the git repo for the code of deployment - name: git-revision type: string description: revision to be used from repo of the code for deployment default: "release-tech-preview-3" - name: IMAGE type: string description: image to be built from the code tasks: 7 - name: fetch-repository taskRef: name: git-clone kind: ClusterTask workspaces: - name: output workspace: shared-workspace params: - name: url value: $(params.git-url) - name: subdirectory value: "" - name: deleteExisting value: "true" - name: revision value: $(params.git-revision) - name: build-image 8 taskRef: name: buildah kind: ClusterTask params: - name: TLSVERIFY value: "false" - name: IMAGE value: $(params.IMAGE) workspaces: - name: source workspace: shared-workspace runAfter: - fetch-repository - name: apply-manifests 9 taskRef: name: apply-manifests workspaces: - name: source workspace: shared-workspace runAfter: 10 - build-image - name: update-deployment taskRef: name: update-deployment workspaces: - name: source workspace: shared-workspace params: - name: deployment value: $(params.deployment-name) - name: IMAGE value: $(params.IMAGE) runAfter: - apply-manifests
- 1
- Pipeline API version
v1beta1
. - 2
- Specifies the type of Kubernetes object. In this example,
Pipeline
. - 3
- Unique name of this Pipeline.
- 4
- Specifies the definition and structure of the Pipeline.
- 5
- Workspaces used across all the Tasks in the Pipeline.
- 6
- Parameters used across all the Tasks in the Pipeline.
- 7
- Specifies the list of Tasks used in the Pipeline.
- 8
- Task
build-image
, which uses thebuildah
ClusterTask to build application images from a given Git repository. - 9
- Task
apply-manifests
, which uses a user-defined Task with the same name. - 10
- Specifies the sequence in which Tasks are run in a Pipeline. In this example, the
apply-manifests
Task is run only after thebuild-image
Task is completed.
1.3.4. PipelineRun
A PipelineRun instantiates a Pipeline for execution with specific inputs, outputs, and execution parameters on a cluster. A corresponding TaskRun is created for each Task automatically in the PipelineRun.
All the Tasks in the Pipeline are executed in the defined sequence until all Tasks are successful or a Task fails. The status
field tracks and stores the progress of each TaskRun in the PipelineRun for monitoring and auditing purpose.
The following example shows a PipelineRun to run the build-and-deploy
Pipeline with relevant resources and parameters:
apiVersion: tekton.dev/v1beta1 1 kind: PipelineRun 2 metadata: name: build-deploy-api-pipelinerun 3 spec: pipelineRef: name: build-and-deploy 4 params: 5 - name: deployment-name value: vote-api - name: git-url value: http://github.com/openshift-pipelines/vote-api.git - name: IMAGE value: image-registry.openshift-image-registry.svc:5000/pipelines-tutorial/vote-api workspaces: 6 - name: shared-workspace volumeClaimTemplate: spec: accessModes: - ReadWriteOnce resources: requests: storage: 500Mi
- 1
- PipelineRun API version
v1beta1
. - 2
- Specifies the type of Kubernetes object. In this example,
PipelineRun
. - 3
- Unique name to identify this PipelineRun.
- 4
- Name of the Pipeline to be run. In this example,
build-and-deploy
. - 5
- Specifies the list of parameters required to run the Pipeline.
- 6
- Workspace used by the PipelineRun.
1.3.5. Workspaces
It is recommended that you use Workspaces instead of PipelineResources in OpenShift Pipelines, as PipelineResources are difficult to debug, limited in scope, and make Tasks less reusable.
Workspaces declare shared storage volumes that a Task in a Pipeline needs at runtime. Instead of specifying the actual location of the volumes, Workspaces enable you to declare the filesystem or parts of the filesystem that would be required at runtime. You must provide the specific location details of the volume that is mounted into that Workspace in a TaskRun or a PipelineRun. This separation of volume declaration from runtime storage volumes makes the Tasks reusable, flexible, and independent of the user environment.
With Workspaces, you can:
- Store Task inputs and outputs
- Share data among Tasks
- Use it as a mount point for credentials held in Secrets
- Use it as a mount point for configurations held in ConfigMaps
- Use it as a mount point for common tools shared by an organization
- Create a cache of build artifacts that speed up jobs
You can specify Workspaces in the TaskRun or PipelineRun using:
- A read-only ConfigMaps or Secret
- An existing PersistentVolumeClaim shared with other Tasks
- A PersistentVolumeClaim from a provided VolumeClaimTemplate
- An emptyDir that is discarded when the TaskRun completes
The following example shows a code snippet of the build-and-deploy
Pipeline, which declares a shared-workspace
Workspace for the build-image
and apply-manifests
Tasks as defined in the Pipeline.
apiVersion: tekton.dev/v1beta1 kind: Pipeline metadata: name: build-and-deploy spec: workspaces: 1 - name: shared-workspace params: ... tasks: 2 - name: build-image taskRef: name: buildah kind: ClusterTask params: - name: TLSVERIFY value: "false" - name: IMAGE value: $(params.IMAGE) workspaces: 3 - name: source 4 workspace: shared-workspace 5 runAfter: - fetch-repository - name: apply-manifests taskRef: name: apply-manifests workspaces: 6 - name: source workspace: shared-workspace runAfter: - build-image ...
- 1
- List of Workspaces shared between the Tasks defined in the Pipeline. A Pipeline can define as many Workspaces as required. In this example, only one Workspace named
shared-workspace
is declared. - 2
- Definition of Tasks used in the Pipeline. This snippet defines two Tasks,
build-image
andapply-manifests
, which share a common Workspace. - 3
- List of Workspaces used in the
build-image
Task. A Task definition can include as many Workspaces as it requires. However, it is recommended that a Task uses at most one writable Workspace. - 4
- Name that uniquely identifies the Workspace used in the Task. This Task uses one Workspace named
source
. - 5
- Name of the Pipeline Workspace used by the Task. Note that the Workspace
source
in turn uses the Pipeline Workspace namedshared-workspace
. - 6
- List of Workspaces used in the
apply-manifests
Task. Note that this Task shares thesource
Workspace with thebuild-image
Task.
Workspaces help tasks share data, and allow you to specify one or more volumes that each task in the pipeline requires during execution. You can create a persistent volume claim or provide a volume claim template that creates a persistent volume claim for you.
The following code snippet of the build-deploy-api-pipelinerun
PipelineRun uses a volume claim template to create a persistent volume claim for defining the storage volume for the shared-workspace
Workspace used in the build-and-deploy
Pipeline.
apiVersion: tekton.dev/v1beta1 kind: PipelineRun metadata: name: build-deploy-api-pipelinerun spec: pipelineRef: name: build-and-deploy params: ... workspaces: 1 - name: shared-workspace 2 volumeClaimTemplate: 3 spec: accessModes: - ReadWriteOnce resources: requests: storage: 500Mi
- 1
- Specifies the list of Pipeline Workspaces for which volume binding will be provided in the PipelineRun.
- 2
- The name of the Workspace in the Pipeline for which the volume is being provided.
- 3
- Specifies a volume claim template that creates a persistent volume claim to define the storage volume for the workspace.
1.3.6. Triggers
Use Triggers in conjunction with pipelines to create a full-fledged CI/CD system where Kubernetes resources define the entire CI/CD execution. Triggers capture the external events and process them to extract key pieces of information. Mapping this event data to a set of predefined parameters triggers a series of tasks that can then create and deploy Kubernetes resources and instantiate the pipeline.
For example, you define a CI/CD workflow using Red Hat OpenShift Pipelines for your application. The pipeline must start for any new changes to take effect in the application repository. Triggers automate this process by capturing and processing any change event and by triggering a pipeline run that deploys the new image with the latest changes.
Triggers consist of the following main resources that work together to form a reusable, decoupled, and self-sustaining CI/CD system:
-
The
TriggerBinding
resource validates events, extracts the fields from an event payload, and stores them as parameters. -
The
TriggerTemplate
resource acts as a standard for the way resources must be created. It specifies the way parameterized data from theTriggerBinding
resource should be used. A trigger template receives input from the trigger binding, and then performs a series of actions that results in creation of new pipeline resources, and initiation of a new pipeline run. -
The
EventListener
resource provides an endpoint, or an event sink, that listens for incoming HTTP-based events with a JSON payload. It extracts event parameters from eachTriggerBinding
resource, and then processes this data to create Kubernetes resources as specified by the correspondingTriggerTemplate
resource. TheEventListener
resource also performs lightweight event processing or basic filtering on the payload using eventinterceptors
, which identify the type of payload and optionally modify it. Currently, pipeline triggers support four types of interceptors: Webhook Interceptors, GitHub Interceptors, GitLab Interceptors, and Common Expression Language (CEL) Interceptors. -
The
Trigger
resource connects theTriggerBinding
andTriggerTemplate
resources, and thisTrigger
resource is referenced in theEventListener
specification.
The following example shows a code snippet of the TriggerBinding
resource, which extracts the Git repository information from the received event payload:
apiVersion: triggers.tekton.dev/v1alpha1 1 kind: TriggerBinding 2 metadata: name: vote-app 3 spec: params: 4 - name: git-repo-url value: $(body.repository.url) - name: git-repo-name value: $(body.repository.name) - name: git-revision value: $(body.head_commit.id)
- 1
- The API version of the
TriggerBinding
resource. In this example,v1alpha1
. - 2
- Specifies the type of Kubernetes object. In this example,
TriggerBinding
. - 3
- Unique name to identify the
TriggerBinding
resource. - 4
- List of parameters which will be extracted from the received event payload and passed to the
TriggerTemplate
resource. In this example, the Git repository URL, name, and revision are extracted from the body of the event payload.
The following example shows a code snippet of a TriggerTemplate
resource, which creates a pipeline run using the Git repository information received from the TriggerBinding
resource you just created:
apiVersion: triggers.tekton.dev/v1alpha1 1 kind: TriggerTemplate 2 metadata: name: vote-app 3 spec: params: 4 - name: git-repo-url description: The git repository url - name: git-revision description: The git revision default: master - name: git-repo-name description: The name of the deployment to be created / patched resourcetemplates: 5 - apiVersion: tekton.dev/v1beta1 kind: PipelineRun metadata: name: build-deploy-$(tt.params.git-repo-name)-$(uid) spec: serviceAccountName: pipeline pipelineRef: name: build-and-deploy params: - name: deployment-name value: $(tt.params.git-repo-name) - name: git-url value: $(tt.params.git-repo-url) - name: git-revision value: $(tt.params.git-revision) - name: IMAGE value: image-registry.openshift-image-registry.svc:5000/pipelines-tutorial/$(tt.params.git-repo-name) workspaces: - name: shared-workspace volumeClaimTemplate: spec: accessModes: - ReadWriteOnce resources: requests: storage: 500Mi
- 1
- The API version of the
TriggerTemplate
resource. In this example,v1alpha1
. - 2
- Specifies the type of Kubernetes object. In this example,
TriggerTemplate
. - 3
- Unique name to identify the
TriggerTemplate
resource. - 4
- Parameters supplied by the
TriggerBinding
orEventListerner
resources. - 5
- List of templates that specify the way resources must be created using the parameters received through the
TriggerBinding
orEventListener
resources.
The following example shows a code snippet of a Trigger
resource, named vote-trigger
that connects the TriggerBinding
and TriggerTemplate
resources.
apiVersion: triggers.tekton.dev/v1alpha1 1 kind: Trigger 2 metadata: name: vote-trigger 3 spec: serviceAccountName: pipeline 4 bindings: - ref: vote-app 5 template: 6 name: vote-app
- 1
- The API version of the
Trigger
resource. In this example,v1alpha1
. - 2
- Specifies the type of Kubernetes object. In this example,
Trigger
. - 3
- Unique name to identify the
Trigger
resource. - 4
- Service account name to be used.
- 5
- Name of the
TriggerBinding
resource to be connected to theTriggerTemplate
resource. - 6
- Name of the
TriggerTemplate
resource to be connected to theTriggerBinding
resource.
The following example shows an EventListener
resource, which references the Trigger
resource named vote-trigger
.
apiVersion: triggers.tekton.dev/v1alpha1 1 kind: EventListener 2 metadata: name: vote-app 3 spec: serviceAccountName: pipeline 4 triggers: - triggerRef: vote-trigger 5
- 1
- The API version of the
EventListener
resource. In this example,v1alpha1
. - 2
- Specifies the type of Kubernetes object. In this example,
EventListener
. - 3
- Unique name to identify the
EventListener
resource. - 4
- Service account name to be used.
- 5
- Name of the
Trigger
resource referenced by theEventListener
resource.
1.4. Additional resources
- For information on installing Pipelines, see Installing OpenShift Pipelines.
- For more details on creating custom CI/CD solutions, see Creating applications with CI/CD Pipelines.