Skip to content

Examples Umbrella Charts

Franklin García edited this page Sep 6, 2026 · 7 revisions

Examples: Umbrella Charts

For new programmatic code, prefer UmbrellaRutter with independently testable Rutter subcharts. The CLI umbrella scaffolding is useful when you want generated project structure, but it is not required by the library.

Minimal two-service umbrella

import * as kplus from 'cdk8s-plus-33';
import { Rutter, UmbrellaRutter } from 'timonel';

function createService(name: string, port: number): Rutter {
  const chart = new Rutter({
    meta: {
      name,
      version: '1.0.0',
    },
  });

  const deployment = new kplus.Deployment(chart.getChart(), 'Application', {
    metadata: { name },
    containers: [
      {
        name,
        image: `ghcr.io/example/${name}:1.0.0`,
        portNumber: port,
      },
    ],
  });

  deployment.exposeViaService({ name });

  return chart;
}

const frontend = createService('frontend', 8080);
const backend = createService('backend', 3000);

const umbrella = new UmbrellaRutter({
  meta: {
    name: 'commerce',
    version: '1.0.0',
    description: 'Commerce application',
  },
  subcharts: [
    {
      name: 'frontend',
      version: '1.0.0',
      rutter: frontend,
    },
    {
      name: 'backend',
      version: '1.0.0',
      rutter: backend,
    },
  ],
});

await umbrella.write('./dist/commerce');

Generated structure

dist/commerce/
├── Chart.yaml
├── values.yaml
├── templates/
│   └── NOTES.txt
└── charts/
    ├── frontend/
    │   ├── Chart.yaml
    │   ├── values.yaml
    │   └── templates/
    └── backend/
        ├── Chart.yaml
        ├── values.yaml
        └── templates/

The parent Chart.yaml points to local chart dependencies by default.

Conditional subchart

Use the standard Helm dependency condition field:

const umbrella = new UmbrellaRutter({
  meta: {
    name: 'platform',
    version: '1.0.0',
  },
  defaultValues: {
    observability: {
      enabled: false,
    },
  },
  subcharts: [
    {
      name: 'api',
      version: '1.0.0',
      rutter: api,
    },
    {
      name: 'observability',
      version: '1.0.0',
      rutter: observability,
      condition: 'observability.enabled',
    },
  ],
});

The condition is written into the parent chart dependency metadata. Keep the corresponding value in the parent values tree.

Tags

Subcharts can also expose Helm dependency tags:

{
  name: 'metrics',
  version: '1.0.0',
  rutter: metrics,
  tags: ['observability'],
}

Use conditions for explicit feature flags and tags when you deliberately want Helm's grouped dependency enablement behavior.

Environment-specific parent values

const umbrella = new UmbrellaRutter({
  meta: {
    name: 'commerce',
    version: '1.0.0',
  },
  subcharts,
  defaultValues: {
    frontend: {
      enabled: true,
    },
    backend: {
      enabled: true,
    },
  },
  envValues: {
    production: {
      frontend: {
        enabled: true,
      },
      backend: {
        enabled: true,
      },
    },
  },
});

UmbrellaRutter writes parent environment files after merging the environment override into the base parent values.

External dependency repository

A subchart entry can override the repository:

{
  name: 'external-service',
  version: '1.2.0',
  rutter: localRepresentation,
  repository: 'https://charts.example.com',
}

When using a remote repository, decide whether you still want Timonel to write the local subchart under charts/. UmbrellaRutter.write() currently writes each supplied rutter locally even when a repository override is present, so use this option deliberately.

Validate the umbrella

helm lint ./dist/commerce
helm template commerce ./dist/commerce

For a dependency chart, inspect both parent and child values scopes in the rendered output.

CLI alternative

pnpm exec tl umbrella init commerce
cd commerce
pnpm exec tl umbrella add frontend
pnpm exec tl umbrella add backend
pnpm exec tl umbrella synth dist --mode dependencies

The CLI also has an inline mode. See CLI Umbrella Chart for the behavioral difference.

Design recommendations

  • keep each subchart independently synthesizable and lintable;
  • attach Kubernetes resources to each subchart's getChart();
  • keep resource IDs stable for readable diffs;
  • keep shared parent values small and intentional;
  • avoid cross-subchart assumptions that Helm dependency scoping cannot represent;
  • test the final parent chart with real environment values before deployment.

Clone this wiki locally