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.yamlon 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.Templateand captured its stdout by globally replacingos.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.gotmpl → helmfile.yaml → helmfile.yml.gotmpl → helmfile.yml. Write the path relative to the directory of tazuna.yaml itself.
Supported helmfile Subset
It interprets the following helmfile.yaml structure.
repositories: # 省略可。chart を <alias>/<chart> 形式で参照する場合に宣言する
- name: <alias>
url: <リポジトリ URL> # https://... もしくは oci://...
# username: <basic 認証ユーザ> # 省略可 (HTTP(S) リポジトリのみ)
# password: <basic 認証パスワード>
# oci: true # url が oci:// でない registry を OCI 扱いにする場合
releases:
- name: <release name>
namespace: <namespace> # filled from defaultNamespace when omitted
chart: <chart 参照> # 下記のいずれか
version: <バージョン> # リモート chart では必須、ローカルチャートでは情報用
values:
- <relative path to a value file>
- <inline values (map)>
helmfile.yaml自体を Go テンプレートとして評価します。.StateValues.<name>/.Values.<name>でvarsを参照でき、defaultなどの sprig 関数が使えます。 ただしenv/expandenvは使えません (ORAS 経由で取得したリモートの helmfile が実行者の環境変数を読み取るのを防ぐため)。環境変数はvarsのfrom: envで明示的に渡してください。chartは次の 3 形式に対応します。- ローカルチャートへの相対パス (例:
./mychart、charts/mychart)。 相対パスはhelmfile.yamlのあるディレクトリ起点で解決します。 - OCI チャート参照 (例:
oci://public.ecr.aws/karpenter/karpenter-crd)。versionを指定し、helm registry client 経由で pull します。 - リポジトリ alias 形式 (
<alias>/<chart>、例:argo-cd/argo-cd)。<alias>がrepositories:で宣言された名前と一致する場合、そのurl(HTTP(S) or OCI) からversionの chart を pull します (helm repo addは不要)。<alias>が未宣言の場合は従来どおりローカル 相対パスとして解決します。
- ローカルチャートへの相対パス (例:
valuesmerges value file paths and inline maps in order, and finally mergesextraValueFilesas an override.
helmfile 本体の以下の機能は 未対応 です: environments / bases / release 間の needs / hooks / --selector 等。これらが必要な場合は helmfile でレンダリングした結果を type: kustomize などで取り込んでください。 ただしテンプレート内の {{ .Environment.Name }} は参照でき、tazuna の -e/--environment フラグの値が注入されます (未指定時は "default")。
Specific Fields
Written inside the manifests[].helmfile object.
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
vars | map<string, HelmFileVar> | - | {} | Variables passed to helmfile. See vars for details. |
includeCRDs | bool | - | false | Passes the equivalent of --include-crds to helmfile template. |
defaultNamespace | string | - | "" | The namespace assigned to rendered resources whose metadata.namespace is unset. |
extraValueFiles | [string] | - | [] | Additional --values files passed to helmfile template. |
wait | bool | - | false | When true, wait after Apply until the target resources become Ready. See wait behavior for details. |
timeoutSeconds | int | - | 0 | Maximum wait seconds for wait. With 0, 300 seconds (5 minutes) is used internally. |
kubeVersion | string | - | "" | 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.
- Retrieve the value according to each var’s
from(env/static/op). - If a
tazuna.hint.yamlis 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
| Field | Type | Required | Description |
|---|---|---|---|
from | string | Yes | Where the value is retrieved from. One of env / static / op. |
env | string | Conditional (*) | Required when from: env. The name of the environment variable to reference. |
static | string | Conditional (*) | Used when from: static. A scalar value. |
staticSlice | [string] | Conditional (*) | Used when from: static. A slice value. |
staticMap | map<string, string> | Conditional (*) | Used when from: static. A map value. |
op | OnePasswordVaultSelector | Conditional (*) | 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
| Field | Type | Required | Description |
|---|---|---|---|
key | string | Yes | Whether to reference the field by id or label. Either id or label. |
vault | string | Yes | 1Password vault name. |
item | string | Yes | 1Password item name. |
field | string | Yes | Field 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:
| Kind | Ready condition |
|---|---|
Deployment | Immediately Ready if spec.replicas == 0. Otherwise: status.readyReplicas == status.replicas AND status.availableReplicas == status.replicas AND status.replicas > 0 |
StatefulSet | Immediately Ready if spec.replicas == 0. Otherwise: status.readyReplicas == status.replicas AND status.replicas > 0 |
DaemonSet | status.numberReady == status.desiredNumberScheduled AND status.desiredNumberScheduled > 0 |
Pod | status.phase == "Running" AND Ready condition is True |
| Others | Treated 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
| Operation | Internal processing |
|---|---|
Build | Returns the YAML result of helm’s in-memory render. |
Apply | Convert the render result to unstructured form, supplement defaultNamespace, and Server-Side Apply in order. If wait is true, wait for Ready. |
Destroy | Convert 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: Platform
item: cert-manager
field: cloudflare-api-token
extraLabels:
from: static
staticMap:
managed-by: tazuna
tier: platform
Related
- helmfile.vars constraints:
tazuna.hint.yamlschema - Terminology: helmfile / Helm / 1Password