How to create a Catalog
This page explains how to author a custom catalog for kubara and how to prepare it for distribution.
If you are new to the idea itself, read Catalogs first.
When you need a custom catalog
You usually need a custom catalog when you want to:
- add a platform service that kubara does not ship
- replace a built-in chart or module with your own
- change platform defaults across many clusters
- package and distribute a reusable platform setup outside the kubara source tree
If you only need to add a simpler workload to one cluster or one team space, use the Argo CD guides in Workload Onboarding with Argo CD instead.
Step 1: scaffold the catalog
Create the catalog root:
kubara catalog create my-catalog
The catalog name must follow RFC 1123 naming rules:
- lowercase letters
- digits
-- starts with a letter
- ends with a letter or digit
Generated structure:
my-catalog/
├── Catalog.yaml
├── services/
├── managed-service-catalog/
│ ├── helm/
│ └── terraform/
└── customer-service-catalog/
├── helm/
│ └── example/
└── terraform/
└── example/
The generated Catalog.yaml looks like this:
apiVersion: kubara.io/v1alpha1
kind: Catalog
metadata:
name: my-catalog
spec:
version: 0.1.0
spec.version is important because kubara uses it when packaging the catalog as an OCI artifact.
kubara enforces strict semantic version formatting for catalogs:
- allowed:
0.1.0 - not allowed:
v0.1.0 - not allowed:
0.1.0-rc.1 - not allowed:
0.1.0-beta - not allowed:
0.1.0+build.5
Only plain major.minor.patch is accepted.
Step 2: add service definitions
Move into the catalog root and add a service:
cd my-catalog
kubara catalog add pet-store
This creates services/pet-store.yaml.
Example:
apiVersion: kubara.io/v1alpha1
kind: ServiceDefinition
metadata:
name: pet-store
spec:
chartPath: pet-store
status: disabled
clusterTypes:
- hub
- spoke
Key fields:
metadata.name: stable service key used inconfig.yamlspec.chartPath: chart directory name undermanaged-service-catalog/helm/spec.status: default statusspec.clusterTypes: optional hub/spoke limitspec.configSchema: optional schema for service-specific config
Step 3: add the actual platform content
A service definition alone is not enough. kubara also needs the files it should render or copy.
Common places:
managed-service-catalog/helm/<chart>/managed-service-catalog/terraform/...customer-service-catalog/helm/example/<chart>/customer-service-catalog/terraform/example/...
Use managed-service-catalog/ for reusable source content.
Use customer-service-catalog/ for cluster-specific overlays.
If you want to learn how .tplt files work, read Catalog templating.
Step 4: use the catalog with kubara
Point kubara at the catalog root:
kubara schema --catalog ./my-catalog
kubara init --catalog ./my-catalog
kubara generate --catalog ./my-catalog
Pass the catalog root, not only services/, when you also want kubara to load templates.
Step 5: override built-in services when needed
You can override a built-in service by reusing the same metadata.name.
Typical reasons:
- change the default
status - change the
chartPath - provide a different
configSchema - replace built-in templates with internal ones
Without --catalog-overwrite, kubara rejects the collision.
With --catalog-overwrite, your external definition replaces the built-in definition for that service name.
Step 6: package the catalog
When the catalog is ready, package it into the local cache:
kubara catalog package oci://ghcr.io/acme/platform-catalogs/
kubara derives the final reference from:
metadata.namespec.version- the optional OCI base path you pass
That means packaging is versioned by Catalog.yaml, not by the directory name alone.
Step 7: distribute the catalog
After packaging, you can:
- log into a registry
- push the cached artifact
- pull it somewhere else
- use the pulled OCI reference with
--catalog
See Catalog distribution for the full workflow.
Provider-specific Terraform templates
Provider-specific template variants are supported only below:
terraform/providers/<provider>/
Example:
customer-service-catalog/terraform/providers/stackit/example/infrastructure/main.tf.tplt
When the cluster Terraform provider matches the directory name, kubara uses that provider-specific file for the generated output path.
Provider-specific directories below Helm paths are not treated as provider overrides.
Practical guidance
- Keep
metadata.namestable. - Keep
spec.versionstable until you intentionally publish a new version. - Keep
chartPathaligned with the actual Helm chart directory name. - Use
configSchemafor defaults and validation instead of prose only. - Treat the catalog directory as the maintainable source.
- Treat generated files in your repo as output.