Ponz Dev Log

ゆるくてマイペースな開発日記

TerraformからHelmチャートをデプロイする

TerraformからHelmチャートをデプロイする方法のメモです。

複数の自作Helmチャートをデプロイする時にサブチャートを使いづらい場面に遭遇したので、 Terraformで複数のHelmチャートをまとめてデプロイしてみます。

環境情報

項目 バージョン
開発端末 macOS Monterey (バージョン 12.1)
Terraform v1.1.3
Helm Provider v2.4.1
Kubernetes v1.22.5

やること

この記事では簡単のために2つのHelmチャートで構成されるサブシステムをデプロイすることにします。 最終的なディレクトリ構成は以下を想定します。

$ tree -L 2 .

.
├── charts  # 自作のHelmチャートを格納する
│   ├── webapp
│   ├── db
├── helm_apps.tf
├── provider.tf
└── terraform.tfvars

セットアップ

早速やる。TerraformからHelmチャートをデプロイするためのHelm Providerをインストールします。 事前に接続先のクラスタの設定情報が書かれたconfigファイルが手元にあることを前提とします。

合わせて、デプロイ先のNamespaceも作成しておきます。

$ ls -1 ~/.kube
config

$ export KUBECONFIG=~/.kube/config

$ kubectl config current-context
kubernetes-admin-cluster.local@cluster.local

$ kubectl cluster-info
Kubernetes control plane is running at https://192.168.xxx.xxx:6443

$ kubectl create ns tf-helm-sample

以下のようにProviderの定義を記載した provider.tf ファイルを用意して terraform init でインストール。

### provider.tf ###

variable "config_path" {}
variable "config_context" {}

terraform {
  required_providers {
    helm = {
      source  = "hashicorp/helm"
      version = "2.4.1"
    }
  }
}

provider "helm" {
  kubernetes {
    config_path    = var.config_path
    config_context = var.config_context
  }
}

Helmチャートをデプロイ

続いてHelmチャートをデプロイするための設定値を定義します。 個別に渡されたローカルチャートを扱いたいので、helm_release リソースでローカルチャートのパスを指定します。

なるべくサブシステムごとに1つのファイルにまとめておくと見通しが良さそうです。

### helm_apps.tf ###

variable "namespace" {}

resource "helm_release" "release_my_webapp" {
  name      = "mywebapp"
  chart     = "./charts/webapp"
  namespace = var.namespace

  values = [
    "${file("./charts/myteam-values.yaml")}"
  ]

  set {
    name   = "image.tag"
    value  = "1.0.2"
  }
  depends_on = [
    helm_release.release_my_db
  ]
}

resource "helm_release" "release_my_db" {
  name      = "mydb"
  chart     = "./charts/db"
  namespace = var.namespace

  set {
    name   = "persistentVolume.storageClassName"
    value  = "longhorn"
  }
}

可変値は variable で変数定義したので、実際にデプロイするときに渡す値を terraform.tfvars に定義する。

### terraform.tfvars ###

config_path    = "~/.kube/config"
config_context = "kubernetes-admin-cluster.local@cluster.local"
namespace      = "tf-helm-sample"

最後に terraform apply でデプロイするだけ。

$ terraform apply

...

Plan: 2 to add, 0 to change, 0 to destroy.

Do you want to perform these actions?
  Terraform will perform the actions described above.
  Only 'yes' will be accepted to approve.

  Enter a value: yes

helm_release.release_my_db: Creating...
helm_release.release_my_db: Creation complete after 3s [id=mydb]
helm_release.release_my_webapp: Creating...
helm_release.release_my_webapp: Creation complete after 2s [id=mywebapp]

Apply complete! Resources: 2 added, 0 changed, 0 destroyed.

意外と簡単ですね。

以上。