Skip to content

Cli Umbrella Chart

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

CLI Umbrella Chart

The CLI can scaffold an umbrella chart that groups multiple Timonel subcharts.

For new programmatic code, also review Umbrella Chart Examples, which uses UmbrellaRutter directly and has fewer generated moving parts.

1. Initialize

pnpm exec tl umbrella init commerce
cd commerce

Generated structure:

commerce/
├── umbrella.ts
├── umbrella.config.json
└── charts/

2. Add subcharts

pnpm exec tl umbrella add frontend
pnpm exec tl umbrella add backend

The command creates:

charts/frontend/chart.ts
charts/backend/chart.ts

and updates both umbrella.config.json and umbrella.ts.

3. Treat generated subcharts as scaffolds

The current CLI generator uses Timonel's compatibility-oriented object manifests and lower-level Helm helpers. You can progressively replace those resources with cdk8s-plus constructs:

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

export default function createFrontend(): Rutter {
  const chart = new Rutter({
    meta: {
      name: 'frontend',
      version: '1.0.0',
    },
  });

  const deployment = new kplus.Deployment(chart.getChart(), 'Frontend', {
    metadata: { name: 'frontend' },
    containers: [
      {
        name: 'frontend',
        image: 'nginx:1.27',
        portNumber: 80,
      },
    ],
  });

  deployment.exposeViaService();
  return chart;
}

Preserve the factory shape expected by the generated umbrella file when refactoring a scaffolded project.

4. Dependencies mode

This is the default:

pnpm exec tl umbrella synth dist --mode dependencies

Conceptual output:

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

The parent Chart.yaml contains local dependencies for each subchart.

Use this mode when you want normal Helm subchart scoping and dependency semantics.

5. Inline mode

pnpm exec tl umbrella synth dist --mode inline

Inline mode removes the parent dependency list and copies generated subchart templates into subdirectories under the parent's templates/ tree.

Use it only when you deliberately want a single rendered chart scope. Helm values behavior differs from dependency-mode subcharts, so validate your values paths carefully.

6. Validate both modes

Dependencies mode:

helm lint ./dist
helm template commerce ./dist

Inline mode should be synthesized into a clean output directory before validation so stale charts/ content cannot confuse the result.

7. Environment values and overrides

The umbrella CLI accepts the normal flags during synthesis/deployment paths where supported:

pnpm exec tl umbrella synth dist --mode dependencies --env production

Helm overrides remain available during validation/deployment:

cd dist
pnpm exec tl validate --set frontend.enabled=true

8. Understand umbrella.config.json

The file tracks scaffold metadata and subchart paths. tl umbrella add appends entries for created subcharts.

Do not use it as a secret store. Keep runtime credentials outside the generated project metadata.

9. Programmatic alternative

For a code-first umbrella chart, UmbrellaRutter is simpler:

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

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

See Umbrella Chart Examples.

10. Common mistakes

Adding resources to a temporary unrelated App

Attach native constructs to each subchart's Rutter.getChart() so Timonel synthesizes the expected construct tree.

Mixing values scopes between modes

Dependency mode naturally scopes values under subchart names. Inline mode operates in the parent chart scope. Render with real values before deploying.

Assuming generated scaffolds represent current best practice

Scaffolding is intentionally compatibility-friendly. The architecture guidance in Best Practices is authoritative for new code.

Clone this wiki locally