Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

type: helmfile

A helmfile Manifest is a Manifest type that takes multiple Helm releases described in (a subset of) the helmfile format, renders them equivalently to helmfile template and then applies the result to the cluster.

On compatibility. Tazuna does not depend on helmfile itself. It interprets a subset of helmfile.yaml on its own and internally generates manifests via the Helm package’s (helm.sh/helm/v3) in-memory render (action.Install{ClientOnly, DryRun}). The format and inspiration come from helmfile, but this is not helmfile itself. For the supported fields, see Supported helmfile subset.

The rendered YAML is converted to unstructured objects and applied to the cluster via Server-Side Apply (FieldOwner=tazuna). Helm release history is not stored on the cluster side (helm rollback is unavailable). The stance is that for bootstrapping, declarative regeneration is preferred over rollback.

The previous implementation called helmfile’s own app.Template and captured its stdout by globally replacing os.Stdout. This was a source of bugs where rendering results could get mixed up during parallel apply, but the migration to in-memory render has fixed it at the root.

path

Points to a helmfile.yaml (or helmfile.yaml.gotmpl) file, or the directory containing them. When a directory is specified, it searches in the order helmfile.yaml.gotmplhelmfile.yamlhelmfile.yml.gotmplhelmfile.yml. Write the path relative to the directory of tazuna.yaml itself.

Supported helmfile Subset

It interprets the following helmfile.yaml structure.

repositories:                   # Optional. Declare when referencing charts in <alias>/<chart> form
  - name: <alias>
    url: <repository URL>        # https://... or oci://...
    # username: <basic auth user>  # optional (HTTP(S) repositories only)
    # password: <basic auth password>
    # oci: true                    # to treat a registry whose url is not oci:// as OCI

releases:
  - name: <release name>
    namespace: <namespace>      # filled from defaultNamespace when omitted
    chart: <chart reference>          # one of the following
    version: <version>        # required for remote charts, informational for local charts
    values:
      - <relative path to a value file>
      - <inline values (map)>
  • helmfile.yaml itself is evaluated as a Go template. You can reference vars via .StateValues.<name> / .Values.<name>, and sprig functions such as default are available. However, env / expandenv are not available (this prevents a remote helmfile fetched via ORAS from reading the executor’s environment variables). Pass environment variables explicitly via from: env in vars.
  • chart supports the following three forms.
    • Relative path to a local chart (e.g. ./mychart, charts/mychart). Relative paths are resolved from the directory containing helmfile.yaml.
    • OCI chart reference (e.g. oci://public.ecr.aws/karpenter/karpenter-crd). Specify version; the chart is pulled via the helm registry client.
    • Repository alias form (<alias>/<chart>, e.g. argo-cd/argo-cd). When <alias> matches a name declared under repositories:, the chart at version is pulled from that url (HTTP(S) or OCI) — no helm repo add needed. When <alias> is not declared, it is resolved as a local relative path as before.
  • values merges value file paths and inline maps in order, and finally merges extraValueFiles as an override.

The following helmfile features are not supported: environments / bases / needs between releases / hooks / --selector, etc. If you need these, render with helmfile and import the result via type: kustomize or similar. However, {{ .Environment.Name }} inside templates can be referenced, and the value of tazuna’s -e/--environment flag is injected ("default" when unspecified).

Specific Fields

Written inside the manifests[].helmfile object.

FieldTypeRequiredDefaultDescription
varsmap<string, HelmFileVar>-{}Variables passed to helmfile. See vars for details.
includeCRDsbool-falsePasses the equivalent of --include-crds to helmfile template.
defaultNamespacestring-""The namespace assigned to rendered resources whose metadata.namespace is unset.
extraValueFiles[string]-[]Additional --values files passed to helmfile template.
waitbool-falseWhen true, wait after Apply until the target resources become Ready. See wait behavior for details.
timeoutSecondsint-0Maximum wait seconds for wait. With 0, 300 seconds (5 minutes) is used internally.
kubeVersionstring-""Value passed as --kube-version to helmfile template.

vars

vars keys are helmfile-side variable names; values are HelmFileVar.

At tazuna.yaml load time, vars are resolved in the following order.

  1. Retrieve the value according to each var’s from (env / static / op).
  2. If a tazuna.hint.yaml is in the same directory, run its validation and default injection.

Sometimes a value is injected via tazuna.hint.yaml’s default even when vars does not specify it. Conversely, violating a tazuna.hint.yaml constraint causes an error here.

HelmFileVar

FieldTypeRequiredDescription
fromstringYesWhere the value is retrieved from. One of env / static / op.
envstringConditional (*)Required when from: env. The name of the environment variable to reference.
staticstringConditional (*)Used when from: static. A scalar value.
staticSlice[string]Conditional (*)Used when from: static. A slice value.
staticMapmap<string, string>Conditional (*)Used when from: static. A map value.
opOnePasswordVaultSelectorConditional (*)Required when from: op.

(*) Depending on the value of from, one of env / static / op is required. For from: static, exactly one of static / staticSlice / staticMap must be set.

OnePasswordVaultSelector

FieldTypeRequiredDescription
keystringYesWhether to reference the field by id or label. Either id or label.
vaultstringYes1Password vault name.
itemstringYes1Password item name.
fieldstringYesField to retrieve. The field ID when key is id, or the label when key is label.

wait Behavior

When wait: true, after Apply finishes, it waits for all target resources to become Ready. Polling happens at 2-second intervals; exceeding timeoutSeconds (300 by default) is an error.

Ready judgment per Kind:

KindReady condition
DeploymentImmediately Ready if spec.replicas == 0. Otherwise: status.readyReplicas == status.replicas AND status.availableReplicas == status.replicas AND status.replicas > 0
StatefulSetImmediately Ready if spec.replicas == 0. Otherwise: status.readyReplicas == status.replicas AND status.replicas > 0
DaemonSetstatus.numberReady == status.desiredNumberScheduled AND status.desiredNumberScheduled > 0
Podstatus.phase == "Running" AND Ready condition is True
OthersTreated as Ready as soon as retrievable (ConfigMap / Secret / Service, etc.)

When you want to express resource-specific conditions that wait cannot handle (such as a CRD’s status), using Test plugin’s WaitUntil (CEL expression) is more flexible.

Behavior

OperationInternal processing
BuildReturns the YAML result of helm’s in-memory render.
ApplyConvert the render result to unstructured form, supplement defaultNamespace, and Server-Side Apply in order. If wait is true, wait for Ready.
DestroyConvert the render result to unstructured form, supplement defaultNamespace, and delete in order. wait is not applied.

All of Apply / Destroy / Build resolve vars at the render stage. If resolution fails (environment variable unset, field missing in the 1Password item, etc.), it fails without touching the cluster.

Examples

manifests:
  - name: cert-manager
    type: helmfile
    path: ./helmfile/cert-manager
    helmfile:
      includeCRDs: true
      wait: true
      timeoutSeconds: 120
      vars:
        clusterIssuerEmail:
          from: env
          env: CLUSTER_ISSUER_EMAIL
        dnsProviderApiToken:
          from: op
          op:
            key: label
            vault: example-vault
            item: dns-provider
            field: dns-provider-api-token
        extraLabels:
          from: static
          staticMap:
            managed-by: tazuna
            tier: platform