Optimisation des déploiements avec Terraform et Kubernetes

Introduction
Terraform et Kubernetes sont complémentaires : Terraform provisionne le cluster et son environnement cloud, Kubernetes orchestre les applications dessus. Mais la frontière entre les deux n'est pas toujours évidente. Où s'arrête Terraform et où commence Helm ? Après avoir géré cette combinaison sur de nombreux projets, voici les patterns qui fonctionnent.
Terraform pour le cluster, Helm pour les applications
La règle que j'applique systématiquement : Terraform gère tout ce qui est "sous" Kubernetes (VPC, subnets, cluster EKS/GKE, node groups, IAM roles, security groups) et les addons critiques (cert-manager, ingress-nginx, external-secrets, monitoring stack). Helm gère les applications métier. Chez F2R2, Terraform provisionnait le cluster EKS Fargate, les Fargate profiles, les IAM roles pour Workload Identity, et le VPC complet. Un module Terraform séparé déployait les Helm charts des addons via le provider helm. Les applications métier étaient déployées par ArgoCD, indépendamment de Terraform. Cette séparation est cruciale : modifier un addon Terraform ne doit pas impacter les applications, et inversement.
Le provider Kubernetes dans Terraform : quand l'utiliser
Le provider kubernetes de Terraform permet de créer des ressources Kubernetes directement. Je l'utilise avec parcimonie, uniquement pour les ressources "bootstrap" nécessaires avant qu'ArgoCD ne soit opérationnel : les namespaces, les ServiceAccounts, les ClusterRoles, et les secrets initiaux. Chez KNDS, le Terraform créait les namespaces avec leurs ResourceQuotas et LimitRanges, les RBAC bindings par équipe, et le secret du registry Docker. ArgoCD prenait ensuite le relais pour tout le reste. L'erreur classique est de gérer des Deployments Kubernetes dans Terraform : c'est possible mais inapproprié, car le cycle de vie d'un Deployment (mise à jour fréquente) ne correspond pas à celui d'une infrastructure Terraform (changement rare).
L'automatisation du provisionnement de cluster
Chez Earny SA, lors de la migration GCP vers AWS, j'ai automatisé le provisionnement complet d'un cluster de production en un seul terraform apply. Le module créait dans l'ordre : le VPC avec ses subnets publics et privés, le cluster EKS avec les managed node groups, les IAM roles pour les workloads, le cert-manager avec ClusterIssuer Let's Encrypt, l'ingress-nginx avec l'ALB AWS, l'External Secrets Operator connecté à AWS Secrets Manager, le Prometheus/Grafana stack, et ArgoCD configuré pour pointer vers le repository d'applications. Le tout prenait 25 minutes et produisait un cluster prêt à recevoir des applications. Ce même Terraform a servi à créer les 3 environnements (dev, staging, prod) avec des paramètres différents.
La gestion des node groups et de l'autoscaling
Terraform gère les node groups Kubernetes, ce qui a un impact direct sur les coûts et les performances. Chez Coopengo sur EKS, j'avais configuré 3 node groups via Terraform : un group "system" (instances t3.medium) pour les pods système (CoreDNS, kube-proxy, monitoring), un group "app" (instances m5.large) pour les applications, et un group "spot" (instances m5.large Spot) pour les workloads tolérants aux interruptions (tests, batch processing). Le cluster autoscaler ajustait le nombre de nodes dans chaque group. Les instances Spot du group "batch" coûtaient 70% de moins que les on-demand. Le Terraform définissait les min/max/desired de chaque group et les labels/taints associés, tandis que le HPA Kubernetes gérait le scaling des pods à l'intérieur de ces limites.
La gestion du cycle de vie et les mises à jour
La mise à jour d'un cluster Kubernetes via Terraform nécessite une planification soignée. Chez Metronome sur OVH, le passage d'une version Kubernetes à la suivante se faisait en modifiant la version dans le module Terraform, puis en appliquant. Le provider OVH gérait la mise à jour du control plane, puis le rolling update des node pools. J'appliquais toujours la stratégie "blue-green node pool" pour les mises à jour majeures : créer un nouveau node pool avec la nouvelle version, migrer les pods, puis supprimer l'ancien node pool. Cette approche évite les surprises : si la nouvelle version pose problème, l'ancien node pool est encore là. Le lifecycle create_before_destroy de Terraform est parfait pour ce pattern.
Conclusion
La combinaison Terraform et Kubernetes est puissante quand chaque outil est utilisé pour ce qu'il fait de mieux. Terraform pour l'infrastructure cloud et les addons, Helm/ArgoCD pour les applications. La séparation des responsabilités, l'automatisation du provisionnement, la gestion intelligente des node groups, et les mises à jour planifiées sont les piliers d'une infrastructure Kubernetes fiable et économique. Cette approche, déployée sur des dizaines de clusters, réduit le temps de provisionnement de jours à minutes et les incidents d'infrastructure de fréquents à rares.