Helm を手運用やCIスクリプトで流すだけだと、値の出自や差分の可視化、ロールバックの一貫性に課題が残ります。Terraform の Helm Provider を使えば、Chart のリリースを IaC の一部として宣言的に管理できます。
本稿は HashiCorp 公式ドキュメントに基づく安定機能を中心に、プロダクション運用で外せない設計ポイントと、認定試験で問われやすい観点をまとめます。
Terraform の Helm Provider は、Helm CLI 相当の操作を Terraform の計画・適用フローに組み込み、helm_release リソースとして状態管理します。これにより、plan で差分を可視化し、apply でアップグレードを自動化できます。
Chart の取得元はリポジトリ URL もしくはローカルパスを指定できます。Provider は Kubernetes API への接続情報(kubeconfig または明示的な認証情報)を使って、Helm のインストールやアップグレードを実行します。
試験で狙われやすいのは、helm_release の主要属性(chart、version、namespace、values、set、atomic、wait、timeout、create_namespace など)と、それらが計画・適用・ロールバックにどう影響するかです。
| コンポーネント | 役割 | 代表設定/例 |
|---|---|---|
| helm_release | Chart リリースの宣言 | chart, version, namespace, values, set |
| Helm Provider | Helm 操作用バックエンド | kubernetes 接続情報, registry/repository 認証 |
| Terraform State | リリースの所望状態を保持 | plan/apply による差分・履歴管理 |
Terraform × Helm × Kubernetes の流れ
最小の helm_release 例
provider "helm" {
kubernetes {
config_path = var.kubeconfig_path
config_context = var.kube_context
}
}
resource "helm_release" "nginx" {
name = "nginx"
repository = "https://charts.bitnami.com/bitnami"
chart = "nginx"
version = "15.0.0"
namespace = "web"
create_namespace = true
values = [file("values-prod.yaml")]
wait = true
timeout = 600
atomic = true
}Helm Provider は内部で Kubernetes への接続を必要とします。一般的には kubeconfig を参照するか、明示的に host・token・CA を指定します。マルチクラスタ運用では provider の alias を用意し、モジュールに渡して使い分けるのが定石です。
CI では短命トークン(OIDC 経由の取得など)を環境変数から渡し、state には残さない運用が望まれます。手元では kubeconfig を読み、CI では明示指定という二層構えも実務でよく使われます。
| 認証手段 | 長所 | 注意点 |
|---|---|---|
| kubeconfig 参照 | ローカル開発が容易・既存ツールと親和 | CI ではファイル配布の管理が必要 |
| 明示指定(host+token+CA) | ファイル不要・短命トークンで安全性向上 | 変数の秘匿・ローテーションが前提 |
| In-cluster(将来の選択肢) | Pod 内から自然に接続 | 実行環境の制約と RBAC 設計が必要 |
代表的な接続パターン(デフォルトと alias)
# ローカル: kubeconfig を参照
provider "helm" {
kubernetes {
config_path = var.kubeconfig_path
config_context = var.kube_context
}
}
# CI: 明示的に接続(別クラスタに alias で接続)
provider "helm" {
alias = "eks"
kubernetes {
host = var.eks_api_endpoint
token = var.eks_bearer_token
cluster_ca_certificate = var.eks_cluster_ca
}
}
# モジュール側では providers で注入
module "payments_release" {
source = "./modules/release"
providers = { helm = helm.eks }
# ... module inputs ...
}Helm の値は values(YAML ファイル文字列の配列)と set(個別 key=value 指定)で与えられます。Terraform ではこれらの差分が plan に現れ、apply で Upgrade に反映されます。機微情報は set_sensitive を使うと plan 出力に値を出さずに管理できます。
大きな構成はテンプレート化した values ファイルを使い、環境ごとの差分は set で最小限にするのが保守しやすい設計です。配列を明示する場合は set_list を使う選択肢もあります。
| 手段 | 主な用途 | 長所 | 注意点 |
|---|---|---|---|
| values | 大規模設定・複数環境の共通値 | 読みやすく再利用しやすい | 配列のマージ挙動・ファイル分割方針が必要 |
| set | 小さな差分・数値や bool の微調整 | 最小差分で明示的 | key の綴り間違いがそのまま差分に |
| set_sensitive | パスワード・トークン等の機微情報 | plan 出力に値を出さない | 参照やログに出さない運用徹底が必要 |
| set_list | 配列の上書き・指定 | 配列を安全に渡せる | 値の型・順序の管理が必要 |
実践例: values と set_sensitive の併用
locals {
values_file = templatefile("${path.module}/values-${var.env}.yaml", {
image_tag = var.image_tag
})
}
resource "helm_release" "app" {
name = "app"
repository = var.chart_repository
chart = var.chart_name
version = var.chart_version
namespace = var.namespace
values = [
local.values_file
]
set {
name = "replicaCount"
value = tostring(var.replicas)
}
set_sensitive {
name = "secrets.DB_PASSWORD"
value = var.db_password
}
wait = true
timeout = 900
atomic = true
}Terraform は helm_release の所望状態を state に保持し、plan で差分を検出します。手動で helm upgrade を実行するとドリフトが発生し、次の plan で差分として検知されます。運用では「変更は Terraform 経由」の原則を徹底するとドリフトを最小化できます。
アップグレードの安定性は wait=true と timeout の適切な設定が鍵です。atomic=true を有効にすると、失敗時に Helm のロールバックが走り、中途半端な状態を避けられます。
既存の Helm リリースを Terraform 管理に取り込む場合は import を使います。取り込み後はリソース宣言と実体の乖離がないか plan で確認します。
| 設定 | 目的 | 実務の目安/コメント |
|---|---|---|
| wait | リソースの安定化を待つ | 本番は true が基本。ジョブ/フックの挙動に注意 |
| timeout | 待機の上限時間 | 本番は 10〜20 分程度を上限に調整 |
| atomic | 失敗時に自動ロールバック | true 推奨。デバッグ時はログと併用 |
既存リリースの取り込み(import)の流れ
# 1) 先にリソース宣言(最小)
resource "helm_release" "postgres" {
name = "postgres"
namespace = "data"
repository = "https://charts.bitnami.com/bitnami"
chart = "postgresql"
}
# 2) 既存の Helm リリースを import(namespace/name 形式の ID を利用可能)
# terraform import helm_release.postgres data/postgres
# 3) chart/version/values を合わせ、plan で差分を確認して整合を取る環境差分はモジュール入力と values テンプレートに閉じ込め、Chart バージョンは必ずピン留めします。これにより、plan の再現性が担保され、CI/CD での apply が安定します。
マルチクラスタ/マルチ名前空間は、プロジェクト単位でモジュールを分け、provider alias で対象クラスタを切り替えます。Workspace を使う場合でも、明示的な var env で可読性を確保しましょう。
| 分割単位 | スコープ | ベネフィット |
|---|---|---|
| チャートごとのモジュール | アプリ/ミドルウェア単位 | 責務分離・オーナーシップ明確化 |
| 名前空間ごとのスタック | 権限/隔離境界 | RBAC 設計と整合 |
| クラスタごとのプロジェクト | 耐障害/リージョン | 障害ドメイン分離・リスク低減 |
モジュール構成と provider alias の注入
# ルート側
provider "helm" {
alias = "prod"
kubernetes {
host = var.prod_host
token = var.prod_token
cluster_ca_certificate = var.prod_ca
}
}
module "orders" {
source = "./modules/release"
providers = { helm = helm.prod }
name = "orders"
namespace = "app"
chart_repository= "oci://registry.example.com/helm"
chart_name = "orders"
chart_version = "1.2.3"
env = "prod"
}
# modules/release/main.tf(例)
resource "helm_release" "this" {
name = var.name
namespace = var.namespace
repository = var.chart_repository
chart = var.chart_name
version = var.chart_version
values = [templatefile("${path.module}/values-${var.env}.yaml", {})]
wait = true
timeout = 900
atomic = true
}秘密値は Terraform の sensitive 変数と helm_release の set_sensitive を組み合わせて扱います。これにより plan/apply の出力や state での露出を最小化できます。また、kubeconfig やトークンはリポジトリに置かず、短命な発行源から渡すのが安全です。
RBAC は最小権限の原則で、対象名前空間の操作権限に限定します。リポジトリの認証が必要な場合は、repository_username / repository_password などの認証パラメータを変数経由で渡します。
| リスク | 推奨策 | Terraform/Helm 側の機能 |
|---|---|---|
| 平文露出 | sensitive 変数・set_sensitive を使用 | variable.sensitive, set_sensitive |
| ログへの漏えい | 出力抑制・レビュー工程でのチェック | sensitive 値のマスキング |
| 認証情報の配布 | 短命トークンと権限最小化 | 明示的 provider 認証・RBAC |
機微情報の安全な受け渡し
variable "db_password" {
type = string
sensitive = true
}
resource "helm_release" "db" {
name = "db"
repository = "https://charts.bitnami.com/bitnami"
chart = "postgresql"
version = "12.6.0"
namespace = "data"
set_sensitive {
name = "global.postgresql.auth.postgresPassword"
value = var.db_password
}
wait = true
timeout = 1200
atomic = true
}Pro
問題 1
本番で PostgreSQL の Helm Chart を Terraform からデプロイします。データベースのパスワードを安全に渡し、terraform plan の出力に値を表示せず、かつ差分管理は維持したい。最も適切な方法はどれですか?
正解: A
set_sensitive は機微情報をマスクしつつ、差分管理に参加させられる。values や set の平文指定は露出リスクが高く、base64 も秘匿化ではない。
ローカルの Chart ディレクトリを使えますか?
はい。helm_release の chart にローカルパス(例: ./charts/app)を指定できます。repository は不要です。
既存の Helm リリースを Terraform 管理に移行する方法は?
まず対応する helm_release を宣言し、terraform import で取り込みます。ID はリリース名(名前空間を含める場合は namespace/name 形式)を指定できます。import 後に chart/version/values を合わせ、plan で乖離がないか確認してください。
認証が必要なリポジトリやレジストリの Chart を使うには?
helm_release に repository とともに repository_username / repository_password 等の認証情報を変数で渡します。機微情報は set_sensitive や sensitive 変数を使用し、plan 出力や state での露出を抑えてください。
NicheeLab編集部
データエンジニアリング・クラウド資格の専門家。Databricks・Snowflake等の認定資格を保有し、実務経験に基づいた問題作成・解説を行っています。NicheeLab運営。
Terraform HCL 構文の基礎:Block / Attribute / Expression を正しく使い分ける
Terraform Associate で頻出の HCL 構文を、ブロック・属性・式の3視点で整理。実務で迷いがちな書き...
Terraform Authoring & Ops Pro: 上位資格の範囲と対策
上位レベルを想定したTerraformの設計・運用ドメインを整理し、実務で通用する対策を提示。モジュール設計、ステート運...
Terraform Providers の基本: プラグイン型アーキテクチャを正しく使いこなす
Associate レベルで押さえるべき Provider の基礎、インストール、バージョニング、認証、エイリアス運用を...
Terraform Resourceブロック徹底ガイド: 最小単位のリソース定義
Associateレベルで押さえるべきResourceブロックの構造、依存関係、メタ引数、ライフサイクル制御を実務目線で...
Terraform Data Source徹底理解:既存リソースの参照で壊さず足す
Terraform Associate向けに、Data Sourceを用いた既存リソース参照の基本、選択基準、評価順序、...