A small Go utility and package for rendering Harness-style Go templates using one or more YAML values files.
It supports:
- Rendering a single template file
- Rendering a directory of Kubernetes manifest templates
- Layering multiple values files (later files override earlier files)
- Optional interpolation of Harness placeholders for local testing
- Helpful template error output with file and line context
- Go 1.26+
Build the CLI:
make buildRun with the included examples:
./bin/harness-parser example-template.yaml example-values.yamlInstall into your GOPATH/bin:
make installThen run from anywhere (if GOPATH/bin is on your PATH):
harness-parser example-template.yaml example-values.yamlharness-parser [flags] <template-or-directory> [values-file ...]
<template-or-directory>: required path to a template file or directory[values-file ...]: optional one or more values YAML files, or a single values directory- Default values file:
example-values.yaml
Flags:
-env <name>: in values directory mode, select only values for the given env-interpolate-secrets: resolve Harness placeholders from values and fake secrets-secrets-file <path>: explicitly provide a fake secrets YAML file
When multiple values files are provided, they are merged in argument order. Later files override earlier files.
If a single values directory is provided, values files are auto-discovered (top-level only):
values.yamlfirst- then
values-*.yaml/values-*.ymlin lexical order secrets.yamland*.secrets.yamlare excluded from value layering
With -env <name> and values directory mode, selected files are:
values.yaml(always required)values-<env>.yaml(if present)values-<env>-*.yaml/values-<env>-*.ymlin lexical order
Example:
harness-parser ./templates ./values -env prodharness-parser ./templates/deployment.yaml ./test/values.yamlharness-parser ./templates ./test/values.yamlharness-parser ./templates ./valuesharness-parser ./templates/deployment.yaml ./values/base.yaml ./values/stage.yaml ./values/az1.yamlharness-parser -interpolate-secrets ./templates ./values/values.yaml ./values/values-stage.yaml ./values/values-stage-az1.yamlWith -interpolate-secrets, if -secrets-file is not provided, the parser auto-discovers adjacent files:
<values-basename>.secrets.yamlsecrets.yaml
Example fake secrets file:
team/path/db-password: fake-db-password
db-password: fake-db-password
pipeline.variables.tag: test-tag
service.name: encryption-service-testDirectory mode behavior:
- Top-level files only (non-recursive)
- Only
.yamland.ymlfiles are considered - File must contain both
apiVersion:andkind:to be treated as a Kubernetes manifest - Matching files are rendered in sorted filename order
- Processing continues when one file fails; failures are summarized at the end
Strict mode is enabled automatically when you pass custom values files.
Strict mode checks values for unresolved Harness expressions like <+...> and fails if any are found.
If -interpolate-secrets is enabled, interpolation runs before strict validation.
make helpCommon targets:
make build- build CLI intobin/harness-parsermake install- copy CLI intoGOPATH/binmake run TEMPLATE=<path> VALUES=<file>- run parser with make variablesmake deps- tidy dependenciesmake clean- remove build output
package main
import (
"fmt"
harnessparser "harness-parser"
)
func main() {
out, err := harnessparser.RenderFile("./templates/deployment.yaml", "./values.yaml")
if err != nil {
panic(err)
}
fmt.Println(out)
}Or with layered values:
package main
import (
"fmt"
harnessparser "harness-parser"
)
func main() {
out, err := harnessparser.RenderFileMulti(
"./templates/deployment.yaml",
[]string{"./values/base.yaml", "./values/stage.yaml", "./values/az1.yaml"},
)
if err != nil {
panic(err)
}
fmt.Println(out)
}example-template.yamlexample-values.yaml
Use these as a starting point for your own templates and values files.