akua / examples / 00-helm-hello

00-helm-hello

The smallest Package that exercises akua's `helm.template` engine callable end-to-end.

Renders end-to-end via the embedded helm-engine-wasm. No helm binary on $PATH needed or consulted. All template rendering happens inside a wasmtime WASI sandbox. See docs/security-model.md + docs/roadmap.md Phase 1.

The smallest Package that exercises akua's helm.template engine callable end-to-end.

What's here

filepurpose
package.kKCL Package; imports akua.helm, calls helm.template, wires the result into resources = ….
akua.tomlManifest — no external deps.
inputs.example.yamlAuto-discovered by akua render when --inputs is omitted.
chart/A tiny in-tree Helm chart (one ConfigMap template).

Render

package.k passes "./chart" to helm.template; akua resolves that against the Package.k's directory (via the path-traversal-guarded resolve_in_package) and hands the chart tarball to the embedded WASM Helm engine. akua render works from any cwd — point --package at this directory:

# Build the embedded helm engine once per machine:
task build:helm-engine-wasm

akua render --package examples/00-helm-hello/package.k --out ./rendered

The rendered ConfigMap lands at ./rendered/000-configmap-hello-greeting.yaml — already checked in alongside the example so you can eyeball the output without running anything.

What's happening

package.k imports akua.helm — the bundled akua KCL stdlib, a thin typed wrapper over kcl_plugin.helm — and calls helm.template(helm.Template { ... }). Under the hood, akua's plugin dispatcher routes the call to a Rust handler that tars the chart directory, hands it to a Go program compiled to wasm32-wasip1 hosted via wasmtime (see crates/helm-engine-wasm/), parses the multi-document YAML output back into resources, and splats them into resources.

No helm binary touched. No subprocess. No $PATH. The entire render path lives inside a WASI sandbox. Per CLAUDE.md: "No shell-out, ever."

Spec

See docs/package-format.md §5 for the outputs shape and docs/cli.md akua render.

package.k

# Minimal Package that exercises the `helm.template` plugin callable.
#
# Renders the adjacent `./chart/` (a tiny ConfigMap template) through
# akua's embedded wasmtime-hosted helm engine. No `helm` binary
# required; no shell-out. See docs/security-model.md + Phase 1 in
# docs/roadmap.md for why.
#
# Render:
#
#   akua render --out ./rendered
#
# `./chart` is a raw-string path resolved under the Package dir — the
# original simplest-possible shape. Example 01 shows the typed
# `import charts.<name>` form that Phase 2a landed; `akua render
# --strict` only accepts that form.
#
# Inputs flow through KCL's `option()` mechanism; `inputs.example.yaml`
# is auto-discovered when --inputs is omitted.

import akua.ctx
import akua.helm

schema Input:
    """Public inputs for 00-helm-hello."""

    greeting: str = "hello from akua"
    """Message embedded into the rendered ConfigMap."""

    replicas: int = 1
    """Replica count recorded in the ConfigMap."""

input: Input = ctx.input()

# helm.template returns a list of Kubernetes resources — a single
# ConfigMap in this case. `*_manifests` splats the list into
# `resources`.
_manifests = helm.template(helm.Template {
    chart     = "./chart"
    values    = {
        greeting = input.greeting
        replicas = input.replicas
    }
    release   = "hello"
    namespace = "default"
})

resources = _manifests

Rendered output

000-configmap-hello-greeting.yaml

apiVersion: v1
data:
  greeting: hello from the example
  replicas: '3'
kind: ConfigMap
metadata:
  labels:
    app.kubernetes.io/name: hello
  name: hello-greeting
  namespace: default

Source: examples/00-helm-hello/