Pack capabilities in Helm charts
Two optional files add Pack capabilities to a Helm chart. pack-metadata.yaml defines outputs that a Pack can expose, and pack-migrations.yaml manages Pack-manifest changes during chart upgrades.
Both files are stored in the chart root beside Chart.yaml and values.yaml. They are not required to install a chart with Pack; only the corresponding feature is unavailable when a file is absent.
| File | Purpose |
|---|---|
pack-metadata.yaml | Defines exports calculated from values or read from Kubernetes resources |
pack-migrations.yaml | Converts the Pack version, vars, and values during a chart upgrade |
See Helm and Helm charts in Kubernetes for standard chart structure. This page covers only the contracts consumed directly by Pack Operator and kubit-cli.
Define exports with pack-metadata.yaml
The exports section in pack-metadata.yaml defines information that users or Kubit tools can read from a Pack. Common examples include the application version, final image, service endpoint, and operational values.
exports:
image_repository: '{{ values.image.repository }}'
image_tag: '{{ values.image.tag }}'
image: '{{ exports.image_repository }}:{{ exports.image_tag }}'
app_version:
value: '{{ exports.image_tag }}'
metric: true
status: true
endpoint:
value: '{{ metadata.name }}.{{ metadata.namespace }}:{{ values.service.port }}'
status: true
An export can be a scalar value or an object with value and additional options. Exports are rendered recursively, so an export such as image can refer to other exports in the same file.
Template context in metadata
Templates in pack-metadata.yaml use the same Jinja syntax as Pack values. These contexts are available:
| Context | Available data |
|---|---|
metadata | Pack name, namespace, labels, and annotations |
chart | Repository, chart name, version, and settings from spec.chart |
vars | Effective organization, project, and Pack variables |
values | Chart values.yaml merged with spec.values; Pack values override chart defaults |
exports | Other exports from the same file after recursive rendering |
When the entire value is one template expression, its data type is preserved. If a template is embedded in a larger string, the result is a string. Cyclic export references or references to undefined paths can cause a render error.
Export value sources
Each export gets its value from one of these sources:
| Source | Purpose |
|---|---|
value | A fixed or templated value |
secretKeyRef | Reads a key from a Secret in the Pack namespace |
configMapKeyRef | Reads a key from a ConfigMap in the Pack namespace |
genericRef | Reads a path from a named Kubernetes resource in the Pack namespace |
exports:
redis_password:
secretKeyRef:
name: '{{ metadata.name }}'
key: redis-password
sensitive: true
optional: false
config_mode:
configMapKeyRef:
name: '{{ metadata.name }}-config'
key: mode
service_cluster_ip:
genericRef:
apiVersion: v1
kind: Service
name: '{{ metadata.name }}'
valueFrom: spec.clusterIP
In genericRef, valueFrom is the path inside the resource. The resource name and path can be fixed or templated. The executing identity must have permission to read the target resource.
Export options
| Option | Default | Behavior |
|---|---|---|
metric | false | Publishes the export through Pack Operator metrics |
status | false | Stores the value in the Pack resource's status.exports |
sensitive | false | Marks the output as sensitive for consumers |
optional | true | Reports a value-read error without failing the complete export render |
With optional: false, a missing resource or key fails metadata rendering. By default, kubit pack exports reports export errors under __errors__.
The sensitive flag does not encrypt or hide a value. The dict and list formats in kubit-cli return this flag with the output, but access to the Pack, Secret, and command output must still be controlled. Do not put sensitive values in logs, pipelines, or Git.
kubit pack exports -f redis.pack.yaml \
--local-chartpath ./redis \
--output dict
See Read Pack exports with kubit-cli for output formats.
Migrate a Pack during a chart upgrade
The optional pack-migrations.yaml file defines Pack-manifest changes required when a chart version changes. Each migration is selected by repository name, chart name, and source version. It updates spec.chart.version to the target and can transform vars or values.
Pack Operator reads this file from the target chart. The target chart must therefore contain a complete migration chain from every supported older version. The file is not required for installation, but an incompatible values change can make choices in older Packs invalid.
See Migrate Packs between chart versions for version ranges, steps, tags, and migration testing.
Test a local chart with kubit-cli
The --local-chartpath option tests a local chart without changing the repository configured in the Pack. The test still needs a Pack manifest so metadata, vars, and values provide a realistic render context.
kubit helm-template -f redis.pack.yaml \
--local-chartpath ./redis
kubit helm-diff -f redis.pack.yaml \
--local-chartpath ./redis
kubit pack exports -f redis.pack.yaml \
--local-chartpath ./redis \
--output dict
kubit pack migrate -f redis.pack.yaml \
--local-chartpath ./redis
- Validate rendered Helm output with
helm-template. - Compare resource changes with the current Helm release using
helm-diff. - Check all exports, errors, and sensitive flags with
pack exports. - Run
pack migratefor every supported upgrade path using an old-version sample.
helm-upgrade also accepts a local chart, but it changes the Helm release directly. Do not use it as part of initial testing; read the direct Helm upgrade warning first.
Chart release checklist
- Run
helm-templatefor sample Packs. - Review resource changes with
helm-diff. - Test scalar, recursive, optional, and sensitive exports with
pack exports. - Keep access for
secretKeyRef,configMapKeyRef, andgenericRefrestricted. - Publish a
valuesstructure change only with a compatible migration and after running the migration test checklist.