Tenant Release Pipelines
The usual release process in Konflux involves two different teams: a Development team and a Managed environment team as described in Releasing an application. The development team is usually the one who develops and support the application while the managed team will control the process and the secrets. Although this is a powerful workflow, in some cases it might feel very limiting. For example, sometimes the Development team wants to release their software to some destination that is directly under their control, using their own secrets, without depending on a Managed environment team. Another example would be performing actions before running the managed pipeline such as cleaning up old images or notifying about an ongoing release. The way Konflux supports these scenarios is by using something we call a tenant release pipeline. It’s a release pipeline that runs in the tenant namespace of the Development team, rather than in that of the Managed environment team.
The gist here is that this workflow doesn’t require a managed pipeline. You can omit the target and just specify the tenant pipeline you want to run. But, if both tenant and managed pipelines are provided, the tenant pipeline needs to succeed before continuing with the release of the application.
Using a tenant pipeline
Before starting to use a tenant pipeline there are some prerequisites you will have to fulfill:
-
You have an existing Development tenant namespace.
-
You have completed the steps listed in the Getting started in the CLI page.
-
You have a ServiceAccount with Roles allowing you to consume Releases and Snapshots.
-
You have access to a tenant pipeline.
To use a tenant pipeline:
-
Follow the regular instruction to create a ReleasePlan YAML file locally.
-
Specify the details about the tenant pipeline to run using the
tenantPipelinefield.Example
ReleasePlan.yamlobjectapiVersion: appstudio.redhat.com/v1alpha1 kind: ReleasePlan metadata: labels: release.appstudio.openshift.io/auto-release: 'true' (1) release.appstudio.openshift.io/standing-attribution: 'true' name: publish namespace: dev-tenant-namespace (2) spec: application: <application-name> (3) data: (4) mapping: components: (5) - name: demo-component-1 repositories: - url: registry/destination-image-repository-1 tags: - "some-tag" - url: registry/destination-image-repository-2 tags: - "some-other-tag" componentTags: - "latest" - name: demo-component-2 repositories: - url: registry/destination-image-repository-2 tags: - "some-tag" componentTags: - "latest" target: managed-tenant-namespace tenantPipeline: params: (6) - name: paramForPipeline value: foo pipelineRef: (7) resolver: git params: - name: url value: "https://github.com/<your-github-user>/<your-pipeline-repo>.git" - name: revision value: main - name: pathInRepo value: "<path-to-your-pipeline>" useEmptyDir: true (8) serviceAccountName: build-pipeline-$COMPONENT_NAME (9)1 Optional: Control if Releases should be created automatically for this ReleasePlan when tests pass. Defaults to true. 2 The development team’s tenant namespace. 3 The name of the application that you want to release via a pipeline in the development tenant namespace. 4 Optional: Pass custom data to the release. Primarily used with managed pipelines. 5 A list of components with their destination repositories. 6 The parameters to pass to your pipeline. Note: the release-operator will automatically pass parameters taskGitRevisionandtaskGitUrlwith the same values as thepipelineRefrevisionandpipelineRefurlparameters respectively. So, you should not pass your own values for these two parameters in this section. If you do, tekton validation webhooks will block the pipelineRun creation.7 Reference to the tenant pipeline to be executed in the development tenant namespace. 8 Optional: Use emptyDirworkspace instead of PVC. See Workspace configuration.9 The name of the service account used to execute the tenant pipeline. -
In case you want to avoid the execution of a managed pipeline, remove the
targetfield from yourReleasePlan.yamlfile. -
In the Development tenant namespace, apply the
ReleasePlan.yamlfile and add the resource to your cluster by running the following command:kubectl apply -f ReleasePlan.yaml -n dev -
Provision any secrets needed by the particular release pipeline you chose and upload them to the Development tenant namespace.
-
Create an
rbac.yamlfile locally. Note: This is optional, as your tenant pipeline doesn’t necessarily need to get any Releases, Snapshots, or ReleasePlans. However, the operator does pass references to these CRs to the tenant release pipeline and it is a common use case to use details from them in your pipeline.Example
rbac.yamlobjectapiVersion: rbac.authorization.k8s.io/v1 kind: Role metadata: name: publish-role (1) namespace: dev-tenant-namespace (2) rules: - apiGroups: - appstudio.redhat.com resources: - releases - releaseplans - snapshots verbs: - get - list - watch --- apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding metadata: name: publish-rolebinding (3) namespace: dev-tenant-namespace (4) roleRef: apiGroup: rbac.authorization.k8s.io kind: Role name: publish-role (5) subjects: - kind: ServiceAccount name: build-pipeline-$COMPONENT_NAME (6) namespace: dev-tenant-namespace (7)1 The name of the Role. 2 The development team’s tenant namespace. 3 The name of the RoleBinding. 4 The development team’s tenant namespace. 5 The name of the Role from (1). 6 The name of the service account used to execute the tenant pipeline. 7 The development team’s tenant namespace. -
In the Development tenant namespace, apply the
rbac.yamlfile and add the resources to your cluster by running the following command:kubectl apply -f rbac.yaml -n dev-tenant-namespace
Creating a new tenant pipeline
Tenant pipelines are Tekton pipelines defined by the {ProductName) community and are not supported by the release team. To fully integrate them with your workflow, you can define three optional parameters that, if defined, will be populated by the release service. Those parameters are release, releasePlan and snapshot. Each of this parameters will get the namespacedName reference to the resource so you can load them and process them in your pipeline.
Example tenant pipeline
apiVersion: tekton.dev/v1
kind: Pipeline
metadata:
name: my-tenant-pipeline
spec:
params:
- name: release (1)
type: string
- name: releasePlan (2)
type: string
- name: snapshot (3)
type: string
tasks:
- name: echo-resources
taskSpec:
steps:
- name: echo resources
image: ubuntu:latest
script: |
#!/usr/bin/env sh
echo "Release $(params.release)"
echo "ReleasePlan $(params.releasePlan)"
echo "Snapshot $(params.snapshot)"
| 1 | Namespacedname to the Release populated automatically by the release service (eg. dev-tenant-namespace/my-tenant-release). |
| 2 | Namespacedname to the ReleasePlan populated automatically by the release service (eg. dev-tenant-namespace/publish). |
| 3 | Namespacedname to the Snapshot populated automatically by the release service (eg. dev-tenant-namespace/my-snapshot). |
If you write a good reusable release pipeline, please submit it to our community catalog, so others can use it.
Final pipeline
Another type of tenant pipeline runs at the end of the release workflow. This is known as the final pipeline, and it allows you to execute a pipeline after the tenant or managed pipeline has completed.
You can use this pipeline, for example, to send Slack notifications once your images have been pushed or to generate a changelog summarizing the new changes.
To enable it, modify the ReleasePlan by adding the finalPipeline field.
Example of final pipeline declaration
apiVersion: appstudio.redhat.com/v1alpha1
kind: ReleasePlan
...
spec:
...
finalPipeline:
pipelineRef: (1)
resolver: git
params:
- name: url
value: "https://github.com/<your-github-user>/<your-pipeline-repo>.git"
- name: revision
value: main
- name: pathInRepo
value: "<path-to-your-pipeline>"
useEmptyDir: true (2)
serviceAccountName: build-pipeline-$COMPONENT_NAME (3)
| 1 | Reference to the tenant pipeline to be executed in the development tenant namespace. |
| 2 | Optional: Use emptyDir workspace instead of PVC. |
| 3 | The name of the service account used to execute the tenant pipeline. |
Both tenant and final pipelines receive the same parameters (i.e. release, releasePlan, and snapshot), allowing them to be used interchangeably. The key difference is that the final pipeline runs at the end of the release workflow, meaning the release status will contain the final outcome and all generated artifacts.
Understand workspace configuration
When a tenant or final PipelineRun is created, Konflux creates a workspace. There are two workspace types available, configured via the useEmptyDir parameter in your pipelineRef, which defaults to false.
emptyDir
Set useEmptyDir: true in your pipelineRef.
Konflux provisions a separate emptyDir volume for each TaskRun. The volume exists only for the lifetime of the TaskRun and is cleaned up afterwards. Steps within the same Task can share the workspace, but each Task receives its own volume, so artifacts created are not available to other Tasks in the Pipeline.
Advantages:
-
Faster PipelineRun startup with no PVC provisioning delay.
-
No impact on namespace PVC storage quotas.
Use this when:
-
Your Pipeline has a single Task with multiple Steps that share data.
-
Your Tasks run independently and do not share data across the Pipeline.
-
Your namespace has limited PVC quotas.
volumeClaimTemplate (default)
Set useEmptyDir: false or omit the field.
Konflux provisions a PersistentVolumeClaim from a volume template when the PipelineRun starts. The PVC is mounted into each Task that declares the workspace. This allows artifacts to be shared across Tasks in the Pipeline, and is cleaned up when the PipelineRun completes. However, this increases PipelineRun startup time and counts against your namespace’s PVC quota.
Advantages:
-
Tasks can share artifacts across the Pipeline.
-
A downstream Task can read artifacts written by an upstream Task.
Use this when:
-
Your Pipeline has multiple Tasks that share artifacts.
-
A downstream Task must read artifacts written by an upstream Task.