Hide navigation
Components

Helm Broker

Overview

The Helm Broker is a Service Broker which exposes Helm charts as Service Classes in the Service Catalog. To do so, the Helm Broker uses the concept of bundles. Bundles are abstraction layers over Helm charts which provide all necessary information to convert the charts into Service Classes.

The Helm Broker fetches bundles which contain a set of specific files. You must place your bundles in a repository of an appropriate format. By default, the Helm Broker fetches bundles from the release of the bundles repository. You can also configure the Helm Broker to fetch bundle definitions from any remote HTTP server.

In Kyma, you can use bundles to install the following Service Brokers:

To get all the bundles that the Helm Broker provides, go to the bundles repository.

The Helm Broker implements the Open Service Broker API (OSB API). To be compliant with the Service Catalog version used in Kyma, the Helm Broker supports only the following OSB API versions:

  • v2.13
  • v2.12
  • v2.11

NOTE: The Helm Broker does not implement the OSB API update operation.

Architecture

The Helm Broker workflow starts with the registration process, during which the Helm Broker fetches bundles from the Kyma bundles repository, or from a remote HTTPS server.

Registration process

The registration process consists of the following steps: 1. The Helm Broker fetches bundles. 2. The Helm Broker registers bundles as Service Classes in the Service Catalog.

Helm Broker registration

Bundles provisioning and binding

After the registration, you can provision and bind your bundles. Follow these steps:

  1. Select a given bundle Service Class from the Service Catalog.
  2. Provision this Service Class by creating its ServiceInstance in a given Namespace.
  3. Bind your ServiceInstance to a service or lambda.
  4. The service or lambda calls a given bundle.

Helm Broker architecture

Create a bundle

Bundles which the Helm Broker uses must have a specific structure. These are all possible files that you can include in your bundle:

Click to copy
sample-bundle/
├── meta.yaml # [REQUIRED] A file which contains metadata information about this bundle
├── chart/ # [REQUIRED] A directory which contains a Helm chart that installs your Kubernetes resources
│ └── {chart-name}/ # [REQUIRED] A Helm chart directory
│ └── .... # [REQUIRED] Helm chart files
├── plans/ # [REQUIRED] A directory which contains the possible plans for an installed chart
│ ├── example-enterprise # [REQUIRED] A directory which contains files for a specific plan
│ │ ├── meta.yaml # [REQUIRED] A file which contains metadata information about this plan
│ │ ├── bind.yaml # A file which contains information required to bind this plan
│ │ ├── create-instance-schema.json # JSON schema definitions for creating a ServiceInstance
│ │ ├── bind-instance-schema.json # JSON schema definitions for binding a ServiceInstance
│ │ ├── update-instance-schema.json # JSON schema definitions for updating a ServiceInstance
│ │ └── values.yaml # Default configuration values in this plan for a chart defined in the `chart` directory
│ └── ....
└── docs/ # A directory which contains documentation for this bundle
├── meta.yaml # [REQUIRED] A file which contains metadata information about documentation for this bundle
├── {assets} # Files with documentation and assets
└── ....

NOTE: All file names in a bundle repository are case-sensitive.

For details about particular files, read the following sections.

meta.yaml file

The meta.yaml file contains information about the bundle. Define the following fields to create a service object which complies with the Open Service Broker API.

Field NameRequiredDescription
nameYESThe name of the bundle.
versionYESThe version of the bundle. It is a broker service identifier.
idYESThe broker service identifier.
descriptionYESThe short description of the service.
displayNameYESThe display name of the bundle.
tagsNOKeywords describing the provided service, separated by commas.
bindableNOThe field that specifies whether you can bind a given bundle.
providerDisplayNameNOThe name of the upstream entity providing the actual service.
longDescriptionNOThe long description of the service.
documentationURLNOThe link to the documentation page for the service.
supportURLNOThe link to the support page for the service.
imageURLNOThe URL to an image. You must provide the image in the SVG format.
labelsNOKey-value pairs that help you to organize your project. Use labels to indicate different elements, such as Namespaces, services, or teams.
bindingsRetrievableNOThe field that specifies whether fetching a ServiceBinding using a GET request on the resource's endpoint is supported for all plans. The default value is false.
planUpdatableNOThe field that specifies whether instances of this service can be updated to a different plan. The default value is false
requiresNOThe list of permissions the user must grant to the instances of this service.
provisionOnlyOnceNOThe field that specifies whether the bundle can be provisioned only once in a given Namespace. The default value is false.

NOTE: The provisionOnlyOnce and local keys are reserved and cannot be added to the labels entry, since the Helm Broker overrides them at runtime. The Helm Broker always adds the local:true label and it adds the provisionOnlyOnce:true label only if provisionOnlyOnce is set to true.

chart directory

In the chart directory, create a folder with the same name as your chart. Put all the files related to your chart in this folder. The system supports Helm version 2.6.

NOTE: The Helm Broker uses the helm wait option to ensure that all the resources that a chart creates are available. If you set your Deployment replicas to 1, you must set maxUnavailable to 0 as a part of the rolling update strategy.

plans directory

The plans directory must contain at least one plan. Each plan must contain the meta.yaml file. Other files are not mandatory.

  • meta.yaml file - contains information about a given plan. Define the following fields to create a plan object which complies with the Open Service Broker API.
Field NameRequiredDescription
nameYESThe name of the plan.
idYESThe ID of the plan.
descriptionYESThe description of the plan.
displayNameYESThe display name of the plan.
bindableNOThe field that specifies whether you can bind an instance of the plan or not. The default value is false.
freeNOThe attribute which specifies whether an instance of the plan is free or not. The default value is false.
  • bind.yaml file - contains information about binding in a specific plan. If you define in the meta.yaml file that your plan is bindable, you must also create a bind.yaml file. For more information about this file, see this document.

  • values.yaml file - provides the default configuration values in a given plan for the chart definition located in the chart directory. For more information, see the values files specification.

  • create-instance-schema.json file - contains a schema that defines parameters for a provision operation of a ServiceInstance. Each input parameter is expressed as a property within a JSON object.

  • update-instance-schema.json file - contains a schema that defines parameters for an update operation of a ServiceInstance. Each input parameter is expressed as a property within a JSON object.

  • bind-instance-schema.json file - contains a schema that defines parameters for a bind operation. Each input parameter is expressed as a property within a JSON object.

NOTE: For more information about schemas, see this specification.

docs directory

In the docs directory, provide documentation for your bundle. The docs directory must contain a meta.yaml which provides information on how documentation for the bundle is uploaded. As the Helm Broker is installed as a ClusterServiceBroker, documentation for bundles is provided using ClusterDocsTopics.

The meta.yaml file contains the specification of the ClusterDocsTopic. The example structure of the meta.yaml file looks as follows:

Field NameRequiredDescription
docs[]YESContains the definitions of documentation.
docs[].templateYESContains the specification of the ClusterDocsTopic.
docs[].template.displayNameYESSpecifies the display name of the ClusterDocsTopic.
docs[].template.descriptionYESProvides the description of the ClusterDocsTopic.
docs[].template.sources[]YESContains the definitions of assets for a bundle.
docs[].template.sources[].typeYESDefines the type of the asset.
docs[].template.sources[].nameYESDefines the name of the asset.
docs[].template.sources[].modeYESDefines the type of the asset file.
docs[].template.sources[].urlYESDefines the URL under which the asset is stored.
docs[].template.sources[].filterYESDefines the path from which to upload assets.

NOTE: Currently you can provide only one entry in the docs array.

Using the Helm Broker, you can provision a broker which provides its own Service Classes. To learn how to upload documentation for those classes, read this document.

Troubleshooting

Use the dry run mode to check the generated manifests of the chart without installing it. The --debug option prints the generated manifests. As a prerequisite, you must install Helm on your machine to run this command:

Click to copy
helm install --dry-run {path-to-chart} --debug

For more details, read the Helm official documentation.

Bind bundles

If you defined in the meta.yaml file that your plan is bindable, you must also create a bind.yaml file. The bind.yaml file supports the Service Catalog binding concept. It is mandatory for all bindable plans as it contains information needed during the binding process. Currently, Kyma supports only the credentials-type binding.

NOTE: Resolving the values from the bind.yaml file is a post-provision action. If this operation ends with an error, the provisioning also fails.

In the bind.yaml file, you can use the Helm chart templates directives. See the example:

Click to copy
# bind.yaml
credential:
- name: HOST
value: {{ template "redis.fullname" . }}.{{ .Release.Namespace }}.svc.cluster.local
{{- if .Values.usePassword }}
- name: REDIS_PASSWORD
valueFrom:
secretKeyRef:
name: {{ template "redis.fullname" . }}
key: redis-password
{{- end }}

In this example, the system renders the bind.yaml file. The system resolves all the directives enclosed in the double curly braces in the same way as in the files located in the templates directory in your Helm chart.

File specification

Define the following fields to create a valid bind.yaml file:

Field NameDescription
credentialThe list of credential variables returned during the binding action.
credential.nameThe name of a given credential variable.
credential.valueThe variable value. You can also use the Helm Chart templating directives. This field is interchangeable with credential.valueFrom.
credential.valueFromThe source of the given credential variable's value. This field is interchangeable with credential.value.
credential.valueFrom.configMapKeyRefThe field which selects a ConfigMap key in the Helm chart release Namespace.
credential.valueFrom.configMapKeyRef.nameThe name of the ConfigMap.
credential.valueFrom.configMapKeyRef.keyThe name of the key from which the value is retrieved.
credential.valueFrom.secretKeyRefThe field which selects a Secret key in the Helm Chart release Namespace.
credential.valueFrom.secretKeyRef.nameThe name of the Secret.
credential.valueFrom.secretKeyRef.keyThe name of the key from which the value is retrieved.
credential.valueFrom.serviceRefThe field which selects a service resource in the Helm Chart release Namespace.
credential.valueFrom.serviceRef.nameThe name of the service.
credential.valueFrom.serviceRef.jsonpathThe JSONPath expression used to select the specified field value. For more information, see the User Guide.
credentialFromThe list of sources to populate credential variables on the binding action. When the key exists in multiple sources, the value associated with the last source takes precedence. Variables from the credential section override the values if duplicated keys exist.
credentialFrom.configMapRefThe ConfigMap to retrieve the values from. It must be available in the Helm chart release Namespace.
credentialFrom.configMapRef.nameThe name of the ConfigMap.
credentialFrom.secretRefThe Secret to retrieve the values from. It must be available in the Helm chart release Namespace.
credentialFrom.secretRef.nameThe name of the Secret.

See the fully extended example of the bind.yaml file:

Click to copy
credential:
- name: HOST
value: redis.svc.cluster.local
- name: PORT
valueFrom:
serviceRef:
name: redis-svc
jsonpath: '{ .spec.ports[?(@.name=="redis")].port }'
- name: REDIS_PASSWORD
valueFrom:
secretKeyRef:
name: redis-secrets
key: redis-password
- name: REDIS_DB_NAME
valueFrom:
configMapKeyRef:
name: redis-cm
key: redis-db-name
credentialFrom:
- configMapRef:
name: redis-config
- secretRef:
name: redis-v2-secrets

In this example, the Helm Broker returns the following values:

  • A HOST key with the defined inlined value.
  • A PORT key with the value from the field specified by the JSONPath expressions. The redis-svc Service runs this expression.
  • A REDIS_PASSWORD key with a value selected by the redis-password key from the redis-secrets Secret.
  • All the key-value pairs fetched from the redis-config ConfigMap.
  • All the key-value pairs fetched from the redis-v2-secrets Secrets.
Credential name conflicts policy

The following rules apply in case of credential name conflicts:

  • If the credential and credentialFrom fields have duplicate values, the system uses the values from the credential field.
  • If you duplicate a key in the credential field, an error appears and informs you about the name of the key that the conflict refers to.
  • If a key exists in the multiple sources defined by the credentialFrom section, the value associated with the last source takes precedence.

Create a bundles repository

The repository in which you create your own bundles must be an HTTPS server with a specific structure so that the Helm Broker can fetch bundles from it. Your remote bundle repository can contain many bundles, each one compressed to the .tgz format and defined in index.yaml files. Depending on your needs and preferences, you can create one or more index.yaml files to categorize your bundles. The repository structure looks as follows:

Click to copy
sample-bundle-repository
├── {bundle_x_name}-{bundle_x_version}.tgz # A bundle compressed to a .tgz file
├── {bundle_y_name}-{bundle_y_version}.tgz
├── ...
├── index.yaml # A file which defines available bundles
├── index-2.yaml
└── ...

Read this document to learn how to set up your own bundles repository which generates .tgz and index.yaml files, and expose them using an HTTPS server. See the example of the Kyma bundles repository here.

{bundle_name}-{bundle_version}.tgz file

The {bundle_name}-{bundle_version}.tgz file is a compressed version of your bundle. To learn how to create your own bundle, read this document.

TIP: If you contribute to the bundles repository, you do not have to compress your bundles as the system does it automatically.

index.yaml file

In the index.yaml file, provide an entry for every single bundle from your bundles repository. The index.yaml file must have the following structure:

Click to copy
apiVersion: v1
entries:
{bundle_name}:
- name: {bundle_name}
description: {bundle_description}
version: {bundle_version}

See the example:

Click to copy
apiVersion: v1
entries:
redis:
- name: redis
description: Redis service
version: 0.0.1

Service Classes documentation provided by bundles

Using the Helm Broker, you can provision a bundle which defines a Service Broker and provides its own Service Classes. If you want to provide documentation for those Service Classes, create the docs.yaml file inside the bundle's chart to comply with the naming convention. The structure of this file looks as follows:

Click to copy
apiVersion: cms.kyma-project.io/v1alpha1
kind: DocsTopic
metadata:
labels:
cms.kyma-project.io/view-context: service-catalog
name: {ServiceClass ID}
spec:
displayName: {displayName}
description: {description}
sources:
- type: {type}
name: {name}
mode: {mode}
url: {{ .Values.addonsRepositoryURL }}
filter: docs/{class_name}/
___
apiVersion: cms.kyma-project.io/v1alpha1
kind: DocsTopic
metadata ...

If your bundle defines a ServiceBroker, use the DocsTopic type. If your bundle defines a ClusterServiceBroker, use the ClusterDocsTopic type. For more details, see the ClusterDocsTopic and DocsTopic custom resources documentation. For more information about currently supported types of the assets, read this document.

One ClusterDocsTopic or DocsTopic object corresponds to a single Service Class with the same ID as the name of the specified object. Store documentation for each Service Class in the docs/{class_name} directory which corresponds to the value of the filter parameter in the ClusterDocsTopic or DocsTopic definition.

During the provisioning process, the Helm Broker pushes the addonRepositoryURL variable into the chart. The addonsRepositoryURL points to your bundle compressed to a .tgz file.

Documentation structure

Deliver documentation for your bundle in the Markdown files with the specified metadata. The metadata must contain the title and type fields:

Click to copy
title: Services and Plans
type: Details

The title field defines the title of the document displayed in the Console.

Configuration

By default, the Helm Broker fetches bundles listed in the index.yaml file from the bundles repository release. You can also configure the Helm Broker to fetch bundle definitions from other remote HTTPS servers. To do so, follow these steps:

  1. Create a repository with your bundles. To complete this tutorial step by step, use the existing bundles repository.
  2. Install Kyma locally or on a cluster.
  3. Create a ConfigMap which contains an URL to the repository. You can either:
  • Create a ConfigMap using the kubectl create command:

    Click to copy
    kubectl create configmap my-helm-repos-urls -n kyma-system --from-literal=URLs=https://github.com/kyma-project/bundles/releases/download/0.3.0/index-testing.yaml

    NOTE: If you want to fetch bundles from many HTTP servers, use \n to separate the URLs.

    If you use this method, you must label your ConfigMap with helm-broker-repo=true. To add the label to your ConfigMap, run:

    Click to copy
    kubectl label configmap my-helm-repos-urls -n kyma-system helm-broker-repo=true
  • Create a valid ConfigMap from the yaml file. Follow this example:

    Click to copy
    apiVersion: v1
    kind: ConfigMap
    metadata:
    name: my-helm-repos-urls
    labels:
    helm-broker-repo: "true"
    data:
    URLs: |-
    https://github.com/kyma-project/bundles/releases/download/0.3.0/index-testing.yaml

    Then, run:

    Click to copy
    kubectl apply my-helm-repos-urls

    NOTE: Your bundle repository must contain at least one file named index.yaml as the Helm Broker automatically searches for it when you provide the https://{host}/{path}/{bundle_repo_version}/ URL to your ConfigMap.

    The default ConfigMap provided by the Helm Broker is the helm-repos-urls ConfigMap. Do not edit this ConfigMap. Create a separate one instead. Depending on your needs and preferences, you can create one or more ConfigMaps with URLs to different remote HTTPS servers.

  1. The Helm Broker triggers the Service Catalog synchronization automatically. New Service Classes appear after a few seconds.

Configuration rules

These are the rules you must follow when you configure the Helm Broker. Otherwise, the Helm Broker will not display your bundles.

  • If you use your bundle in two different repositories simultaneously, the Helm Broker detects a conflict and does not display this bundle at all. You can see the details of the conflict in the Helm Broker application logs. If you need a given bundle in two or more repositories, do not use them at the same time.
  • On your non-local clusters, you can use only servers with TLS enabled. All incorrect or unsecured URLs will be omitted. Find the information about the rejected URLs in the Helm Broker logs. You can use unsecured URLs only on your local cluster. To use URLs without TLS enabled, set the global.isDevelopMode environment variable in the values.yaml file to true.