Skip to content

Package Values

Package Values provide a familiar way to define and reusable configuration data in your Zarf packages. Unlike the legacy Variables and Constants system that uses string substitution with ###ZARF_VAR_### syntax, Package Values uses Go templates with access to structured and typed data, go’s templating engine, and custom functions like those offered by Sprig.

Package Values allow you to:

  • Define structured configuration data in separate YAML files similar to Helm’s values files
  • Use Go template syntax ({{ .Values.key }}) for interpolation
  • Access nested values with dot notation
  • Leverage Go’s templating engine for advanced transformations and use functions like Sprig
  • Directly map Zarf package values to Helm chart values
  • Maintain clean separation between configuration and deployment logic

Values are defined in YAML files and are declared in your zarf.yaml package configuration:

zarf.yaml
kind: ZarfPackageConfig
metadata:
name: my-package
values:
files:
- values.yaml
- overrides.yaml
schema: values-schema.json # Optional JSON schema for validation

The values files contain structured YAML data:

values/values.yaml
site:
name: "My Application"
organization: "MyOrg"
styles: |
body { font-family: sans-serif; }
app:
environment: "production"
replicas: 3
features:
- "templating"
- "sprig-functions"
ports: [80, 443, 8080]
database:
host: "postgres.local"
port: 5432

Multiple values files are merged in order, with later files taking precedence.

Optionally provide a JSON schema to validate user-provided values:

zarf.yaml
values:
files:
- values.yaml
schema: values-schema.json
{
"$schema": "http://json-schema.org/draft-07/schema#",
"type": "object",
"properties": {
"app": {
"type": "object",
"properties": {
"replicas": {
"type": "integer",
"minimum": 1,
"maximum": 10
},
"environment": {
"type": "string",
"enum": ["development", "staging", "production"]
}
},
"required": ["replicas", "environment"]
}
}
}

The schema validates values during deployment, helping catch configuration errors early.

Values are accessed in templates through the .Values template object. See the Templating Reference for details on all available template objects (.Values, .Metadata, .Build, etc.).

Enable Go templating in manifest files by setting template: true:

components:
- name: my-component
manifests:
- name: app-manifests
template: true # Enables Go template processing
files:
- deployment.yaml
- service.yaml
- configmap.yaml

See the Templating Reference for complete details on template syntax, Sprig functions, and advanced usage.

Actions require explicit opt-in to templating. Set template: true on individual actions:

components:
- name: my-component
actions:
onCreate:
after:
- cmd: |
echo "Deploying {{ .Values.site.name }}"
echo "Environment: {{ .Values.app.environment }}"
template: true # Required to enable templating in actions

See the Templating Reference for details on templating in actions and why it requires opt-in.

Actions can dynamically set values using the setValues field, similar to setVariables:

components:
- name: dynamic-config
actions:
onDeploy:
after:
- cmd: echo "generated-password-123"
setValues:
- name: database.password
- cmd: kubectl get configmap app-config -o json
setValues:
- name: existing.config
type: json
- cmd: |
cat <<EOF
apiVersion: v1
kind: Config
settings:
debug: true
EOF
setValues:
- name: runtime.settings
type: yaml

The setValues field accepts:

  • name: The path where the value should be stored (e.g., database.password)
  • type: The format of the output - string (default), json, or yaml

Values set via setValues are available in subsequent actions and manifests within the same deployment.

Map Package Values to Helm chart values using sourcePath and targetPath:

components:
- name: helm-component
charts:
- name: my-chart
version: 1.0.0
namespace: my-app
localPath: charts/my-chart
values:
# Map .Values.app.name to .appName in the Helm chart
- sourcePath: ".app.name"
targetPath: ".appName"
# Map nested values
- sourcePath: ".app.replicas"
targetPath: ".replicaCount"
# Map to deeply nested chart values
- sourcePath: ".database.host"
targetPath: ".config.database.host"
# Multiple mappings to the same target - last one wins
- sourcePath: ".database.host"
targetPath: ".config.database.host"
- sourcePath: ".database.host_override"
targetPath: ".config.database.host" # Takes priority

You can map all Package Values directly to a Helm chart by using . for both sourcePath and targetPath:

components:
- name: helm-component
charts:
- name: my-chart
version: 1.0.0
namespace: my-app
localPath: charts/my-chart
values:
# Map all Package Values to the Helm chart's values
- sourcePath: "."
targetPath: "."

This approach passes your entire Package Values structure to the Helm chart, useful when your values file structure matches the chart’s expected values schema.

Example:

values/values.yaml
replicaCount: 3
image:
repository: nginx
tag: "1.21"
service:
type: ClusterIP
port: 80

With sourcePath: "." and targetPath: ".", all these values are passed directly to the Helm chart as if you had specified them in the chart’s values.yaml.

  • Mappings are evaluated in order from top to bottom
  • Later mappings to the same targetPath override earlier ones
  • Source paths reference your Package Values (.Values.*, .Metadata.*, etc.)
  • Target paths reference the Helm chart’s values.yaml structure
Field Type Description
targetPath * string
sourcePath * string
* Required field
 

Override or provide values when deploying or removing a package:

Provide individual values via command line:

Terminal window
# Set values at deploy time
zarf package deploy my-package.tar.zst \
--features="values=true" \
--set-values="app.environment=staging,app.replicas=5"
# Set values during removal
zarf package remove my-package \
--features="values=true" \
--set-values="app.environment=staging"

Provide entire values files with the -f or --values flag:

Terminal window
# Deploy with custom values file
zarf package deploy my-package.tar.zst \
--features="values=true" \
-f custom-values.yaml
# Multiple values files (later files override earlier ones)
zarf package deploy my-package.tar.zst \
--features="values=true" \
-f base-values.yaml \
-f override-values.yaml
# Also works with zarf dev deploy
zarf dev deploy \
--features="values=true" \
-f dev-values.yaml

Values can also be set via Viper configuration:

~/.zarf-config.yaml
package:
deploy:
values:
- custom-values.yaml
remove:
values:
- cleanup-values.yaml

Zarf’s :

Terminal window
# View the results of templates without having to deploy. This also works with command line and --set-values.
zarf dev inspect manifests --features="values=true"
# View helm values files mappings
zarf package inspect values-files my-package.tar.zst --features="values=true"

If you’re migrating from the legacy Variables/Constants system:

zarf.yaml
variables:
- name: DATABASE_USERNAME
default: "postgres"
constants:
- name: APP_VERSION
value: "1.0.0"
components:
- name: app
manifests:
- name: configmap
files:
- config.yaml
config.yaml
apiVersion: v1
kind: ConfigMap
data:
username: ###ZARF_VAR_DATABASE_USERNAME###
version: ###ZARF_CONST_APP_VERSION###
zarf.yaml
values:
files:
- values.yaml
components:
- name: app
manifests:
- name: configmap
template: true # Required for Go templates
files:
- config.yaml
values/values.yaml
database:
username: "postgres"
app:
version: "1.0.0"
config.yaml
apiVersion: v1
kind: ConfigMap
data:
username: {{ .Values.database.username }}
version: {{ .Values.app.version }}

Benefits of the new approach:

  • Structured, nested configuration
  • Type safety (numbers, booleans, arrays, objects)
  • Access to powerful template engine and function chaining
  • Better IDE support with standard YAML

See the values-templating example for a complete working example demonstrating:

  • File-based values configuration
  • Manifest templating with Go templates
  • Helm chart value mappings
  • Action templating
  • Sprig function usage