Helmで複数の変数定義ファイルを指定する

# 概要

Helmチャートで使う変数は``values.yaml``に定義するのがデフォルトですが、環境によって値を変えたい場合に変数定義ファイル一つだと結構使いにくいです。（``templates``ディレクトリ内のマニフェストの中でif文などを入れて対応可能ですが、ソースの可読性が落ちます...）
そこで[公式ドキュメント](https://helm.sh/ja/docs/intro/using_helm/)を見てみると、``helm install``時のオプションで複数の変数定義ファイルを指定できるようなので、本記事で実際に試してみようと思います。

# とりあえず結論

以下のように、``-f``（または``--values``）オプションで複数の変数定義ファイルを指定可能です。
```
$ helm install [NAME] [CHART] -f [変数定義ファイル1] -f [変数定義ファイル2]
```

[公式ドキュメント](https://helm.sh/ja/docs/intro/using_helm/)からの抜粋
> --values (または -f): 上書きする YAML ファイルを指定します。 これは複数回指定でき、一番右のファイルが優先されます

では実際の挙動を確認していきましょう。

# 環境情報

Helmのバージョンはv3.10.2
```
$ helm version
version.BuildInfo{Version:"v3.10.2", GitCommit:"50f003e5ee8704ec937a756c646870227d7c8b58", GitTreeState:"clean", GoVersion:"go1.19.3"}
```

# ディレクトリ構成

以下のように、デフォルトの``values.yaml``に加えて``values``ディレクトリに環境毎の変数定義ファイルを格納しています。
```
.
├── Chart.yaml
├── templates
│   └── configmap.yaml
├── values               # 環境別の変数定義ファイルを格納
│   ├── kameda.yaml
│   ├── mochikichi.yaml
│   └── yatsuhashi.yaml
└── values.yaml          # デフォルトで使う変数を定義
```

# 共通に使うファイル内容

変数定義ファイル
```yaml:values.yaml
common:
  country: "Japan"

company:
  name: "default"
  prefecture: "Kyoto"
```

テンプレート内には値を確認する用のConfigMapを定義
```yaml:templates/configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: company-wagashi
data:
  country: {{ .Values.common.country }}
  {{- range $key, $value := .Values.company }}
  {{ $key }}: {{ $value }}
  {{- end }}
```

# 確認

まずは、デフォルトの状態で生成されるマニフェストを確認してみます。

:::note info
実際は``helm install``でクラスターに反映されますが、今回は``helm template``で生成マニフェストの中身のみ確認します。
:::

```yaml
$ helm template .
---
# Source: some-path/templates/configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: company-wagashi
data:
  country: Japan
  name: default
  prefecture: Kyoto
```
``values.yaml``の内容が素直に反映されています。

続いて、以下の``values/kameda.yaml``のファイルを引数指定してみます。

```yaml:values/kameda.yaml
company:
  name: "Kameda"
  prefecture: "Tokyo"
```
```yaml
$ helm template . -f values/kameda.yaml
---
# Source: some-path/templates/configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: company-wagashi
data:
  country: Japan
  name: Kameda
  prefecture: Tokyo
```
``name``と``prefecture``の内容が変わっていることを確認できました。

:::note info
``values.yaml``の中身は``-f``オプションで指定しなくても反映されます。
:::

次は以下のように、keyを新たに加えたもので確認してみます。

```yaml:values/mochikichi.yaml
company:
  name: "Mochikichi"
  prefecture: "Fukuoka"
  founding-date: "1929-09-01"
```

```yaml
$ helm template . -f values/mochikichi.yaml
---
# Source: some-path/templates/configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: company-wagashi
data:
  country: Japan
  founding-date: 1929-09-01
  name: Mochikichi
  prefecture: Fukuoka
```
``founding-date``のキーが新たに加わりました。

反対に、次のようにデフォルトで存在するキー``prefecture``を定義しない場合はどうなるでしょうか。

```yaml:values/yatsuhashi.yaml
company:
  name: "Yatsuhashi"
```

```yaml
$ helm template . -f values/yatsuhashi.yaml
---
# Source: some-path/templates/configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: company-wagashi
data:
  country: Japan
  name: Yatsuhashi
  prefecture: Kyoto
```
``values.yaml``の``prefecture``の値``Kyoto``が反映されました。

また複数ファイルを指定した場合は、[公式ドキュメント](https://helm.sh/ja/docs/intro/using_helm/)にも記載があるように一番右（=最後）に指定したファイルの内容が優先されることも確認できます。

```yaml
$ helm template . -f values/yatsuhashi.yaml -f values/kameda.yaml
---
# Source: some-path/templates/configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: company-wagashi
data:
  country: Japan
  name: Kameda
  prefecture: Tokyo
```

# おわりに

今回ご紹介したお話は、GitHubのissue（[Helm multiple environments best practices](https://github.com/helm/helm/issues/5257#issue-406447046)）でも話題になっており「よさそう！」と回答が出ていました