TerraformとKubernetesの「危険な関係」を断ち切る:ハイブリッドIaCの限界と正しい設計思想
こんにちは。インフラの深淵を覗き続けてきたエンジニアです。
今日は、多くの現場が陥る「TerraformでK8sリソースを全部管理しようとして地獄を見る」という罠について、その突破口を伝授します。
Terraformで`helm_release`リソースを使い始めたとき、皆さんはこう思うはずです。「これでインフラもアプリも一元管理できる!完璧だ!」と。しかし、それは中規模以上のシステムでは「崩壊へのカウントダウン」の始まりに過ぎません。
なぜか?Terraformは「リソースの静的な状態」を管理するのに長けていますが、Kubernetesの動的な振る舞い(オートスケーリングやコントローラーによる状態変更)とは本質的に相性が悪いからです。
—
1. なぜ「TerraformでHelm管理」は限界を迎えるのか
`helm_release`リソースは便利ですが、以下の「3つの壁」に必ずぶつかります。
1. 状態の不整合: Terraform外で誰かが`kubectl`でリソースをいじった瞬間、TerraformのPlanと実態が乖離し、次回の適用で「破壊的な修正」が走るリスクがあります。
2. CRD更新のジレンマ: Kubernetesのカスタムリソース(CRD)を管理しようとすると、TerraformのプロバイダーがCRDを認識する前にリソースを作ろうとしてエラーになります。
3. デプロイサイクルの乖離: インフラ(Terraform)の適用と、アプリケーションのデプロイ(Helm)は、本来ライフサイクルが別物です。これらを無理やり結合すると、CI/CDパイプラインが巨大化し、詰まります。
突破口:役割の明確化
- Terraform: クラウド・インフラ(VPC, RDS, EKSクラスター自体)を管理する。
- GitOps (ArgoCD等): K8s内のアプリケーション(Deployment, Service, CRD)を管理する。
Terraformは「家(Kubernetesクラスター)」を作り、ArgoCDに「家具(アプリケーション)」の配置を任せる。これが現代のハイブリッドIaCの解です。
—
2. HelloWorld:Terraform × ArgoCD の最強セットアップ
まずは、Terraformで「ArgoCDが住むための環境」を整えるところから始めましょう。
手順1: TerraformでのEKSクラスター作成(最小構成)
まずはプロバイダーの設定です。`main.tf`を用意します。
provider “kubernetes” {
# EKSの認証情報を動的に取得する設計
host = module.eks.cluster_endpoint
cluster_ca_certificate = base64decode(module.eks.cluster_certificate_authority_data)
exec {
api_version = “client.authentication.k8s.io/v1beta1”
command = “aws”
args = [“eks”, “get-token”, “–cluster-name”, module.eks.cluster_name]
}
}
ArgoCDをインストールするだけの最小Helm設定
resource “helm_release” “argocd” {
name = “argo-cd”
repository = “https://argoproj.github.io/argo-helm”
chart = “argo-cd”
namespace = “argocd”
create_namespace = true
# ここで重要なのは「必要最低限の管理」に留めること
values = [
“${file(“values/argocd.yaml”)}”
]
}
手順2: 動作確認の「Hello World」
ここでは、あえてTerraformでアプリをデプロイせず、ArgoCDに任せるための「Applicationリソース」を定義します。
argocd-app.yaml (GitOpsの定義ファイル)
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: my-app
namespace: argocd
spec:
destination:
server: https://kubernetes.default.svc
namespace: default
project: default
source:
repoURL: https://github.com/your-org/your-app-repo
targetRevision: HEAD
path: k8s/base # ここにDeploymentやServiceを置く
—
3. プロの視点:なぜこれが「楽」なのか
この構成をマスターすると、何が変わるのでしょうか?
- 冪等性(べきとうせい)の確保: Terraformは「インフラが正しく存在しているか」だけを監視します。アプリケーションの更新でTerraformを叩く必要はゼロになります。
- 開発者の自律性: 開発者は`git push`するだけでアプリケーションを更新できます。インフラチームのTerraformの権限を待つ必要はもうありません。
- ロールバックの高速化: 万が一障害が起きても、Gitのコミットを一つ戻すだけで、ArgoCDが即座に同期して元通りにしてくれます。
最後に
「すべてのツールをTerraformで管理したい」という誘惑は、エンジニアとして非常に理解できます。しかし、「管理できること」と「管理すべきこと」は違います。
Terraformでインフラの骨格を作り、GitOpsでアプリケーションの血を通わせる。この境界線を引けるようになることが、中級者から「真のインフラエンジニア」へ脱皮する第一歩です。
まずは、小さなクラスターでこの分離を試してみてください。毎日の「Terraformがクラッシュして復旧できない」という悪夢から、確実に解放されるはずですよ。