What should helm package freeze into a chart, and what should the deploy job decide?
answer
- Frozen at package, chosen at deploy
- Where does the application version live
- One coordinate or two
- Version inflation destroys the signal
- Published versions are immutable
basics
~20 shelm package freezes templates, defaults, Chart.yaml version and appVersion, and vendored dependencies into one versioned tarball. The deploy job supplies what varies per target: release name, namespace and values. The real decision is which side owns the application version.
solid answer
~50 s`helm package` turns a directory into `payments-ledger-2.14.3.tgz`, and everything inside becomes part of one artifact named by a single SemVer string. Everything else has to be handed to `helm upgrade --install`. The genuine design choice is where the application's version lives. Stamp it in at package time with `--app-version` (and a chart version per build) and the deploy job's entire input is one string, which is auditable and works for anything that only accepts a chart version - at the cost of hundreds of near-identical chart versions and a chart version that no longer signals a chart change. Keep the chart slow-moving and pass the image tag at deploy, and the chart stays a shared component - at the cost of two coordinates to track per environment. Decide by who consumes the chart and by what the deploying system can express.
code
bash · 5 lineshelm package charts/payments-ledger \
--version 2.14.3 \
--app-version 1.9.44 \
-d dist/
# dist/payments-ledger-2.14.3.tgzgo deeper
Know what ends up inside the tarball: templates, values defaults, both Chart.yaml version fields, and dependencies. Everything else, including which namespace and which values file, is passed on the deploy command line.
Explain the two version fields and how packaging flags set them, and why environment-specific values belong outside the package so one artifact can reach several environments.
Argue the tradeoff from experience: what version inflation does to review signal, how one coordinate versus two changes the audit story, and why a published version must never be re-packaged.
Set the policy for the estate. Decide which charts are per-application artifacts and which are shared components, what the deploy record must capture, and how the choice serves whatever downstream system consumes the chart version.
Every chart pipeline eventually has to answer one question, and it is a design question rather than a Helm question: what is fixed at package time, and what is chosen at deploy time. `helm package charts/payments-ledger` produces `payments-ledger-2.14.3.tgz`. Everything in that tarball is frozen: the templates, the `values.yaml` defaults, the `Chart.yaml` `version` and `appVersion`, the `crds/` directory, and the dependencies vendored under `charts/`. The file's identity is one SemVer string. `--version` and `--app-version` let the packaging job override the two version fields without editing the working tree, and `-d` puts the result somewhere the rest of the pipeline can find it. Everything not in the tarball must be supplied by whoever runs `helm upgrade --install`: the release name, the namespace, the values files and any `--set` overrides. ## The real fork: where does the application version live? **School A - the chart is the application artifact.** The build produces an image, then packages a chart whose `appVersion` is that build's application version and whose chart version is minted per build. Deploying is one string. Rollback is deploying the previous chart version. An audit question - *what was running on 14 August?* - has a one-token answer. It also fits anything downstream that accepts a chart version and nothing else, which is the shape a controller handed a pinned chart version has: the whole desired state is expressible as one version. The cost is version inflation. Ship 137 builds in a quarter and you have 137 chart versions, most of which differ only in a tag. The chart version stops meaning *the chart changed* and starts meaning *something was built*, so a reviewer can no longer tell a template change from a routine release by looking at the number. Consumers who subscribe to your chart get churn. And an application rollback silently rolls the chart back too, which is convenient right up to the moment a template fix you needed goes with it. **School B - the chart is a slow-moving component.** The chart is versioned only when the chart changes, and the image tag arrives at deploy time as a value. This is the right default when one chart serves many services, when a platform team owns the chart and product teams own their releases, or when chart changes are rare compared to application releases. The cost is that the deploy is now two coordinates - chart version plus image tag - and both must be recorded together for an answer about what was running to be meaningful. Systems that can only express a chart version cannot express this deployment at all without a values file living somewhere else, which is exactly where teams lose track of what is deployed. ## Criteria I would decide on Who consumes the chart? One application, or seventeen services and an external team. A shared chart cannot be minted per build without imposing that churn on everyone. What is the ratio of change? If the chart changes monthly and the app changes daily, minting a chart version per app build destroys the signal in the chart version. Can the deploying system express two coordinates? If deployment happens by handing something a chart version, School A is not a preference, it is a requirement. What must an audit answer, and in how many tokens? One string is materially easier to record, compare across environments and reason about in an incident than a pair. Should an application rollback move the chart? School A makes that automatic; decide whether that is the semantics you want. ## The hybrid that usually wins Package on chart change, version the chart accordingly, and stamp `--app-version` at deploy-artifact time only if you are also minting a chart version - never let `appVersion` drift from what the tarball actually deploys, because a chart whose `appVersion` lies is worse than one that omits it. Whichever school you choose, two rules are not negotiable. Environment-specific facts - hostnames, replica counts, credentials - never go in the tarball; the values files own them, and a chart that bakes in a production hostname cannot be promoted anywhere. And a published version is immutable: never re-package different content under a version that has already shipped, because every downstream pin, every audit record and every rollback silently changes meaning if you do. ## What an interviewer is listening for Not a rule. They want you to name the tradeoff explicitly - artifact identity versus version signal, one coordinate versus two - tie it to who consumes the chart and what the deploying system can express, and be honest that the choice mostly determines how painful your audit and rollback stories are rather than whether the deploy works.
- What is the practical difference between a chart's version and its appVersion?`version` identifies the chart artifact, must be valid SemVer 2, and is what a caller pins with `--version` and what names the tarball. `appVersion` is a free-form string describing the application the chart deploys; nothing resolves against it and it usually appears in labels and in the APP VERSION column of `helm list`. Bumping `appVersion` alone still requires a new chart `version`, because the tarball's content changed.
- Your platform chart is used by seventeen services. Does School A still work?No. Minting a chart version per application build would force every consumer to absorb another team's release cadence, and the chart version would no longer signal that the chart itself changed. A shared chart should be versioned on chart changes, with each consumer supplying its own image tag and values. Reserve the artifact-per-build model for charts with exactly one consumer.
- Can a values file inside the chart carry an environment's hostname to save the deploy job an argument?It should not. Anything environment-specific in the tarball means the artifact is no longer promotable - the same version cannot go to staging and production - and it makes the packaged chart a per-environment build, which reintroduces the build/deploy blur you packaged to remove. Keep environment facts in values files supplied at deploy, and keep the tarball a single artifact that every environment can receive.
saying these in an interview costs you the question
- Baking environment hostnames into the packaged chart
- Re-packaging different content under a published version
- Treating appVersion as something callers can pin
- Minting a chart version per build on a shared chart
- Letting appVersion drift from what the chart deploys
- Assuming one model fits both app charts and platform charts