Why you should create `HelmChart` resources for your Helm-only releases

When talking with vendors using Replicated, it sometimes comes up that they
should create HelmChart resources even when they only ever plan for their
customers to install with Helm. This recommendation often raises eyebrows.
From looking at the documentation for the HelmChart
resource
,
it appears to be primarily useful for Embedded Cluster and KOTS installations.

That used to be the right take, and in some cases, it’s still all you need
today. But there’s a hidden story here that makes the HelmChart resource
valuable even for Helm-only distributions—one that becomes critical the moment
your first customer needs to install in an air-gapped environment.

Most of the HelmChart resource configuration speaks directly to the Admin
Console. The chart dictionary specifies which chart to install and where to
place it. The values section provides template values that get passed to
your Helm chart during installation—essentially a template for the
values.yaml file. The optionalValues section handles conditional
configuration based on deployment scenarios, such as marking deployments as
air-gapped when a local registry is detected. This templating adapts the Admin
Console’s helm update commands to each customer’s environment, which isn’t
relevant for Helm-only installations.

apiVersion: kots.io/v1beta2
kind: HelmChart
metadata:
  name: slackernews
spec:
  chart:
    name: slackernews
    chartVersion: $VERSION
  namespace: slackernews

  values:
    postgres:
      enabled: true
      deploy_postgres: repl{{ ConfigOption "deploy_postgres" | ParseBool }}
    slack:
      botToken: repl{{ ConfigOption "slack_bot_token" | quote }}
      userToken: repl{{ ConfigOption "slack_user_token" | quote }}
    # ... more Admin Console configuration

  # This is the section that matters for Helm-only releases
  builder:
    postgres:
      password: this-is-not-used-but-needed-for-builder
      deploy_postgres: true
      enabled: true

But notice that builder section at the bottom. Unlike everything else, it’s
not intended for the Admin Console at all—it’s for the air gap builder. And
here’s where the hidden value emerges.

The air gap instruction problem

Replicated generates air gap installation instructions for customers who need
them for their Helm installations. These instructions are dynamic and built
from the list of images that your Helm chart requires. The air gap builder
discovers these images by running helm template on your chart and parsing
the output for container image references.

This approach works perfectly when your chart’s default values expose all the
images customers might need. But real-world Helm charts are more complex.
Images often hide behind conditional logic, only referenced when certain
features are enabled. Required values frequently have no defaults because you
want to force customers to set their own credentials or domain names. In these
scenarios, helm template either fails outright due to missing required
values, or it succeeds but only renders a subset of the possible images.

Consider a chart where PostgreSQL is optional but enabled by default, yet
requires a password with no default value. When the air gap builder runs helm template, it fails immediately. Your customers get air gap instructions with
zero images listed. Or imagine a chart where PostgreSQL is disabled by
default—the air gap instructions will omit the PostgreSQL image entirely,
leaving customers to discover this gap during their actual installation.

The builder solution

The builder section solves this problem by providing the air gap builder
with a complete set of values designed specifically for image discovery. These
values don’t need to represent realistic production configuration—they just
need to exercise every “code path” in your Helm chart that references images
your customers might need in an air-gapped environment.

In the Slackernews example above, the builder values ensure that PostgreSQL
is enabled and provide the necessary password to make helm template succeed.
This guarantees that the PostgreSQL image appears in the generated air gap
instructions, even though production customers will set their own passwords.

This is a small investment that pays significant dividends the moment your
first customer starts an air-gapped installation. They get complete, accurate
instructions instead of discovering missing images during deployment.

And remember, Air Gap: It’s Not Just for Air Gap
Anymore
. The customers who need
these comprehensive installation instructions aren’t just the ones in truly
disconnected environments—they’re also the ones in highly regulated,
security-conscious organizations where every container image needs to be
accounted for before it can be deployed.