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 workspace.

  • 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:

  1. Follow the regular instruction to create a ReleasePlan YAML file locally.

  2. Specify the details about the tenant pipeline to run using the tenantPipeline field.

    Example ReleasePlan.yaml object

    apiVersion: 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-workspace (2)
    spec:
      application: <application-name> (3)
      data:
        mapping:
          components: (4)
            - name: demo-component-1
              repository: registry/destination-image-repository-1
              tags: [latest]
            - name: demo-component-2
              repository: registry/destination-image-repository-2
              tags: [latest]
      target: managed-workspace
      tenantPipeline:
        pipelineRef: (5)
          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>"
        serviceAccountName: appstudio-pipeline (6)
    1 Optional: Control if Releases should be created automatically for this ReleasePlan when tests pass. Defaults to true.
    2 The development team’s workspace.
    3 The name of the application that you want to release via a pipeline in the development workspace.
    4 A list containing the destination repository for each component
    5 Reference to the tenant pipeline to be executed in the development workspace.
    6 The name of the service account used to execute the tenant pipeline.
  3. In case you want to avoid the execution of a managed pipeline, remove the target field from your ReleasePlan.yaml file.

  4. In the Development workspace, apply the ReleasePlan.yaml file and add the resource to your cluster by running the following command:

    kubectl apply -f ReleasePlan.yaml -n dev
  5. Provision any secrets needed by the particular release pipeline you chose and upload them to the Development workspace.

  6. Create an rbac.yaml file 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.yaml object

    apiVersion: rbac.authorization.k8s.io/v1
    kind: Role
    metadata:
     name: publish-role (1)
     namespace: dev-workspace (2)
    rules:
    - apiGroups:
      - appstudio.redhat.com
      resources:
      - releases
      - releaseplans
      - snapshots
      verbs:
      - get
      - list
      - watch
    - apiGroups:
      - appstudio.redhat.com
      resources:
      - releases/status
      verbs:
      - get
      - patch
    ---
    apiVersion: rbac.authorization.k8s.io/v1
    kind: RoleBinding
    metadata:
     name: publish-rolebinding (3)
     namespace: dev-workspace (4)
    roleRef:
     apiGroup: rbac.authorization.k8s.io
     kind: Role
     name: publish-role (5)
    subjects:
    - kind: ServiceAccount
      name: appstudio-pipeline (6)
      namespace: dev-workspace (7)
    1 The name of the Role.
    2 The development team’s workspace.
    3 The name of the RoleBinding.
    4 The development team’s workspace.
    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 workspace.
  7. In the Development workspace, apply the rbac.yaml file and add the resources to your cluster by running the following command:

    kubectl apply -f rbac.yaml -n dev-workspace

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-workspace/my-tenant-release).
2 Namespacedname to the ReleasePlan populated automatically by the release service (eg. dev-workspace/publish).
3 Namespacedname to the Snapshot populated automatically by the release service (eg. dev-workspace/my-snapshot).

If you write a good reusable release pipeline, please submit it to our 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>"
    serviceAccountName: appstudio-pipeline (2)
1 Reference to the tenant pipeline to be executed in the development workspace.
2 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.

Next steps

Now that the ReleasePlan is defined, the development team can create a Release object to reference a specific Snapshot and the new ReleasePlan. It indicates the users' intent to release that Snapshot via the tenant release pipeline defined in the ReleasePlan.