# HelmChart v1 (Deprecated)

:::important
The HelmChart custom resource `apiVersion: kots.io/v1beta1` is deprecated. For installations with Replicated KOTS v1.99.0 and later, use the HelmChart custom resource with `apiVersion: kots.io/v1beta2` instead. See [HelmChart v2](/reference/custom-resource-helmchart-v2).
:::

Each Helm chart `.tgz` archive in a release requires a unique HelmChart custom resource. The HelmChart custom resource provides the Replicated installer with the instructions needed to process and deploy the given Helm chart.

The HelmChart custom resource also generates a list of required images for the chart, which is necessary for the following use cases:
* Air gap installations with the Helm CLI or with a Replicated installer
* Online installations with a Replicated installer where the user will push images to a local image registry
* Online or air gap installations that use the [Security Center (Alpha)](/vendor/security-center-about) to scan and report on Helm chart images

For more information, see [About Distributing Helm Charts with KOTS](/vendor/helm-native-about).

## Example

The following is an example manifest file for the HelmChart v1 custom resource:

```yaml
apiVersion: kots.io/v1beta1
kind: HelmChart
metadata:
  name: samplechart
spec:
  # chart identifies a matching chart from a .tgz
  chart:
    name: samplechart
    chartVersion: 3.1.7
    releaseName: samplechart-release-1

  exclude: "repl{{ ConfigOptionEquals `include_chart` `include_chart_no`}}"

  # helmVersion identifies the Helm Version used to render the chart. Default is v3.
  helmVersion: v3

  # useHelmInstall identifies the kots.io/v1beta1 installation method
  useHelmInstall: true

  # weight determines the order that charts with "useHelmInstall: true" are applied, with lower weights first.
  weight: 42

  # helmUpgradeFlags specifies additional flags to pass to the `helm upgrade` command.
  helmUpgradeFlags:
    - --skip-crds
    - --no-hooks
    - --timeout
    - 1200s
    - --history-max=15

  # values are used in the customer environment, as a pre-render step
  # these values will be supplied to helm template
  values:
    postgresql:
      enabled: repl{{ ConfigOptionEquals `postgres_type` `embedded_postgres`}}

  optionalValues:
    - when: "repl{{ ConfigOptionEquals `postgres_type` `external_postgres`}}"
      recursiveMerge: false
      values:
        postgresql:
          postgresqlDatabase: "repl{{ if ConfigOptionEquals `postgres_type` `external_postgres`}}repl{{ ConfigOption `external_postgres_database`}}repl{{ end}}"
          postgresqlUsername: "repl{{ if ConfigOptionEquals `postgres_type` `external_postgres`}}repl{{ ConfigOption `external_postgres_username`}}repl{{ end}}"
          postgresqlHost: "repl{{ if ConfigOptionEquals `postgres_type` `external_postgres`}}repl{{ ConfigOption `external_postgres_host`}}repl{{ end}}"
          postgresqlPassword: "repl{{ if ConfigOptionEquals `postgres_type` `external_postgres`}}repl{{ ConfigOption `external_postgres_password`}}repl{{ end}}"
          postgresqlPort: "repl{{ if ConfigOptionEquals `postgres_type` `external_postgres`}}repl{{ ConfigOption `external_postgres_port`}}repl{{ end}}"

  # namespace allows for a chart to be installed in an alternate namespace to
  # the default
  namespace: samplechart-namespace

  # builder values provide a way to render the chart with all images
  # and manifests. this is used in Replicated to create `.airgap` packages
  builder:
    postgresql:
      enabled: true
```
## Properties
### chart

The `chart` key allows for a mapping between the data in this definition and the chart archive itself.
More than one `kind: HelmChart` can reference a single chart archive if you need different settings.

| Property | Description |
| --- | --- |
| `chart.name` | The name of the chart. This value must exactly match the `name` field from a `Chart.yaml` in a `.tgz` chart archive that is also included in the release. If the names do not match, then the installation can error or fail. |
| `chart.chartVersion` | The version of the chart. This value must match the `version` field from a `Chart.yaml` in a `.tgz` chart archive that is also included in the release. |
| `chart.releaseName` | <ChartReleaseName/> |

### helmVersion

Identifies the Helm Version used to render the chart. Acceptable values are `v2` or `v3`. `v3` is the default when no value is specified.

:::note
Support for Helm v2, including security patches, ended on November 13, 2020. If you specified `helmVersion: v2` in any HelmChart custom resources, update your references to v3. By default, KOTS uses Helm v3 to process all Helm charts.
:::

### useHelmInstall

Identifies the method that KOTS uses to install the Helm chart:
* `useHelmInstall: true`: KOTS uses Kustomize to modify the chart then repackages the resulting manifests to install. This was previously referred to as the _native Helm_ installation method.

* `useHelmInstall: false`: KOTS renders the Helm templates and deploys them as standard Kubernetes manifests using `kubectl apply`. This was previously referred to as the _Replicated Helm_ installation method.

  :::note
  You cannot migrate Helm charts in existing installations from the `useHelmInstall: false` installation method to a different method.
  If a user previously installed the Helm chart using `apiVersion: kots.io/v1beta1` and `useHelmInstall: false`, the installer won't attempt to use a different installation method.
  Instead, it displays the following error: `Deployment method for chart <chart_name> has changed`.

  To change the installation method from `useHelmInstall: false` to a different method, the user must reinstall your application in a new environment.
  :::

For more information about how KOTS deploys Helm charts when `useHelmInstall` is `true` or `false`, see [About Distributing Helm Charts with KOTS](/vendor/helm-native-about).

### weight

The `weight` field is _not_ supported for HelmChart custom resources with `useHelmInstall: false`.

Specifies the installation order of the Helm charts in the release. Charts are installed by weight in ascending order with lower weights first. Also determines the uninstall order, where charts are uninstalled by weight in descending order with higher weights first. **Supported values:** Positive or negative integers. **Default:** `0`

For installations with the Helm CLI, the Replicated Enterprise Portal uses the `weight` property to order the list of charts in the installation and update instructions. For more information, see [View Install and Update Instructions](/vendor/enterprise-portal-use#view-install-and-update-instructions) in _Access and Use the Enterprise Portal_.

### helmUpgradeFlags

The `helmUpgradeFlags` field is _not_ supported for HelmChart custom resources with `useHelmInstall: false`.

Specifies additional flags to pass to the `helm upgrade` command.
The Replicated installer runs `helm upgrade` for _all_ deployments, not just upgrades, by specifying the `--install` flag.

The Replicated installer passes these flags in addition to the flags it passes by default.
The values specified in this field take precedence if the installer already passes the same flag.

Template functions can parse the `helmUpgradeFlags` attribute. For more information, see [About Replicated template functions](/reference/template-functions-about).

For non-boolean flags that require an additional argument, such as `--timeout 1200s`, you must use an equal sign (`=`) or specify the additional argument separately in the array.

#### Example

```yaml
helmUpgradeFlags:
  - --timeout
  - 1200s
  - --history-max=15
```

### values

Use the `values` key to set or delete existing values in the Helm chart `values.yaml` file. Any values that you include in the `values` key must match values in the Helm chart `values.yaml`. For example, `spec.values.images.pullSecret` in the HelmChart custom resource matches `images.pullSecret` in the Helm chart `values.yaml`.

During installation or upgrade with KOTS, KOTS merges `values` with the Helm chart `values.yaml` in the chart archive. Only include values in the `values` key that you want to set or delete.

#### Example

```yaml
# HelmChart custom resource

apiVersion: kots.io/v1beta1
kind: HelmChart
metadata:
  name: samplechart
spec:
  values:
    postgresql:
      enabled: repl{{ ConfigOptionEquals `postgres_type` `embedded_postgres`}}
```

### exclude

When the installer processes your release, it excludes any Helm chart if the output of the `exclude` field is `true`.

Template functions can parse the `exclude` attribute. See [About Replicated template functions](template-functions-about).

### optionalValues

Use the `optionalValues` key to set values in the Helm chart `values.yaml` file when a conditional statement evaluates to true. For example, a customer including an optional application component might need Helm chart values related to that component.

`optionalValues` includes the following properties:

| Property | Description |
| --- | --- |
| `optionalValues.when` | Defines a conditional statement that must evaluate to true for the Helm chart to apply the values in `optionalValues.values`. The Replicated installer defers evaluation of the conditional in `optionalValues.when` until render time in the customer environment. |
| `optionalValues.recursiveMerge` | The `optionalValues.recursiveMerge` boolean defines how the Replicated installer merges `values` and `optionalValues`. When `optionalValues.recursiveMerge` is false, the top level keys in `optionalValues` override the top level keys in `values`. When `optionalValues.recursiveMerge` is true, the installer includes all keys from `values` and `optionalValues`. In the case of a conflict where there is a matching key in `optionalValues` and `values`, the Replicated installer uses the value of the key from `optionalValues`. By default, `optionalValues.recursiveMerge` is false. For an example, see [Recursive merge](#recursive-merge) on this page.|
| `optionalValues.values` | Array of key value pairs to set in the Helm chart when the specified condition is true. Supports static values and Replicated template functions. |

#### Examples

##### Set optional values with Replicated template functions

```yaml
# HelmChart custom resource

apiVersion: kots.io/v1beta1
kind: HelmChart
spec:
  optionalValues:
    - when: "repl{{ ConfigOptionEquals `mariadb_type` `external`}}"
      recursiveMerge: false
      values:
        externalDatabase:
          host: "repl{{ ConfigOption `external_db_host`}}"
          user: "repl{{ ConfigOption `external_db_user`}}"
          password: "repl{{ ConfigOption `external_db_password`}}"
          database: "repl{{ ConfigOption `external_db_database`}}"
          port: "repl{{ ConfigOption `external_ db_port`}}"
```

During installation, the Replicated installer renders the template functions and sets the `externalDatabase` values in the HelmChart `values.yaml` file _only_ when the user selects the `external` option for `mariadb_type`.

##### Recursive merge

The following HelmChart custom resource has both `values` and `optionalValues`:

```yaml
# HelmChart custom resource
apiVersion: kots.io/v1beta2
kind: HelmChart
spec:
  values:
    favorite:
      drink:
        hot: tea
        cold: soda
      dessert: ice cream
      day: saturday
  optionalValues:
    - when: '{{repl ConfigOptionEquals "example_config_option" "1" }}'
      recursiveMerge: false
      values:
        example_config_option:
          enabled: true
        favorite:
          drink:
            cold: lemonade
```

The associated Helm chart `values.yaml` file defines these key value pairs:

```yaml
# Helm chart values.yaml
favorite:
  drink:
    hot: coffee
    cold: soda
  dessert: pie
```
The associated Helm chart has the following `templates/configmap.yaml` file:

```yaml
# templates/configmap.yaml
apiVersion: v1
kind: ConfigMap
data:
  favorite_day: {{ .Values.favorite.day }}
  favorite_dessert: {{ .Values.favorite.dessert }}
  favorite_drink_cold: {{ .Values.favorite.drink.cold }}
  favorite_drink_hot: {{ .Values.favorite.drink.hot }}
```

When `recursiveMerge` is `false`, the ConfigMap for the deployed application includes the following key value pairs:

```yaml
# templates/configmap.yaml
apiVersion: v1
kind: ConfigMap
data:
  favorite_day: null
  favorite_dessert: pie
  favorite_drink_cold: lemonade
  favorite_drink_hot: coffee
```
When `recursiveMerge` is `true`, the ConfigMap for the deployed application includes the following key value pairs:

```yaml
# templates/configmap.yaml
apiVersion: v1
kind: ConfigMap
data:
  favorite_day: saturday
  favorite_dessert: ice cream
  favorite_drink_cold: lemonade
  favorite_drink_hot: tea
```

### namespace

The `namespace` key specifies an alternative namespace to install the Helm chart. By default, for Embedded Cluster v2 and KOTS existing cluster installations, KOTS installs the Helm chart in the same namespace as the Admin Console. For Embedded Cluster v3 installations, Embedded Cluster installs the chart in a `<chart-name>` namespace by default.

Template functions can parse the `namespace` attribute. For more information about template functions, see [About Replicated template functions](/reference/template-functions-about).

If you specify a namespace in the HelmChart `namespace` field, you must also include the same namespace in the [additionalNamespaces](custom-resource-application#additionalnamespaces) field of the Application custom resource.

### builder

The `builder` key contains the minimum Helm values required so that the output of `helm template` exposes all container images needed to install the chart in an air-gapped environment.

The Replicated Vendor Portal uses the Helm values in the `builder` key to run `helm template` on the chart. It then parses the output to generate a list of required images. 

The Vendor Portal then uses this list of images to do the following:
* Create the Helm CLI air gap installation instructions that are automatically made available to customers in the [Enterprise Portal](/vendor/enterprise-portal-about) or Download Portal. 
* Build the `.airgap` bundle for a release to support air gap installations with a Replicated installer (Embedded Cluster, KOTS, kURL).
* Determine which images to scan and report on in the [Security Center (Alpha)](/vendor/security-center-about).

You must configure the `builder` key to support the following installation types:

* Air gap installations with a Replicated installer (Embedded Cluster, KOTS, kURL)
* Air gap installations with the Helm CLI
* Online installations with KOTS or kURL where the user will push images to their own local image registry

#### Requirements

The `builder` key has the following requirements and recommendations:
* Replicated recommends that you include only the minimum Helm values in the `builder` key required to template the Helm chart with the correct image tags.
* Use only static, or _hardcoded_, values in the `builder` key. You can't use template functions in the `builder` key because values in the `builder` key are not rendered in a customer environment.
* Any `required` Helm values that need to be set to render the chart templates must have a value in the `builder` key. For more information about the Helm `required` function, see [Using the 'required' function](https://helm.sh/docs/howto/charts_tips_and_tricks/#using-the-required-function) in the Helm documentation.
* Specify `kubeVersion` in the root Helm chart. The Vendor Portal renders Helm charts with the minimum Kubernetes minor version that satisfies the `kubeVersion` in the root Helm chart. For example, if the chart specifies `kubeVersion: >=1.24.1`, then it's rendered with Kubernetes 1.25.0. If this fails or if a `kubeVersion` is not specified in the root Helm chart, then the Vendor Portal attempts to render the chart with each supported minor version of Kubernetes up to the latest version.

#### Example

Many applications include or exclude images based on a given condition.

For example, a Helm chart might include a conditional PostgreSQL Deployment, as shown in the following Helm template:

```yaml
{{- if .Values.postgresql.enabled }}
apiVersion: apps/v1
kind: Deployment
metadata:
  name: postgresql
  labels:
    app: postgresql
spec:
  selector:
    matchLabels:
      app: postgresql
  template:
    metadata:
      labels:
        app: postgresql
    spec:
      containers:
      - name: postgresql
        image: "postgres:10.17"
        ports:
        - name: postgresql
          containerPort: 80
# ...
{{- end }}
```

To include the `postgresql` image in the air gap bundle, add `postgresql.enabled` to the `builder` key of the HelmChart custom resource and set it to `true`:

```yaml
apiVersion: kots.io/v1beta2
kind: HelmChart
metadata:
  name: samplechart
spec:
  chart:
    name: samplechart
    chartVersion: 3.1.7
  values:
    postgresql:
      enabled: repl{{ ConfigOptionEquals "postgres_type" "embedded_postgres"}}
  builder:
    postgresql:
      enabled: true
```