Aller au contenu principal

Ressources

ECS ou EKS : choisir, puis migrer d'ECS vers EKS service par service, sans big bang

ECS vs EKS : critères de choix, tarifs et versions vérifiés, puis migration d'ECS vers EKS service par service, retour arrière et pièges Terraform.

L'équipe CTN Solutions · publié le · 25 min de lecture

Base d'expérience : Méthode et documentation officielle (guide EKS, modèles d'API et listes de prix AWS, documentation Kubernetes, Terraform, fournisseur Terraform AWS, modules terraform-aws-modules et contrôleur AWS Load Balancer) ; sans récit, donnée, configuration ni référence client.

Faits vérifiés sur les sources primaires le

Une équipe qui exploite ses conteneurs sur Amazon ECS peut en venir à se poser la question d'Amazon EKS : pour un opérateur qui n'existe que sur Kubernetes, pour un outillage GitOps ou pour une exigence de portabilité. La question mérite une réponse honnête, et « rester sur ECS » en fait partie. Si la réponse est EKS, le risque principal n'est pas Kubernetes : c'est la bascule de tous les services en une nuit, avec un retour arrière qui n'existe que sur le papier.

Faits datés

Les critères de décision viennent d'abord, puis une migration service par service, de l'inventaire au décommissionnement. Cette lecture est établie sur Amazon EKS (versions 1.34 à 1.37 en support standard), le fournisseur Terraform AWS 6.69.1 et les modules terraform-aws-modules/eks 21.26.0 et terraform-aws-modules/ecs 7.6.1 ; tarifs, calendrier et versions ont été revérifiés le , les autres sources citées le 7 octobre 2026.

Vérifié le

ECS, EKS ou rester simple : les critères de décision

Les deux services exécutent des conteneurs sur la même infrastructure AWS. Ce qui les sépare est le modèle d'exploitation : ce que l'équipe maintient, à quel rythme, et ce qu'elle obtient en échange.

ECS : un orchestrateur sans version à suivre

La liste de prix d'Amazon ECS ne comporte aucun frais d'orchestration : l'usage sur instances EC2 y est compté à 0 $, seuls le calcul et les ressources associées se paient. Le calcul vient de Fargate (facturé au vCPU, à la mémoire et au stockage éphémère), d'instances EC2 gérées par l'équipe, ou d'ECS Managed Instances : ECS gère des instances EC2 pour le compte de l'équipe, contre des frais de gestion par instance ajoutés au prix EC2, avec des types d'instance choisis par attributs, GPU compris.

L'API ECS ne comporte aucun paramètre de version de cluster, mais la maintenance existe : quand AWS doit appliquer une mise à jour de sécurité ou d'infrastructure, les tâches Fargate concernées sont arrêtées et remplacées, avec un préavis réglable à 0, 7 ou 14 jours (fargateTaskRetirementWaitPeriod). Un service maintient son nombre de tâches (desiredCount) et relance donc les tâches retirées ; une tâche lancée hors service n'a pas ce mécanisme.

EKS : un plan de contrôle Kubernetes et son calendrier

Amazon EKS facture chaque cluster 0,10 $ de l'heure tant que sa version de Kubernetes est en support standard, et 0,50 $ de plus en support étendu, soit 0,60 $ (tarifs publics de la région Paris) pour le niveau standard du plan de contrôle ; les niveaux provisionnés (XL et au-delà) sont facturés davantage. Une version mineure reste 14 mois en support standard après sa sortie sur EKS, puis 12 mois en support étendu ; ensuite, EKS met à jour le plan de contrôle d'office. Une mise à jour ne franchit qu'une version mineure et ne peut être ni suspendue ni arrêtée une fois lancée ; les modules (VPC CNI, CoreDNS, kube-proxy) et les nœuds suivent séparément. Un retour à la version précédente reste possible dans les 7 jours, sauf après une mise à jour d'office en fin de support étendu. Au , les versions 1.34 à 1.37 sont en support standard (la 1.37 y est entrée le 1er octobre 2026 ; la 1.34 le quitte le 2 décembre 2026) et les versions 1.31 à 1.33 en support étendu ; les échéances de fin 2026 et leur coût sont détaillés dans « Support étendu EKS et RDS : calendrier de fin 2026, tarifs et calcul de l'exposition ».

Côté nœuds, trois options :

  • Groupes de nœuds gérés, ou nœuds provisionnés par Karpenter, projet open source qui crée des nœuds pour les pods non planifiables et les retire quand ils ne servent plus. Pour un groupe de nœuds géré sur une AMI optimisée EKS, la console signale les mises à jour et les applique en un clic ; les déclencher reste à l'équipe.
  • EKS Auto Mode : AWS gère les instances (système, correctifs, durée de vie maximale de 21 jours), leur mise à l'échelle sur la base de Karpenter, les répartiteurs de charge et le stockage bloc, contre des frais de gestion par instance. L'équipe déclenche la montée de version du plan de contrôle ; Auto Mode renouvelle ensuite les nœuds en respectant les PodDisruptionBudgets.
  • Fargate pour EKS : un environnement isolé par pod, sans DaemonSet, conteneur privilégié, volume EBS ni EKS Pod Identity (les rôles IAM pour comptes de service, IRSA, restent la voie pour un rôle IAM), avec des cibles de type IP uniquement.

Ce que Kubernetes apporte, et ce qu'il coûte

Les apports sont réels quand l'équipe en a l'usage :

Le prix est tout aussi réel : des frais par cluster, une montée de version à suivre au rythme du calendrier, des composants de plus à maintenir (contrôleur de répartiteur de charge, pilote de secrets, collecte de journaux, nœuds) et des compétences à détenir à plusieurs. Pour une équipe réduite, ce dernier point peut peser plus que la facture ; « Platform engineering pour une scale-up : par où commencer sans sur-ingénierie » traite ce dimensionnement.

Tableau de décision

Critères de décision entre ECS, EKS avec groupes de nœuds gérés ou Karpenter, EKS Auto Mode et EKS sur Fargate
CritèreECS (Fargate, EC2 ou Managed Instances)EKS, groupes de nœuds gérés ou KarpenterEKS Auto ModeEKS sur Fargate
Frais fixes d'orchestrationAucun0,10 $ par heure et par cluster, 0,60 $ en support étenduIdem, plus frais de gestion par instanceIdem
Gestion des machinesAWS (Fargate, Managed Instances) ou équipe (EC2)Équipe (AMI, mises à jour), aidée de KarpenterAWS (21 jours au plus par nœud)AWS
Montées de versionAucune ; retraits de tâches FargatePlan de contrôle dans les 14 mois de support standard, puis modules et nœudsPlan de contrôle par l'équipe, nœuds par AWSPlan de contrôle par l'équipe
Agents par nœudSur EC2 : stratégie DAEMON ; sur Fargate : conteneurs annexesOuiOuiNon
Identité IAMRôle de tâchePod Identity ou IRSAPod Identity ou IRSAIRSA
Compétences à détenir à plusieursIAM, VPC, ECSKubernetes et gestion des nœudsKubernetesKubernetes et limites de Fargate
Bon choix quand (avis)Peu de services, ni opérateur ni GitOps, équipe réduitePlateforme partagée, agents et opérateurs, rythme de version tenableMêmes besoins, sans gérer de nœudsCharges isolées, sans agent ni stockage bloc

La dernière ligne est un avis, pas une règle. Rester sur ECS, ou passer d'EC2 à Fargate ou à Managed Instances pour ne plus gérer d'instances, peut être la décision la plus raisonnable quand aucun des apports ci-dessus n'est attendu.

Chiffrer le coût fixe sans fausse comparaison

Exemple fictif. Trois clusters EKS (production, préproduction, outillage) coûtent, sur un mois moyen de 730 heures, 3 × 730 × 0,10 $ = 219 $ de plan de contrôle en support standard, 1 314 $ en support étendu ; sur ECS, cette composante n'existe pas. Le coût du calcul dépend du remplissage des instances, des réservations et des Savings Plans : il se compare dans l'export de coûts, pas sur les pages de prix, comme le détaille « Coût facturé, coût amorti, crédits : réconcilier des montants AWS qui ne tombent jamais juste ».

Chiffrage fondé sur vos données

CTN Solutions ne publie aucun pourcentage d'économie type : les écarts dépendent des usages réels et des contrats en cours.

Inventorier ce que chaque service ECS fait sans le dire

Un service ECS porte bien plus qu'une image : identité IAM, secrets, nom de découverte, groupe cible, mise à l'échelle, journaux, parfois des tâches planifiées. La migration commence par une fiche par service qui recense ces éléments, leur équivalent côté EKS, et les bases, caches et files où le service écrit.

Correspondance ECS vers EKS

Correspondance entre les éléments d'un service ECS, leur équivalent EKS et le point de vigilance
Élément ECSÉquivalent EKSPoint de vigilance
Définition de tâche (image, CPU, mémoire, ports, variables)Deployment, Service, requêtes et limitesMême image, au même condensat (digest)
Rôle de tâche (ecs-tasks.amazonaws.com)EKS Pod Identity (pods.eks.amazonaws.com) ou IRSAPas de Pod Identity sur Fargate ; le rôle d'exécution ECS, qui sert à l'agent pour préparer la tâche, n'a pas d'équivalent direct
secrets et valueFrom, valeur injectée en variable d'environnementPilote CSI Secrets Store et fournisseur AWS (ASCP), secrets montés en fichiersMême entrée Secrets Manager des deux côtés, jamais une copie ; ASCP non pris en charge sur Fargate pour EKS
Service Connect ou Cloud MapService Kubernetes et DNS du clusterAucun des deux noms ne se résout de l'autre côté
Groupe cible ALB de type ipTargetGroupBinding vers un groupe cible dédiéUn groupe cible par plateforme
Application Auto Scaling (CPU, mémoire, ALBRequestCountPerTarget, métrique personnalisée)HorizontalPodAutoscaler ; Karpenter ou Auto Mode pour les nœudsLe HPA lit CPU et mémoire via Metrics Server ; au-delà, il exige un adaptateur de métriques
awslogs ou FireLensAgent de journaux en DaemonSet, par exemple Fluent BitMêmes destinations et même format, sinon les alertes deviennent aveugles
Tâches planifiées (EventBridge Scheduler)CronJobJamais actives des deux côtés à la fois
Migrations de schéma en tâche ponctuelleJob ou hook PreSync d'Argo CDUne seule plateforme les lance

Ce que Terraform ne voit pas

L'état Terraform décrit ce qui a été déclaré, pas ce qui existe. Une règle d'écoute ajoutée dans la console n'apparaît dans aucun plan, et Terraform ne la recréera pas si l'écouteur est remplacé. Ces commandes en lecture seule comparent les deux :

# Services ECS : définition de tâche, nombre de groupes cibles et de registres Cloud Map (hors Service Connect)
CLUSTER=production
for s in $(aws ecs list-services --cluster "$CLUSTER" --query 'serviceArns[]' --output text); do
  aws ecs describe-services --cluster "$CLUSTER" --services "$s" \
    --query 'services[0].[serviceName, taskDefinition, length(loadBalancers), length(serviceRegistries)]' \
    --output text
done

# Tâches planifiées déclarées dans EventBridge Scheduler
aws scheduler list-schedules --query 'Schedules[].[Name, State, Target.Arn]' --output text

# Règles d'écoute réelles, à rapprocher de l'état Terraform
aws elbv2 describe-rules --listener-arn "$LISTENER_ARN" --query 'Rules[].[Priority, RuleArn]' --output text
terraform state list | grep aws_lb_listener_rule

Tout objet présent dans AWS et absent de l'état reçoit un propriétaire et un bloc import (chapitre 5) avant la première bascule. Les planifications plus anciennes, créées comme règles EventBridge, se listent avec aws events list-rules.

Faire tourner ECS et EKS côte à côte

La cohabitation dure le temps de basculer tous les services et repose sur quatre règles, détaillées ci-dessous. Tout élément provisoire de la cohabitation reçoit une date de retrait.

Un groupe cible par plateforme, derrière la même règle

Le montage le plus simple garde un seul ALB et une règle par service, dont l'action forward répartit les requêtes entre deux groupes cibles pondérés créés par Terraform : ECS enregistre ses tâches dans le premier, une TargetGroupBinding du contrôleur AWS Load Balancer enregistre les pods dans le second. Deux groupes cibles, pas un : avec multiClusterTargetGroup à false (valeur par défaut), le contrôleur prend le contrôle complet du groupe cible et désenregistre toute cible absente du cluster, tâches ECS comprises.

resource "aws_lb_target_group" "api_eks" {
  name_prefix          = "apik-"
  port                 = 8080
  protocol             = "HTTP"
  target_type          = "ip" # adresses des pods
  vpc_id               = var.vpc_id
  deregistration_delay = 30   # à aligner sur l'arrêt gracieux des pods

  health_check {
    path    = "/healthz"
    matcher = "200"
  }

  lifecycle {
    create_before_destroy = true
  }
}
apiVersion: elbv2.k8s.aws/v1beta1
kind: TargetGroupBinding
metadata:
  name: api
  namespace: api
spec:
  serviceRef:
    name: api
    port: 8080
  targetGroupARN: "<ARN du groupe cible api_eks, sortie de la pile Terraform>"
  targetType: ip

Trois précisions :

  • Porte de disponibilité : le libellé elbv2.k8s.aws/pod-readiness-gate-inject: enabled sur l'espace de noms fait attendre qu'un nouveau pod soit sain dans le groupe cible avant d'arrêter l'ancien (cibles ip seulement).
  • EKS Auto Mode : la ressource passe en eks.amazonaws.com/v1, targetType devient obligatoire, le groupe cible porte l'étiquette eks:eks-cluster-name, et le contrôleur le supprime avec la TargetGroupBinding ou le cluster ; un groupe cible créé par Terraform aurait deux propriétaires, point à trancher avant la première bascule.
  • Bleu/vert natif d'ECS : ECS modifie lui-même la règle d'écoute de production qu'on lui confie, au moyen d'un rôle qui l'autorise à appeler les API Elastic Load Balancing ; les déploiements ECS du service sont gelés pendant sa bascule.

Mêmes identités, mêmes secrets

Pendant la cohabitation, les deux formes d'un même service doivent avoir exactement les mêmes droits : un seul rôle IAM par service, approuvé à la fois pour ECS et pour EKS Pod Identity, dont le principal ECS est retiré au décommissionnement.

data "aws_iam_policy_document" "api_trust" {
  statement {
    actions = ["sts:AssumeRole"]
    principals {
      type        = "Service"
      identifiers = ["ecs-tasks.amazonaws.com"]
    }
  }
  statement {
    actions = ["sts:AssumeRole", "sts:TagSession"]
    principals {
      type        = "Service"
      identifiers = ["pods.eks.amazonaws.com"]
    }
  }
}

resource "aws_iam_role" "api" {
  name               = "api"
  assume_role_policy = data.aws_iam_policy_document.api_trust.json
}

resource "aws_eks_pod_identity_association" "api" {
  cluster_name    = var.cluster_name
  namespace       = "api"
  service_account = "api"
  role_arn        = aws_iam_role.api.arn
}

Sur Fargate pour EKS, le second bloc devient une approbation IRSA. Pour un autre compte, Pod Identity enchaîne un rôle cible (target_role_arn), le rôle Pod Identity restant dans le compte du cluster ; ce cas sort du périmètre de cette lecture.

Les deux plateformes lisent la même entrée Secrets Manager. ECS injecte la valeur en variable d'environnement, fixée au lancement de la tâche : une rotation n'atteint les tâches qu'à leur remplacement. Changer un secret pendant la cohabitation impose donc de redéployer les deux côtés.

Une adresse stable entre services

Deux services qui s'appellent peuvent se retrouver de part et d'autre de la frontière ; or les noms Service Connect ne sont servis qu'aux tâches ECS du même espace de noms, et les noms en .svc.cluster.local ne se résolvent que dans le cluster. Avant la première bascule, chaque service appelé reçoit donc une adresse indépendante de la plateforme (ALB interne à règle pondérée, ou nom DNS privé dans Cloud Map ou Route 53, qu'ExternalDNS sait alimenter), et ses appelants y passent d'abord.

Aucune exécution en double

Le poids d'un ALB répartit des requêtes, pas les traitements qui démarrent seuls : pour chacun, une seule plateforme est active à la fois. Le CronJob est livré suspendu tant que la planification ECS tourne :

apiVersion: batch/v1
kind: CronJob
metadata:
  name: traitement-planifie
  namespace: api
spec:
  schedule: "0 3 * * *"
  timeZone: "Europe/Paris"
  suspend: true                 # tant que la planification ECS est active
  startingDeadlineSeconds: 600  # borne le rattrapage à la réactivation
  concurrencyPolicy: Forbid
  jobTemplate:
    spec:
      template:
        spec:
          serviceAccountName: api
          restartPolicy: Never
          containers:
            - name: traitement
              image: "<même image et même condensat que la tâche ECS>"

Pour basculer : désactiver la planification ECS (state = "DISABLED" sur aws_scheduler_schedule), vérifier qu'aucune tâche lancée par elle ne tourne encore, puis passer suspend à false. Sans startingDeadlineSeconds, les exécutions manquées partent dès la réactivation ; et un CronJob peut, dans certaines circonstances, créer deux Jobs pour une échéance : le traitement doit être idempotent.

Le consommateur de file EKS démarre à zéro réplique et prend le relais quand ECS descend à zéro, sauf idempotence prouvée et non supposée. Les migrations de schéma partent de la plateforme qui sert la version de référence du code.

Basculer service par service, revenir en arrière, décommissionner

L'ordre des services

Le premier service à basculer est sans état, bien observé, peu appelé par les autres, et sa panne serait visible et bornée. Ceux qui écrivent beaucoup, reçoivent des webhooks de partenaires ou portent des connexions longues passent en dernier. Deux services ne changent jamais de poids dans la même fenêtre : un incident doit pouvoir s'attribuer.

Déplacer les poids par paliers

Les poids d'une action forward vont de 0 à 999 et sont relatifs ; une seule variable suffit à les piloter :

variable "poids_eks" {
  type    = number
  default = 0
  validation {
    condition     = var.poids_eks >= 0 && var.poids_eks <= 100
    error_message = "Le poids EKS est compris entre 0 et 100."
  }
}

resource "aws_lb_listener_rule" "api" {
  listener_arn = aws_lb_listener.https.arn
  priority     = 100

  action {
    type = "forward"
    forward {
      target_group {
        arn    = aws_lb_target_group.api_ecs.arn
        weight = 100 - var.poids_eks
      }
      target_group {
        arn    = aws_lb_target_group.api_eks.arn
        weight = var.poids_eks
      }
    }
  }

  condition {
    host_header {
      values = ["api.example.com"]
    }
  }
}

Exemple fictif de progression : 0, 5, 25, 50 puis 100 % vers EKS, avec une durée d'observation fixée par l'équipe à chaque palier. La répartition se fait requête par requête ; pour une application à sessions, la persistance de groupe cible (bloc stickiness de l'action forward) garde un client sur le même groupe cible pendant la durée choisie. Le retour arrière ne s'attend pas du répartiteur : c'est une action préparée.

Avant le dernier palier, EKS est dimensionné pour porter seul la charge ; ECS, qui réduit ses tâches à mesure que son trafic baisse, garde une capacité minimale relevée pendant l'observation pour que le retour arrière reste immédiat.

Avec deux répartiteurs distincts, la pondération passe par Route 53 (poids de 0 à 255, trafic proportionnel au poids rapporté à la somme des poids), plus lente à inverser à cause du cache des résolveurs et des connexions ouvertes. Le TTL de l'enregistrement s'abaisse avant la fenêtre.

Le chemin d'écriture ne suit pas les poids

Le poids déplace les nouvelles requêtes HTTP, pas les connexions ouvertes, les workers, les tâches planifiées, ni les webhooks d'un partenaire qui a mis l'adresse en cache. Avant la fenêtre, il faut savoir quels chemins écrivent, lesquels restent actifs côté ECS, et comment le prouver. La base de données, elle, ne bouge pas : les deux versions du code doivent rester compatibles avec le même schéma pendant toute la cohabitation.

Critères de retour arrière

Signaux de retour arrière, où les lire et décision associée
SignalOù le lireDécision
5xx du groupe cible EKS au-dessus de la ligne de base ECSHTTPCode_Target_5XX_Count (dimensions TargetGroup, LoadBalancer)Poids EKS à 0
Latence au-delà du seuil sur la durée d'observationTargetResponseTime, traces applicativesPoids EKS à 0
Cibles EKS non sainesUnHealthyHostCount, état des podsPoids EKS à 0
Indicateur métier en écartTableaux de bord applicatifsPoids EKS à 0, puis analyse
Journaux ou métriques absents côté EKSPlateforme d'observabilitéPoids EKS à 0 : une bascule invisible ne se poursuit pas
Traitement unique exécuté deux foisJournaux des planifications et consommateursArrêt du côté fautif, examen des données

Les seuils se fixent avant la fenêtre, à partir de la ligne de base ECS. Le retour arrière est une commande préparée et testée (terraform apply -var 'poids_eks=0'), plus, si les planifications ont basculé, la réactivation de celle d'ECS et la suspension du CronJob.

Bascule d'un service par paliers, avec retour arrière

Le trafic d'un service passe d'ECS à EKS par paliers observés ; un critère atteint ramène le poids EKS à zéro, et le décommissionnement ne vient qu'après la fenêtre d'observation.

Schéma défilable horizontalement ; sa version textuelle complète suit.

Lire le schéma sous forme textuelle
  1. Service prêt sur EKS : groupe cible dédié, cibles saines, CronJobs suspendus.
  2. La règle de l'ALB envoie tout le trafic à ECS.
  3. Un palier augmente la part d'EKS, puis l'équipe observe pendant la durée fixée.
  4. Critère de retour arrière atteint : poids EKS à zéro, planifications ECS réactivées si besoin, analyse, puis reprise à l'étape 2.
  5. Sinon, tant que le trafic n'est pas entièrement sur EKS, un nouveau palier suit.
  6. Tout le trafic HTTP sur EKS : les chemins hors HTTP basculent (planifications, consommateurs, webhooks).
  7. Fenêtre d'observation, ECS à zéro tâche mais service conservé ; un critère atteint renvoie à l'étape 4.
  8. En fin de fenêtre, décommissionnement : groupe cible ECS retiré de la règle, service ECS et pile Terraform supprimés.
Modèle explicatif, sans donnée client, d'après la documentation des actions pondérées des répartiteurs AWS et du contrôleur AWS Load Balancer.

Liste de contrôle avant bascule

  • Fiche du service complète, chemins d'écriture compris.
  • terraform plan sans modification sur la pile socle ; rien hors état (règles, groupes de sécurité, DNS).
  • Groupe cible EKS dédié, de type ip, cibles saines ; multiClusterTargetGroup absent ou à false ; porte de disponibilité activée ; délai de désenregistrement aligné sur l'arrêt gracieux des pods.
  • Rôle IAM approuvé pour les deux principaux ; un appel réel à chaque service AWS utilisé réussi depuis un pod.
  • Même entrée Secrets Manager lue des deux côtés, à la même version.
  • Appelants internes passés sur l'adresse stable du service.
  • CronJobs suspendus, consommateurs EKS à zéro ou idempotence prouvée, migrations de schéma attribuées à une seule plateforme.
  • Journaux, métriques et alertes du service visibles côté EKS, dans les mêmes tableaux de bord.
  • Capacité EKS dimensionnée pour tout le trafic ; capacité minimale ECS relevée.
  • Seuils écrits ; commande de retour arrière testée hors production.
  • Déploiements ECS du service gelés ; décideur disponible.

Décommissionner, puis transmettre

Le décommissionnement commence quand le service tourne entièrement sur EKS depuis toute la fenêtre d'observation :

  1. ECS à zéro tâche, service conservé. Le module terraform-aws-modules/ecs ignore toujours desired_count : la mise à zéro passe par les capacités minimale et maximale d'Application Auto Scaling ramenées à 0 (ou, sans mise à l'échelle, par aws ecs update-service --desired-count 0) ; sinon la mise à l'échelle relance des tâches.
  2. Groupe cible ECS retiré de la règle, puis supprimé.
  3. Service, définitions de tâches, planifications et Cloud Map supprimés ; principal ecs-tasks.amazonaws.com retiré du rôle.
  4. Journaux ECS conservés selon la rétention prévue.
  5. Cluster ECS en dernier.

La migration n'est terminée que si l'équipe sait refaire seule les gestes suivants : monter de version EKS, faire tourner un secret, ajouter un service, revenir en arrière sur un déploiement Argo CD, chacun avec un runbook court exercé par une autre personne que son auteur. Le cadrage d'une telle migration, de l'inventaire à la transmission, est décrit sur la page Migration Kubernetes : avancer par vagues.

Les pièges Terraform de la cohabitation

Un propriétaire par ressource, et une pile socle

Pendant la cohabitation, la pile Terraform ECS, la pile Terraform EKS et le contrôleur AWS Load Balancer modifient des objets AWS ; chaque objet n'a qu'un propriétaire. Une pile « socle » porte l'ALB, les écouteurs, les règles pondérées, les deux groupes cibles de chaque service et les groupes de sécurité partagés ; la pile ECS ne porte plus que les services et leurs définitions de tâches ; la pile EKS, le cluster, ses nœuds et ses associations d'identité ; le dépôt GitOps, les TargetGroupBinding. Les ARN passent d'une pile à l'autre par des sorties ou des sources de données, jamais par copie. Décommissionner ECS revient alors à détruire une pile sans toucher au trafic.

Changer une ressource de pile : removed, puis import

Le bloc moved (Terraform 1.1 et plus) change l'adresse d'une ressource dans l'état de la configuration qui le porte ; il ne transfère rien vers une autre pile. Pour transférer un groupe cible de la pile ECS à la pile socle sans le détruire :

# Pile ECS : cesser de gérer la ressource sans la détruire (Terraform 1.7 et plus)
removed {
  from = aws_lb_target_group.api_ecs
  lifecycle {
    destroy = false
  }
}
# Pile socle : adopter la ressource existante (Terraform 1.5 et plus)
import {
  to = aws_lb_target_group.api_ecs
  id = "arn:aws:elasticloadbalancing:eu-west-3:111122223333:targetgroup/api-ecs/0123456789abcdef"
}

resource "aws_lb_target_group" "api_ecs" {
  # configuration identique à l'existant
}

L'ordre : geler les apply des deux piles, importer côté socle et obtenir un plan sans modification, puis appliquer le removed côté ECS en vérifiant que le plan annonce l'abandon de gestion sans destruction. terraform state rm ferait le même travail sans plan à relire ; la documentation Terraform recommande removed, plus sûr précisément parce qu'il se prévisualise.

Importer ce que la console a créé

Pour les règles, groupes de sécurité ou enregistrements créés à la main, terraform plan -generate-config-out=generated.tf écrit une configuration de départ à partir des blocs import (Terraform 1.5 et plus, fonction encore signalée comme expérimentale), et for_each sur import (1.7 et plus) traite une liste en une fois. La configuration générée se relit ligne à ligne : elle reproduit l'existant, y compris ce qui n'aurait pas dû exister.

ignore_changes : utile pour un compteur, dangereux pour une valeur

ignore_changes fait ignorer à Terraform, lorsqu'il planifie des mises à jour, les attributs listés ; ils ne comptent qu'à la création. Trois cas :

  • Légitime : desired_count d'un service ECS piloté par la mise à l'échelle.
  • Piège silencieux : un ignore_changes sur un attribut de valeur (paramètre, variable, valeur de configuration) fige cette valeur après la création ; toute modification ultérieure passe inaperçue au plan. Tout attribut ignoré se vérifie dans AWS avant la fenêtre.
  • Piège de module : avec ignore_task_definition_changes = true, le module ECS ignore aussi le bloc load_balancer du service.

Enfin, un retour arrière fait à la console serait annulé par le prochain apply : il passe par la variable de la bascule.

create_before_destroy et noms uniques

Remplacer un groupe cible encore attaché à une règle échoue si Terraform détruit avant de créer. create_before_destroy inverse l'ordre, mais deux objets du même nom ne coexistent pas, d'où name_prefix (6 caractères au plus) plutôt que name sur aws_lb_target_group. Sur un groupe de sécurité partagé entre piles, les règles en ligne (ingress, egress) et les ressources de règle séparées ne se mélangent pas, sous peine de conflits et de règles écrasées : chaque pile déclare ses propres aws_vpc_security_group_ingress_rule.

Versions du fournisseur et des modules

Au , la dernière version publiée du fournisseur AWS est la 6.69.1 ; le module terraform-aws-modules/eks 21.26.0 exige Terraform 1.5.7 et le fournisseur 6.59 au minimum, le module ECS 7.6.1 Terraform 1.5.7 et le fournisseur 6.41. Une pile restée sur un fournisseur 5.x monte donc d'abord de fournisseur, seule, avec un plan relu, avant tout ajout lié à EKS. La version 21 du module EKS a aussi renommé ses variables (cluster_name devient name, cluster_version devient kubernetes_version) et retiré son sous-module aws-auth.

terraform {
  required_version = ">= 1.7.0" # blocs removed et import avec for_each
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 6.69"
    }
  }
}

module "eks" {
  source  = "terraform-aws-modules/eks/aws"
  version = "~> 21.26"
  # ...
}

Le fichier .terraform.lock.hcl se versionne avec le code, pour que bascule et retour arrière s'exécutent avec les mêmes versions de fournisseur.

aws-auth ou access entries

Le ConfigMap aws-auth est déprécié au profit des access entries, gérées par l'API EKS. Trois faits orientent le choix : un cluster créé par l'API EKS, un SDK ou CloudFormation sans précision est en mode CONFIG_MAP, alors que le module EKS fixe API_AND_CONFIG_MAP par défaut ; une fois activées, les access entries ne peuvent plus être retirées du mode d'authentification ; EKS Auto Mode les exige. Pour un cluster neuf, le mode API (authentication_mode = "API" dans le module) évite deux sources de vérité. Le module n'ajoute pas non plus l'identité qui exécute Terraform comme administrateur (enable_cluster_creator_admin_permissions vaut false) : les administrateurs se déclarent explicitement.

resource "aws_eks_access_entry" "plateforme" {
  cluster_name  = var.cluster_name
  principal_arn = var.role_plateforme_arn
}

resource "aws_eks_access_policy_association" "plateforme" {
  cluster_name  = var.cluster_name
  principal_arn = var.role_plateforme_arn
  policy_arn    = "arn:aws:eks::aws:cluster-access-policy/AmazonEKSClusterAdminPolicy"

  access_scope {
    type = "cluster"
  }
}

Sources officielles et limites de lecture

Tarifs, calendrier et versions d'outils ont été revérifiés le , les autres paramètres le 7 octobre 2026, dans les sources ci-dessous, à relire avant toute décision : AWS et les modules Terraform publient souvent. Les pages de la documentation AWS citées ont été lues sur docs.aws.amazon.com ou dans leur dépôt source publié par AWS, les paramètres d'API dans les modèles qu'AWS publie et les tarifs dans les fichiers de l'AWS Price List.

  • Méthode, pas récit : aucune migration particulière n'est relatée ; ni durée, ni volume, ni résultat observé.
  • Tarifs publics en dollars, région Paris, avant remises et taxes ; l'exemple ne porte que sur le plan de contrôle.
  • Périmètre : un compte et une région ; nœuds autogérés ou hybrides, EKS Anywhere, ECS Anywhere, Outposts et migrations de données hors champ.
  • Aucune garantie : une bascule par paliers réduit le rayon d'un incident, elle ne garantit pas son absence.

Sources

  1. AWS Price List, offre AmazonEKS, région eu-west-3 (publication du 28/09/2026), Amazon Web Services, https://pricing.us-east-1.amazonaws.com/offers/v1.0/aws/AmazonEKS/current/eu-west-3/index.csv, consulté le 18/10/2026.
  2. AWS Price List, offre AmazonECS, région eu-west-3 (publication du 11/09/2026), Amazon Web Services, https://pricing.us-east-1.amazonaws.com/offers/v1.0/aws/AmazonECS/current/eu-west-3/index.csv, consulté le 18/10/2026.
  3. Understand the Kubernetes version lifecycle on EKS, Amazon Web Services, https://docs.aws.amazon.com/eks/latest/userguide/kubernetes-versions.html, consulté le 18/10/2026.
  4. Update existing cluster to new Kubernetes version, Amazon Web Services, https://docs.aws.amazon.com/eks/latest/userguide/update-cluster.html, consulté le 18/10/2026.
  5. Amazon ECS API, modèle d'API publié par AWS (PutAccountSettingDefault, CreateService, CreateCluster, Secret, LoadBalancer, AdvancedConfiguration, ServiceConnectClientAlias, FirelensConfiguration), https://github.com/boto/botocore/blob/develop/botocore/data/ecs/2014-11-13/service-2.json, consulté le 18/10/2026.
  6. Manage compute resources by using nodes, Amazon Web Services, https://docs.aws.amazon.com/eks/latest/userguide/eks-compute.html, consulté le 07/10/2026.
  7. Karpenter documentation, projet Karpenter, https://github.com/aws/karpenter-provider-aws/blob/main/website/content/en/docs/_index.md, consulté le 07/10/2026.
  8. Automate cluster infrastructure with EKS Auto Mode, Amazon Web Services, https://docs.aws.amazon.com/eks/latest/userguide/automode.html, consulté le 18/10/2026.
  9. Update the Kubernetes version of an EKS Auto Mode cluster, Amazon Web Services, https://docs.aws.amazon.com/eks/latest/userguide/auto-upgrade.html, consulté le 07/10/2026.
  10. Simplify compute management with AWS Fargate, Amazon Web Services, https://docs.aws.amazon.com/eks/latest/userguide/fargate.html, consulté le 18/10/2026.
  11. Learn how EKS Pod Identity grants pods access to AWS services, Amazon Web Services, https://docs.aws.amazon.com/eks/latest/userguide/pod-identities.html, consulté le 18/10/2026.
  12. Create IAM role with trust policy required by EKS Pod Identity, Amazon Web Services, https://docs.aws.amazon.com/eks/latest/userguide/pod-id-role.html, consulté le 07/10/2026.
  13. Access AWS resources using EKS Pod Identity target IAM roles, Amazon Web Services, https://docs.aws.amazon.com/eks/latest/userguide/pod-id-assign-target-role.html, consulté le 07/10/2026.
  14. Grant Kubernetes workloads access to AWS using Kubernetes Service Accounts, Amazon Web Services, https://docs.aws.amazon.com/eks/latest/userguide/service-accounts.html, consulté le 07/10/2026.
  15. Use AWS Secrets Manager secrets with Amazon EKS Pods, Amazon Web Services, https://docs.aws.amazon.com/eks/latest/userguide/manage-secrets.html, consulté le 07/10/2026.
  16. DNS for Services and Pods, Kubernetes, https://kubernetes.io/docs/concepts/services-networking/dns-pod-service/, consulté le 07/10/2026.
  17. Extend Amazon EKS capabilities with open source projects (ExternalDNS), Amazon Web Services, https://docs.aws.amazon.com/eks/latest/userguide/related-projects.html, consulté le 07/10/2026.
  18. Monitor your cluster performance and view logs, Amazon Web Services, https://docs.aws.amazon.com/eks/latest/userguide/eks-observe.html, consulté le 07/10/2026.
  19. Elastic Load Balancing v2 API, modèle d'API publié par AWS (TargetGroupTuple, TargetGroupAttribute), https://github.com/boto/botocore/blob/develop/botocore/data/elbv2/2015-12-01/service-2.json, consulté le 07/10/2026.
  20. AWS CDK, ApplicationTargetGroup (métriques CloudWatch des groupes cibles), Amazon Web Services, https://github.com/aws/aws-cdk/blob/main/packages/aws-cdk-lib/aws-elasticloadbalancingv2/lib/alb/application-target-group.ts, consulté le 07/10/2026.
  21. Amazon Route 53 API, modèle d'API publié par AWS (ResourceRecordSet, Weight), https://github.com/boto/botocore/blob/develop/botocore/data/route53/2013-04-01/service-2.json, consulté le 18/10/2026.
  22. TargetGroupBinding, AWS Load Balancer Controller, Kubernetes SIGs, https://github.com/kubernetes-sigs/aws-load-balancer-controller/blob/main/docs/guide/targetgroupbinding/targetgroupbinding.md, consulté le 07/10/2026.
  23. Pod readiness gate, AWS Load Balancer Controller, Kubernetes SIGs, https://github.com/kubernetes-sigs/aws-load-balancer-controller/blob/main/docs/deploy/pod_readiness_gate.md, consulté le 07/10/2026.
  24. Create an IngressClass to configure an Application Load Balancer (EKS Auto Mode), Amazon Web Services, https://docs.aws.amazon.com/eks/latest/userguide/auto-configure-alb.html, consulté le 07/10/2026.
  25. Application Auto Scaling API, modèle d'API publié par AWS (MetricType), https://github.com/boto/botocore/blob/develop/botocore/data/application-autoscaling/2016-02-06/service-2.json, consulté le 07/10/2026.
  26. Horizontal Pod Autoscaling, Kubernetes, https://kubernetes.io/docs/concepts/workloads/autoscaling/horizontal-pod-autoscale/, consulté le 07/10/2026.
  27. EventBridge Scheduler API, modèle d'API publié par AWS (EcsParameters, ScheduleSummary), https://github.com/boto/botocore/blob/develop/botocore/data/scheduler/2021-06-30/service-2.json, consulté le 07/10/2026.
  28. CronJob, Kubernetes, https://kubernetes.io/docs/concepts/workloads/controllers/cron-jobs/, consulté le 18/10/2026.
  29. Sync Phases and Waves, Argo CD, https://argo-cd.readthedocs.io/en/stable/user-guide/sync-waves/, consulté le 07/10/2026.
  30. Operator pattern, Kubernetes, https://kubernetes.io/docs/concepts/extend-kubernetes/operator/, consulté le 07/10/2026.
  31. Refactor modules (moved blocks), HashiCorp, https://developer.hashicorp.com/terraform/language/modules/develop/refactoring, consulté le 07/10/2026.
  32. Generate configuration for import blocks, HashiCorp, https://developer.hashicorp.com/terraform/language/import/generating-configuration, consulté le 07/10/2026.
  33. Remove a resource from state (removed block), HashiCorp, https://developer.hashicorp.com/terraform/language/state/remove, consulté le 07/10/2026.
  34. Terraform CHANGELOG, branche v1.5 (1.5.0 : blocs import, -generate-config-out), HashiCorp, https://github.com/hashicorp/terraform/blob/v1.5/CHANGELOG.md, consulté le 07/10/2026.
  35. Terraform CHANGELOG, branche v1.7 (1.7.0 : bloc removed, import avec for_each), HashiCorp, https://github.com/hashicorp/terraform/blob/v1.7/CHANGELOG.md, consulté le 07/10/2026.
  36. The lifecycle meta-argument, HashiCorp, https://developer.hashicorp.com/terraform/language/meta-arguments/lifecycle, consulté le 07/10/2026.
  37. Resource aws_lb_listener_rule, fournisseur Terraform AWS, HashiCorp, https://github.com/hashicorp/terraform-provider-aws/blob/main/website/docs/r/lb_listener_rule.html.markdown, consulté le 07/10/2026.
  38. Resource aws_lb_target_group, fournisseur Terraform AWS, HashiCorp, https://github.com/hashicorp/terraform-provider-aws/blob/main/website/docs/r/lb_target_group.html.markdown, consulté le 07/10/2026.
  39. Resource aws_security_group, fournisseur Terraform AWS, HashiCorp, https://github.com/hashicorp/terraform-provider-aws/blob/main/website/docs/r/security_group.html.markdown, consulté le 07/10/2026.
  40. Resource aws_eks_access_entry, fournisseur Terraform AWS, HashiCorp, https://github.com/hashicorp/terraform-provider-aws/blob/main/website/docs/r/eks_access_entry.html.markdown, consulté le 07/10/2026.
  41. Resource aws_eks_access_policy_association, fournisseur Terraform AWS, HashiCorp, https://github.com/hashicorp/terraform-provider-aws/blob/main/website/docs/r/eks_access_policy_association.html.markdown, consulté le 07/10/2026.
  42. Resource aws_eks_pod_identity_association, fournisseur Terraform AWS, HashiCorp, https://github.com/hashicorp/terraform-provider-aws/blob/main/website/docs/r/eks_pod_identity_association.html.markdown, consulté le 07/10/2026.
  43. Resource aws_scheduler_schedule, fournisseur Terraform AWS, HashiCorp, https://github.com/hashicorp/terraform-provider-aws/blob/main/website/docs/r/scheduler_schedule.html.markdown, consulté le 18/10/2026.
  44. Terraform AWS provider CHANGELOG (6.69.1 du 15/10/2026), HashiCorp, https://github.com/hashicorp/terraform-provider-aws/blob/main/CHANGELOG.md, consulté le 18/10/2026.
  45. terraform-aws-modules/eks, tag v21.26.0 (versions.tf, variables.tf), terraform-aws-modules, https://github.com/terraform-aws-modules/terraform-aws-eks/tree/v21.26.0, consulté le 18/10/2026.
  46. Upgrade from v20.x to v21.x, terraform-aws-modules, https://github.com/terraform-aws-modules/terraform-aws-eks/blob/v21.26.0/docs/UPGRADE-21.0.md, consulté le 07/10/2026.
  47. terraform-aws-modules/ecs, tag v7.6.1 (versions.tf, modules/service/main.tf), terraform-aws-modules, https://github.com/terraform-aws-modules/terraform-aws-ecs/tree/v7.6.1, consulté le 18/10/2026.
  48. Grant IAM users and roles access to Kubernetes APIs, Amazon Web Services, https://docs.aws.amazon.com/eks/latest/userguide/grant-k8s-access.html, consulté le 18/10/2026.
  49. Change authentication mode to use access entries, Amazon Web Services, https://docs.aws.amazon.com/eks/latest/userguide/setting-up-access-entries.html, consulté le 18/10/2026.
  50. Grant IAM users access to Kubernetes with a ConfigMap, Amazon Web Services, https://docs.aws.amazon.com/eks/latest/userguide/auth-configmap.html, consulté le 07/10/2026.
  51. Amazon EKS API, modèle d'API publié par AWS (CreateAccessConfigRequest), https://github.com/boto/botocore/blob/develop/botocore/data/eks/2017-11-01/service-2.json, consulté le 07/10/2026.
  52. Review access policy permissions, Amazon Web Services, https://docs.aws.amazon.com/eks/latest/userguide/access-policy-permissions.html, consulté le 07/10/2026.

Parlons de votre contexte.

Cet article expose une pratique générale ; votre situation a ses propres contraintes. Décrivez-la, nous répondons avec un périmètre.

Ouvrir le formulaire