# HelmChart v2

This topic describes the KOTS HelmChart v2 custom resource.

For installations with a Replicated installer (Embedded Cluster, KOTS, kURL), a unique HelmChart custom resource is required for each Helm chart `.tgz` archive in a release. The primary purpose of the HelmChart custom resource is to provide the necessary instructions to the Replicated installer for processing and preparing the given Helm chart for deployment.

The HelmChart custom resource is also used to generate a list of required images for the chart, which is required 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

## Example

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

```yaml
apiVersion: kots.io/v1beta2
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`}}"

  # weight determines the order that charts 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 are 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}}"
  # adds backup labels to postgresql if the license supports snapshots
  - when: "repl{{ LicenseFieldValue `isSnapshotSupported` }}"
    recursiveMerge: true
    values:
      postgresql:
        commonLabels:
          kots.io/backup: velero
          kots.io/app-slug: my-app
        podLabels:
          kots.io/backup: velero
          kots.io/app-slug: my-app  

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

  # builder values render the chart with all images and manifests.
  # builder is used to create `.airgap` packages and to support end users
  # who use private registries
  builder:
    postgresql:
      enabled: true
```

## 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 different settings are needed.

### 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.

## releaseName

Specifies the release name to use when installing this instance of the Helm chart. Defaults to the chart name.

The release name must be unique across all charts deployed in the namespace. To deploy multiple instances of the same Helm chart in a release, you must add an additional HelmChart custom resource with a unique release name for each instance of the Helm chart.

Must be a valid Helm release name that matches regex `^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$` and is no longer than 53 characters.

## weight

Specifies the order in which Helm charts are installed within the application. Charts are installed by weight in ascending order, with lower weights installed first. **Supported values:** Positive or negative integers. **Default:** `0`

For installations with Helm, the Replicated Enterprise Portal uses the `weight` property to order the list of charts in the Helm installation and update instuctions. 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_.

For installations with Replicated Embedded Cluster or with KOTS in an existing cluster, `weight` determines the order in which KOTS applies the Helm chart. In KOTS v1.99.0 and later, `weight` also determines the order in which charts are uninstalled. Charts are uninstalled by weight in descending order, with higher weights uninstalled first. For more information about uninstalling applications, see [remove](kots-cli-remove) in _KOTS CLI_.

For more information, see [Orchestrate Resource Deployment](/vendor/orchestrating-resource-deployment).

## helmUpgradeFlags

Specifies additional flags to pass to the `helm upgrade` command for charts. These flags are passed in addition to any flags Replicated KOTS passes by default. The values specified here take precedence if KOTS already passes the same flag. The `helmUpgradeFlags` attribute can be parsed by template functions. For more information about template functions, see [About template function contexts](template-functions-about).

KOTS uses `helm upgrade` for _all_ deployments of an application, not just upgrades, by specifying the `--install` flag. 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
```

## exclude

The  attribute is a value for making optional charts. The `exclude` attribute can be parsed by template functions. 

When Replicated KOTS processes Helm charts, it excludes the entire chart if the output of the `exclude` field can be parsed as a boolean evaluating to `true`.

For more information about optional charts, template functions, and how KOTS processes Helm charts, see:

* [About Template Function Contexts](template-functions-about)
* [About Distributing Helm Charts with KOTS](/vendor/helm-native-about)

## values

The `values` key can be used 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, `values` is merged with the Helm chart `values.yaml` in the chart archive. Only include values in the `values` key that you want to set or delete.

For more information about using `values`, see [Setting Helm Chart Values with KOTS](/vendor/helm-optional-value-keys).

## optionalValues {#optionalvalues}

The `optionalValues` key can be used to set values in the Helm chart `values.yaml` file when a given conditional statement evaluates to true. For example, if a customer chooses to include an optional application component in their deployment, it might be necessary to include Helm chart values related to the optional component.

`optionalValues` includes the following properties:

* `optionalValues.when`: Defines a conditional statement using Replicated template functions. If `optionalValues.when` evaluates to true, then the values specified in `optionalValues` are set.

* `optionalValues.recursiveMerge`: Defines how `optionalValues` is merged with `values`.

* `optionalValues.values`: An array of key-value pairs.

For more information about using `optionalValues`, see [Setting Helm Chart Values with KOTS](/vendor/helm-optional-value-keys).

### optionalValues.when

The `optionalValues.when` field defines a conditional statement that must evaluate to true for the given values to be set. Evaluation of the conditional in the `optionalValues.when` field is deferred until render time in the customer environment. 

Use Replicated template functions to write the `optionalValues.when` conditional statement. The following example shows a conditional statement for selecting a database option on the Admin Console configuration screen:

```yaml
optionalValues:
  - when: repl{{ ConfigOptionEquals "postgres_type" "external_postgres"}}
```

For more information about using Replicated template functions, see [About Replicated Template Functions](/reference/template-functions-about).

### 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`. By default, `optionalValues.recursiveMerge` is set to false.

* When `optionalValues.recursiveMerge` is true, all keys from `values` and `optionalValues` are included. 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 of recursive and non-recursive merging, see [About Recursive Merge](/vendor/helm-optional-value-keys#recursive-merge).

### optionalValues.values

In the `optionalValues.values` key, include the values to set if the specified condition is met. The `optionalValues.values` key supports static values and Replicated template functions.

For example:

```yaml
  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`}}"
```

In this example, the Replicated installer renders the template functions and sets the `externalDatabase` values _only_ when the user selects the `external` option for the `mariadb_type` config option.

## namespace

The `namespace` key specifies an alternative namespace where Replicated KOTS installs the Helm chart. **Default:** The Helm chart is installed in the same namespace as the Admin Console. The `namespace` attribute can be parsed by template functions. For more information about template functions, see [About template function contexts](template-functions-about).


If you specify a namespace in the HelmChart `namespace` field, you must also include the same namespace in the `additionalNamespaces` field of the Application custom resource manifest file. KOTS creates the namespaces listed in the `additionalNamespaces` field during installation. For more information, see [additionalNamespaces](custom-resource-application#additionalnamespaces) in the _Application_ reference.

## builder

#### Overview

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 that you provide in the `builder` key to run `helm template` on the chart, then parses the output to generate a list of required images for the chart. 

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 Replicated Enterprise Portal or Download Portal. For more information, see [Install and Update with Helm in Air Gap Environments](/vendor/helm-install-airgap). 
* Build the `.airgap` bundle for a release to support air gap installations with a Replicated installer (Embedded Cluster, KOTS, kURL). For more information about how to build `.airgap` bundles, see [Package Air Gap Bundles for Helm Charts](/vendor/helm-packaging-airgap-bundles).
* Determine which images to scan and report on in the Security Center (Alpha). For more information about the Security Center, see [About the Security Center (Alpha)](/vendor/security-center-about).

The `builder` key is required 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 a Replicated installer where the user will push images to a 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 that are required to template the Helm chart with the correct image tags.
* Use only static, or _hardcoded_, values in the `builder` key. You cannot 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 supplied 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.

#### Example

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

```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 ensure that the `postgresql` image is included in the air gap bundle for the release, the `postgresql.enabled` value is added to the `builder` key of the HelmChart custom resource and is hardcoded 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
```