Johnman.md

プログラミングのことや個人的なことを書きます。たぶん。

Helmfileを使ってHelm Chartにないリソースを作成・管理する

はじめに

Helmを使っていると、Helm Chartには存在しないリソースを追加で作りたいということがあります。

直近あった例は、ArgoCDをHelmで導入したいが、Secretの管理にはExternal Secretを使いたいというケースです。HelmはChartで定義されているリソースしか作れないので、ArgoCDのHelm Chartとは別にリソースを定義する必要があります。

ここで問題になってくるのがマニフェストの管理方法です。 ArgoCDのHelm Chartでは管理できないからといって全く別のところにマニフェストを置いてしまうと、ArgoCDで使うリソースなのに定義が離れてしまって構成が理解しづらくなります。

この記事では、Helmfileを使ってArgoCDのHelm Chartと追加リソースを一元的に管理する方法を紹介します。


Helm

HelmKubernetes用のパッケージマネージャです。

KubernetesではリソースをYAMLで定義(マニフェストと言います)して管理しますが、デフォルトではそれぞれのマニフェストを一元管理する仕組みがありません。そこで、Helm Chartとしてマニフェストをまとめることで、アプリケーション単位でのマニフェストの管理が行えるようになります。

たとえば、ArgoCDの動作に必要なリソースをすべてHelm Chartとしてまとめることで、ユーザは helm install コマンドを打つだけでArgoCDをKubernetesクラスタに導入することができます。

Helm Chartに含まれないリソースは作れない

Helmを導入することで、マニフェストの管理や公開が楽になることがわかりました。ですが、一点問題があります。それはHelm Chartで定義されたリソースしか管理することができないということです。

たとえば、ArgoCDでExternal Secretを使いたいと思ったとしても、ArgoCDのHelm ChartではExternal Secretが定義されていないので作成することができません。

ではどうやって管理すればいいでしょうか?

すぐに思いつくのはArgoCDとは別にリソースを作成することです。 Helmとは別にリソースを定義して kubectl apply などでクラスタへ反映します。

argocd
├── argocd-helm
└── externalsecret.yaml

しかし、この方法はクラスタへの反映方法がHelmとkubectlで別れてしまうので望ましくありません。

そこで使えるのがHelmfileです、

Helmfile

HelmfileはHelm Chartを宣言的に管理できるツールです。要は複数のHelm Chartをまとめて管理することができます。

このHelmfileでArgoCDと追加のリソースを管理することで、一元的にリソースを管理することができるようになります。

独自のHelm Chartを作成してHelmfileで管理する

まず、追加リソース用のHelm Chartを作ります。Helm Chartは helm create コマンドで作成することができます。

コマンド実行後、作成したいリソースのマニフェストを追加します。最終的には下記のような構成になっているはずです。Chartやディレクトリ名はargocd-miscとしています。

argocd-misc
├── Chart.yaml
├── templates
│   ├── NOTES.txt
│   ├── _helpers.tpl
│   └── externalsecret.yaml
└── values.yaml

HelmfileはHelm Chartをまとめて管理できるので、今作成したargocd-miscとArgoCDのHelm Chartを管理するような構成にすれば、晴れて両方を一つのHelmfileで管理することができます。

HelmfileでHelm Chartを管理するには helmfile.yaml を作成します。これをArgoCDとargocd-miscそれぞれに作成します。

ArgoCD

environments:
  "{{ .Environment.Name }}":
    values:
      - "{{ .Environment.Name }}-values.yaml"
repositories:
  - name: argo
    url: https://argoproj.github.io/argo-helm
releases:
  - name: argocd
    namespace: argocd
    chart: argo/argo-cd
    version: 4.5.3
    values:
      - values.yaml.gotmpl

argocd-misc

environments:
  "{{ .Environment.Name }}":
    values:
      - "{{ .Environment.Name }}-values.yaml"
releases:
  - name: argocd-misc
    namespace: argocd
    chart: ./chart
    version: 0.1.0
    values:
      - values.yaml.gotmpl

どちらもprd, stgなどの環境ごとにValueを変更できるように、values.yamlを定義しています。また、values.yaml.gotmplはHelmfileで使うことのできるvalueファイルのテンプレートです。

これらhelmfile.yamlとHelm Chartを下記のようなディレクトリ構成で配置します。

argo-cd
├── argocd
│   ├── helmfile.yaml
│   ├── prd-values.yaml
│   ├── stg-values.yaml
│   └── values.yaml.gotmpl
└── argocd-misc
    ├── chart
    │   ├── Chart.yaml
    │   ├── templates
    │   │   ├── NOTES.txt
    │   │   ├── _helpers.tpl
    │   │   └── externalsecret.yaml
    │   └── values.yaml
    ├── helmfile.yaml
    ├── prd-values.yaml
    ├── stg-values.yaml
    └── values.yaml.gotmpl

この時点ではまだそれぞれのHelm ChartをHelmfileで管理できるようになっただけです。さらに上の階層にhelmfile.yamlを定義することで、先ほど作成したhelmfileをhelmfileで管理します。

environments:
  "{{ .Environment.Name }}":

helmfiles:
  - path: ./argocd/helmfile.yaml
  - path: ./argocd-misc/helmfile.yaml

helmfile.yamlではhelmfileを指定して読み込むことができます。こうすることで、helmfile apply コマンド一発で両方のHelm Chartを反映でき、晴れて一つのHelmfileで管理できるようになりました。

最終的なディレクトリ構成は下記のようになります。

argo-cd
├── argocd
│   ├── helmfile.yaml
│   ├── prd-values.yaml
│   ├── stg-values.yaml
│   └── values.yaml.gotmpl
├── argocd-misc
│   ├── chart
│   │   ├── Chart.yaml
│   │   ├── templates
│   │   │   ├── NOTES.txt
│   │   │   ├── _helpers.tpl
│   │   │   └── externalsecret.yaml
│   │   └── values.yaml
│   ├── helmfile.yaml
│   ├── prd-values.yaml
│   ├── stg-values.yaml
│   └── values.yaml.gotmpl
└── helmfile.yaml

まとめ

HelmはKubernetesマニフェストを管理するパッケージマネージャでした。しかし、HelmはHelm Chartで定義したものしか作成することができません。

定義されていないリソースを作成するには、新たにHelm Chartを作成して、もとのHelm Chartと一緒にHelmfileで管理することで、一元的に管理することができるようになります。

たまに使いたいことが出てくるかもしれないので、お役に立てれば幸いです。