Terraform + AWS EKS : la combinaison de référence pour Kubernetes en production

Amazon EKS (Elastic Kubernetes Service) est la plateforme Kubernetes managée d’AWS — le plan de contrôle (API server, etcd) est géré par AWS, vous gérez uniquement les nodes workers. En 2026, EKS est la solution Kubernetes la plus déployée en entreprise selon le rapport CNCF Annual Survey, devant GKE et AKS.

Terraform, avec le provider AWS HashiCorp, permet de provisionner et gérer un cluster EKS complet en code versionné dans Git. L’avantage du Terraform sur les alternatives (eksctl, CDK, CloudFormation) est la portabilité et la richesse de l’écosystème : modules Terraform EKS de la communauté, intégration avec Terragrunt pour la gestion multicompte, et plan/apply qui montrent précisément ce qui va changer avant application.

Ce guide crée un cluster EKS production-ready : VPC dédié avec subnets publics et privés, node groups managés en auto-scaling, IAM Roles for Service Accounts (IRSA) pour les permissions pod-level, addon Karpenter pour l’autoscaling avancé, et intégration CloudWatch Logs + Prometheus.

Architecture réseau : VPC et subnets EKS

L’architecture réseau d’un cluster EKS production-ready suit des patterns établis. Le VPC dédié (jamais le VPC default AWS) avec des plages CIDR adaptées à votre croissance future. Les subnets sont divisés en trois tiers : publics (load balancers, NAT Gateways), privés (nodes EKS), et isolés (RDS, ElastiCache).

Les nodes EKS doivent être dans des subnets privés — ils ne doivent pas avoir d’adresses IP publiques directement accessibles depuis Internet. Le trafic entrant passe par des load balancers dans les subnets publics, le trafic sortant par des NAT Gateways. Cette topologie est la baseline de sécurité réseau AWS.

Pour le sizing des subnets, planifiez large : EKS assigne une IP par pod (via VPC CNI), et un nœud EC2 de type m5.xlarge peut accueillir jusqu’à 58 pods selon les limites d’ENI AWS. Un subnet /24 (254 IPs) peut s’avérer trop petit pour un cluster qui scale. Préférez des /21 ou /22 pour les subnets de nodes.

Node Groups et Karpenter : stratégie d’autoscaling

EKS propose deux approches pour les nodes workers. Les Managed Node Groups (MNG) sont des groupes de nodes managés par AWS avec mise à jour automatique et monitoring intégré. Karpenter est un autoscaler de nodes plus flexible : il analyse les pods en attente et provisionne le type d’instance exact (parmi des milliers de types EC2) qui répond le mieux aux besoins.

La combinaison recommandée en 2026 : un MNG avec des instances On-Demand pour les workloads critiques (base de ~3 nodes m5.large permanents), et Karpenter pour le scale-out qui peut utiliser des instances Spot (jusqu’à 90 % moins chères) pour les workloads tolérant des interruptions.

Configurez des nodeAffinity et tolerations pour diriger les workloads vers les bons types de nodes : workloads critiques → On-Demand, jobs batch → Spot, GPU workloads → instances g5 gérées par Karpenter. Cette stratégie peut réduire la facture EC2 de 40 à 60 % sur un cluster de taille significative.

IAM IRSA : permissions Kubernetes sans credentials dans les pods

IRSA (IAM Roles for Service Accounts) est le mécanisme qui permet à des pods Kubernetes d’assumer des rôles IAM AWS sans stocker de credentials dans des variables d’environnement ou des secrets Kubernetes. Le pod reçoit un token JWT signé par EKS, qu’il présente à AWS STS pour obtenir des credentials temporaires.

Sans IRSA, les patterns dangereux sont courants : credentials AWS hardcodés dans les Dockerfiles, accessKeyId/secretAccessKey dans des ConfigMaps Kubernetes, ou pire, des node IAM roles trop permissifs qui donnent à tous les pods sur un node les mêmes droits AWS. IRSA permet le principe du moindre privilège au niveau pod.

Configurez un rôle IAM par service applicatif qui a besoin d’accès AWS (S3, DynamoDB, SQS…). Le rôle est lié au ServiceAccount Kubernetes via une Trust Policy qui vérifie l’identité EKS. Le pod assume ce rôle et n’a accès qu’aux ressources AWS explicitement autorisées dans la policy du rôle.

Monitoring et observabilité EKS

Un cluster EKS production-ready nécessite trois couches de monitoring. Les logs du plan de contrôle (API server, controller manager, scheduler) doivent être activés et envoyés à CloudWatch Logs. Ces logs sont critiques pour déboguer les problèmes au niveau cluster (pods qui ne démarrent pas, erreurs d’admission controllers).

Les métriques des nodes et pods (CPU, mémoire, réseau, disque) sont collectées par Prometheus (via kube-prometheus-stack, le Helm chart de référence) et visualisées dans Grafana. Les dashboards Kubernetes par défaut de Grafana (ceux du community board, IDs 315 et 6417) donnent une vue immédiate de la santé du cluster.

L’alerting doit couvrir : pods en état CrashLoopBackOff pendant plus de 5 minutes, utilisation CPU/mémoire des nodes >85 %, pods en état Pending depuis plus de 10 minutes (indique un problème de scaling ou de ressources), et erreurs 5xx sur les services en production. Ces alertes doivent aller vers PagerDuty pour les heures ouvrées et déclencher un appel pour les incidents critiques hors horaires.

Gestion des coûts EKS : rightsizing et optimisation

Un cluster EKS peut rapidement devenir coûteux sans gestion active des ressources. La première source de gaspillage : les resource requests trop élevées. Si tous vos pods demandent 1 CPU et 2 Go de RAM mais n’en utilisent réellement que 0,2 CPU et 0,5 Go, vous payez 5 fois plus que nécessaire.

Utilisez Goldilocks (un outil open source basé sur Vertical Pod Autoscaler en mode recommendation) pour analyser l’utilisation réelle de vos pods et recommander des resource requests optimisés. En appliquant ces recommandations, les équipes économisent typiquement 30 à 50 % sur leur facture de compute EKS.

Activez les Savings Plans AWS (engagement de consommation 1 ou 3 ans) pour les instances On-Demand de votre cluster : une réduction de 30 à 40 % sur le prix à la demande. Combiné avec l’utilisation de Spot pour les workloads éligibles, le coût total du cluster peut être réduit de 50 à 60 % par rapport à une utilisation naïve On-Demand sans gestion des coûts.

# Terraform — Cluster AWS EKS production-ready (extrait)
module "vpc" {
  source  = "terraform-aws-modules/vpc/aws"
  version = "~> 5.0"

  name = "eks-production-vpc"
  cidr = "10.0.0.0/16"

  azs             = ["eu-west-1a", "eu-west-1b", "eu-west-1c"]
  private_subnets = ["10.0.1.0/22", "10.0.5.0/22", "10.0.9.0/22"]
  public_subnets  = ["10.0.100.0/24", "10.0.101.0/24", "10.0.102.0/24"]

  enable_nat_gateway   = true
  single_nat_gateway   = false  # HA: 1 NAT par AZ
  enable_dns_hostnames = true

  tags = {
    "kubernetes.io/cluster/eks-production" = "shared"
    Environment = "production"
  }
  private_subnet_tags = {
    "kubernetes.io/role/internal-elb" = "1"
  }
}

module "eks" {
  source  = "terraform-aws-modules/eks/aws"
  version = "~> 20.0"

  cluster_name    = "eks-production"
  cluster_version = "1.29"

  cluster_endpoint_public_access  = false   # Accès API uniquement depuis VPC
  cluster_endpoint_private_access = true

  vpc_id     = module.vpc.vpc_id
  subnet_ids = module.vpc.private_subnets

  # Activer les logs du plan de contrôle
  cluster_enabled_log_types = ["api", "audit", "authenticator", "controllerManager", "scheduler"]

  eks_managed_node_groups = {
    system = {
      instance_types = ["m5.large"]
      min_size       = 3
      max_size       = 6
      desired_size   = 3

      labels = { role = "system" }
      taints = [{ key = "CriticalAddonsOnly", value = "true", effect = "NO_SCHEDULE" }]
    }
  }

  # IRSA activé par défaut avec le provider OIDC
  enable_irsa = true
}

Sources et références

W
WP Admin Lab

Architecte web full-stack. WordPress, performance, data et sécurité. Notes de terrain, tests reproductibles et retours d'expérience.