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

**URL:** <https://community.replicated.com/t/why-you-should-create-helmchart-resources-for-your-helm-only-releases/1539>\
**Category:** How does it work?\
**Created:** [June 13, 2025, 3:38pm UTC](https://community.replicated.com/t/why-you-should-create-helmchart-resources-for-your-helm-only-releases/1539 "2025-06-13T15:38:19Z")\
**Posts on this page:** 1\
**Page:** 1

<div class="post-metadata">

**Author:** ![crdant](https://yyz2.discourse-cdn.com/flex030/user_avatar/community.replicated.com/crdant/32/576_2.png) [@crdant](https://community.replicated.com/u/crdant)\
**Post date:** [June 13, 2025, 3:38pm UTC](https://community.replicated.com/t/why-you-should-create-helmchart-resources-for-your-helm-only-releases/1539/1 "2025-06-13T15:38:19Z")

</div>

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](https://docs.replicated.com/reference/custom-resource-helmchart-v2),  
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.

```yaml
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](https://youtu.be/K2D6GRHkQ3w?feature=shared). 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.
