Running the adapter as a pipeline stage
The Portal Controller generates Backstage entities for you: install it with a backstage portal,
label a Promise with kratix.io/portal-backstage, and the entities appear. That is the
recommended path, and most platforms should use it. See Installation.
This page is for platforms that already wire the generator into each Promise's pipeline by hand
and want to carry on doing so. The generator now ships as the portal adapter, the entrypoint
of the ghcr.io/syntasso/ske-portal-controller image, which is the same binary that used to ship
in the Backstage Controller image. Swapping the image keeps that setup working.
Running the adapter yourself gives you the generate stage and nothing else. You do not get:
- A portal-owned Destination and state store. You must create a Destination labelled
environment: backstageyourself, as described below. PortalCustomizationbindings, so no Portal Patch recipes. You can still add your own containers after the adapter in the same pipeline.- Sync conditions, events, or the
kratix.io/portal-<type>-entity-urlannotation. - The setup stage, credential handling, or anything the Cortex portal type provides.
The adapter has no independently published image or version of its own: it is versioned with the Portal Controller. If you want the features above, use the Portal Controller rather than this page.
Kratix sets KRATIX_WORKFLOW_TYPE on every pipeline container, and the adapter uses it to pick a
mode when none is given. Without an explicit mode it selects a legacy path that does not
generate entities, and which needs cluster permissions it will not have.
Always pass --mode=generate, as every example on this page does. Setting the environment
variable PORTAL_ADAPTER_ACTION=generate does the same thing.
Added as a container in a Kratix Pipeline, the adapter generates the Backstage Template and Component manifests for your Promises and Resource requests, driven by the environment variables and annotations documented below. Those manifests are read by Backstage and are designed to work with the SKE Backstage plugins.
Prerequisites
SKE Backstage plugins
The ske-portal-adapter uses an action from the ske-backend Backstage plugin.
This action is used within the generated Template to create a Resource Request.
The generated Components are also used by the ske-frontend Backstage plugin to display
Promise and Resource metadata.
In order to utilise the Templates and Components, you should also install both the
ske-backend and ske-frontend plugins into your Backstage instance.
See Configuring the Plugins for instructions.
Backstage Destination
You must have a Destination created with the environment: backstage label. See the
Kratix Backstage docs
for setup instructions.
How does it work?
ske-portal-adapter is intended to be run as part of your Configure Pipeline for your Promise and Resource Workflows. It will auto-generate Backstage Template and Component manifests, and schedule them to your Backstage Destination.
Promise Configure
In a Promise Configure workflow, two Backstage manifests will be generated:
- Promise Component: A Backstage Component representing the Promise.
- Promise Template: A Backstage Template representing the Promise API (i.e. the CRD for Resources created from this Promise).
Check the YAML File Format for examples of these manifests.
Resource Configure
In a Resource Configure workflow, a single Backstage manifest will be generated:
- Resource Component: A Backstage Component representing the Resource.
Check the YAML File Format for examples of these manifests.
Accessing the image
Pulling the image locally
The image is hosted in a private registry. To access the image, you will need to authenticate using the Syntasso registry token you have been provided with. For Docker, you can run the following command, providing your token as the password when prompted:
docker login ghcr.io --username syntasso-pkg
If you are using a different container engine, follow the docs for your specific tool.
Once you have authenticated, you can pull any released version of the image.
docker pull ghcr.io/syntasso/ske-portal-controller:VERSION
Pulling the image from your cluster
Your Kubernetes cluster must have permission to pull this image from the private registry.
If your cluster is running in a secure environment, you may wish to pull this image and push it to an internal registry which your cluster has permission to pull from.
If you are using a local cluster such as Minikube of KinD, of have used the quick-start guide to set up a development environment, you can load the image directly to the Kubernetes cache. Different tools have different commands for this. For example:
# For minikube
minikube image load ghcr.io/syntasso/ske-portal-controller:VERSION
# For KinD
kind load docker-image ghcr.io/syntasso/ske-portal-controller:VERSION
For other tools, follow their specific documentation.
When using the adapter in your Workflows, you can define the secret you want to use for authentication within your Promise, see below for more details.
Using the adapter in your Workflows
To use ske-portal-adapter, update your Promise definition to include it as a container in both the Promise Configure and Resource Configure workflows:
# ...
workflows:
promise:
configure:
- apiVersion: platform.kratix.io/v1alpha1
kind: Pipeline
metadata:
name: promise-configure
spec:
containers:
- image: ghcr.io/syntasso/kratix-marketplace/jenkins-configure-pipeline:v0.1.0
name: jenkins-promise-pipeline
- image: ghcr.io/syntasso/ske-portal-controller:VERSION
name: ske-portal-adapter
args: ["--mode=generate"]
resource:
configure:
- apiVersion: platform.kratix.io/v1alpha1
kind: Pipeline
metadata:
name: resource-configure
spec:
containers:
- image: ghcr.io/syntasso/kratix-marketplace/jenkins-configure-pipeline:v0.1.0
name: jenkins-resource-pipeline
- image: ghcr.io/syntasso/ske-portal-controller:VERSION
name: ske-portal-adapter
args: ["--mode=generate"]
Once your Promise is updated, the adapter will be run as part of your Workflows. If you install the Promise, you should see a Component automatically appearing in your Backstage instance, together with a new Template. If you use the Template to create a Resource, you should see the resource Component appearing as well as the Resource itself being created in your cluster.
In order to have the full status of your Promise or Resource request displayed in Backstage,
you should place ske-portal-adapter as the last container in the last pipeline of your workflow.
If ske-portal-adapter needs to be used more than once in a Workflow, you should utilise the SKE Backstage
Component Promise. Otherwise, you will observe only one of the components
in Backstage, and Backstage will emit a warning:
{"level":"warn","message":"Detected conflicting entityRef component:default/my-request-jenkins already referenced by url:http://minio.kratix-platform-system.svc.cluster.local/kratix/backstage/resources/default/cicd/my-request/instance-configure/5cfaf/backstage/catalog-info.yaml and now also url:http://minio.kratix-platform-system.svc.cluster.local/kratix/backstage/resources/default/cicd/my-request/instance-configure-2/5cfaf/backstage/catalog-info.yaml","plugin":"catalog","service":"backstage"}
Authenticating against the image registry
If you have not loaded the image to your Kubernetes cache or pushed it to an internal registry,
you can define your authentication credentials via a docker-registry secret and refer to this secret
in Pipeline definition in your Workflow.
You can create the secret with the following command, replacing YOUR_TOKEN with the token you have
been provided with:
kubectl create secret docker-registry syntasso-registry \
--docker-server=ghcr.io \
--docker-username=syntasso-pkg \
--docker-password=YOUR_TOKEN \
--namespace kratix-platform-system
The secret must exist in the kratix-platform-system namespace as well as any other namespaces where users
be able to make requests
The imagePullSecrets field in your Workflow can be used to refer to the new syntasso-registry
secret.
# ...
workflows:
promise:
configure:
- apiVersion: platform.kratix.io/v1alpha1
kind: Pipeline
metadata:
name: promise-configure
spec:
imagePullSecrets:
- name: syntasso-registry
containers:
- image: ghcr.io/syntasso/kratix-marketplace/jenkins-configure-pipeline:v0.1.0
name: jenkins-promise-pipeline
- image: ghcr.io/syntasso/ske-portal-controller:VERSION
name: ske-portal-adapter
args: ["--mode=generate"]
This ensures that, when pulling the ske-portal-controller image, Kubernetes will use the
syntasso-registry secret for authentication.
Customising the generated Components
By default, the adapter will create the Backstage Promise Component with default values for the metadata and
spec fields. For a Promise, for example, it will look like this:
metadata:
name: <Promise Kind>-promise
title: <Promise Kind> Promise
description: <Promise Kind> as a Service
tags:
- kratix
spec:
lifecycle: production
owner: kratix-platform
type: kratix-promise
# Other fields are left empty
You can customise these values by setting the following env variables in the
workflow:
COMPONENT_NAME: the value ofmetadata.nameCOMPONENT_TITLE: the value ofmetadata.titleCOMPONENT_DESCRIPTION: the value ofmetadata.descriptionCOMPONENT_TAGS: comma-separated list of values formetadata.tagsCOMPONENT_TYPE: the value ofspec.typeCOMPONENT_LIFECYCLE: the value ofspec.lifecycleCOMPONENT_OWNER: the value ofspec.ownerCOMPONENT_SYSTEM: the value ofspec.systemCOMPONENT_SUBCOMPONENT_OF: the value ofspec.subcomponentOfCOMPONENT_PROVIDES_APIS: comma-separated list of values forspec.providesApisCOMPONENT_CONSUMES_APIS: comma-separated list of values forspec.consumesApisCOMPONENT_DEPENDS_ON: comma-separated list of values forspec.dependsOn
You can also customise the fields by setting the following annotations in the Promise or Resource object directly:
ske.backstage.component/name: the value ofmetadata.nameske.backstage.component/title: the value ofmetadata.titleske.backstage.component/description: the value ofmetadata.descriptionske.backstage.component/tags: comma-separated list of values formetadata.tagsske.backstage.component/type: the value ofspec.typeske.backstage.component/lifecycle: the value ofspec.lifecycleske.backstage.component/owner: the value ofspec.ownerske.backstage.component/system: the value ofspec.systemske.backstage.component/subcomponentOf: the value ofspec.subcomponentOfske.backstage.component/providesApis: comma-separated list of values forspec.providesApisske.backstage.component/consumesApis: comma-separated list of values forspec.consumesApisske.backstage.component/dependsOn: comma-separated list of values forspec.dependsOn
For example, to set spec.owner and spec.providesApis, you can update your
Pipeline Stage with the snippet below:
#...
workflows:
promise:
configure:
- apiVersion: platform.kratix.io/v1alpha1
kind: Pipeline
metadata:
name: promise-configure
spec:
containers:
- image: ghcr.io/syntasso/kratix-marketplace/jenkins-configure-pipeline:v0.1.0
name: jenkins-promise-pipeline
- image: ghcr.io/syntasso/ske-portal-controller:VERSION
name: ske-portal-adapter
args: ["--mode=generate"]
env:
- name: COMPONENT_OWNER
value: "platform-team"
- name: COMPONENT_PROVIDES_APIS
value: "component/api/v1,component/api/v2"
For any further customisation, you can directly modify the generated Component
in the /kratix/output/backstage/catalog-info.yaml file.
Customising the generated Templates
By default, the adapter will create the Backstage Template with default
values for the metadata and spec fields, as shown below:
metadata:
name: <Promise Kind>-promise-template
title: <Promise Kind>
description: <Promise Kind> as a Service
tags:
- kratix
- <Promise Name>-promise
spec:
lifecycle: experimental
owner: kratix-platform
type: kratix-resource
# steps and parameters will be generated based on the Promise API
You can customise these values by setting the following env variables in the
workflow:
TEMPLATE_TITLE: the value ofmetadata.titleTEMPLATE_DESCRIPTION: the value ofmetadata.descriptionTEMPLATE_TAGS: comma-separated list of values formetadata.tagsTEMPLATE_TYPE: the value ofspec.typeTEMPLATE_LIFECYCLE: the value ofspec.lifecycleTEMPLATE_OWNER: the value ofspec.owner
The environment variables must be set on the adapter container in the
promise.configure workflow, since that's where the Backstage Template is
generated.
You can also customise the fields by setting the following annotations in the Promise or Resource object directly:
ske.backstage.template/title: the value ofmetadata.titleske.backstage.template/description: the value ofmetadata.descriptionske.backstage.template/tags: comma-separated list of values formetadata.tagsske.backstage.template/type: the value ofspec.typeske.backstage.template/lifecycle: the value ofspec.lifecycleske.backstage.template/owner: the value ofspec.owner
For example, to set metadata.title and spec.owner, you can update your
Pipeline Stage with the snippet below:
#...
workflows:
promise:
configure:
- apiVersion: platform.kratix.io/v1alpha1
kind: Pipeline
metadata:
name: promise-configure
spec:
containers:
- image: ghcr.io/syntasso/kratix-marketplace/jenkins-configure-pipeline:v0.1.0
name: jenkins-promise-pipeline
- image: ghcr.io/syntasso/ske-portal-controller:VERSION
name: ske-portal-adapter
args: ["--mode=generate"]
env:
- name: TEMPLATE_OWNER
value: "platform-team"
- name: TEMPLATE_TITLE
value: "My Super Service"
Customising the Steps and Parameters
By default, the adapter will create the Backstage Template with resource namespace as a required field.
You can customise this behaviour by setting the following env variables in the workflow:
TEMPLATE_NAMESPACE: the default value of the resource namespaceTEMPLATE_NAMESPACE_FIELD_TITLE: the name of the resource namespace field in Backstage UITEMPLATE_NAMESPACE_FIELD_DESCRIPTION: the description of the resource namespace field in Backstage UITEMPLATE_SINGLE_SPEC_PAGE: set totrueif you would like to generate a single page for the Spec in the Template, rather than a page per.spec.<field>TEMPLATE_HIDE_NAMESPACE: set totrueif you would like to hide the namespace field from the generated resource Template. Resource namespace will default toTEMPLATE_NAMESPACEwhen it is set, otherwise will be set todefaultnamespace.
For example, to generate the resource Template without the namespace field and set the resource namespace to my-team
for all resource requests:
#...
workflows:
promise:
configure:
- apiVersion: platform.kratix.io/v1alpha1
kind: Pipeline
metadata:
name: promise-configure
spec:
containers:
- image: ghcr.io/syntasso/kratix-marketplace/jenkins-configure-pipeline:v0.1.0
name: jenkins-promise-pipeline
- image: ghcr.io/syntasso/ske-portal-controller:VERSION
name: ske-portal-adapter
args: ["--mode=generate"]
env:
- name: TEMPLATE_NAMESPACE
value: "my-team"
- name: TEMPLATE_HIDE_NAMESPACE
value: "true"
For any further customisation, you can directly modify the generated Template
in the /kratix/output/backstage/catalog-info.yaml file.
Providing a Resource Summary
On the Resource Component page, it's possible to include a free-form text block to provide documentation about the resource.
To do this, set the ske.backstage.component/summary annotation on the Promise object:
apiVersion: platform.kratix.io/v1alpha1
kind: Promise
metadata:
#...
annotations:
ske.backstage.component/summary: |
Some information about this Promise.
This accepts **markdown!**
The text will be rendered on each Resource Component page in Backstage.
