🚢 Module Terraform — EKS cluster (Kubernetes AWS)
Format : Terraform (.tf) · EKS 1.29 · production-ready Auteur : Équipe pédagogique ITAG · DevOps Pack Mise à jour : 2026
🎯 Description
Module Terraform pour provisionner un cluster EKS managé AWS, prêt pour la production. Inclut : node groups managed, IRSA (IAM Roles for Service Accounts), autoscaling, addons (CoreDNS, kube-proxy, EBS CSI driver, VPC CNI).
📋 Ressources créées
Cluster
aws_eks_cluster(version 1.29, encryption KMS, audit logs CloudWatch)aws_iam_rolecluster + nodeaws_security_group(cluster + node + worker)aws_kms_keypour encryption secrets
Node groups
- 1 × node group
system(t3.medium, taints CriticalAddonsOnly) - 1 × node group
general(m5.large, autoscaling 2-10) - Optionnel : node group
gpu(g4dn.xlarge, taints nvidia.com/gpu)
IRSA
- OIDC provider configuré
- Roles pré-créés pour : cluster-autoscaler, AWS Load Balancer Controller, External DNS, EBS CSI
Addons
- CoreDNS (managed)
- kube-proxy (managed)
- VPC CNI (managed)
- EBS CSI Driver (managed avec IRSA)
Observability
- CloudWatch Container Insights
- Prometheus operator (via Helm provider, optionnel)
💾 Code Terraform complet
main.tf
terraform {
required_version = ">= 1.6"
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 5.0"
}
}
}
provider "aws" {
region = "eu-west-1"
}
── IAM ROLE — EKS CLUSTER ────────────────────────────────────────────────────
resource "aws_iam_role" "eks_cluster_role" {
name = "${var.cluster_name}-cluster-role"
assume_role_policy = jsonencode({
Version = "2012-10-17"
Statement = [{
Action = "sts:AssumeRole"
Effect = "Allow"
Principal = {
Service = "eks.amazonaws.com"
}
}]
})
tags = {
Environment = var.environment
ManagedBy = "Terraform"
}
}
resource "aws_iam_role_policy_attachment" "eks_cluster_policy" {
policy_arn = "arn:aws:iam::aws:policy/AmazonEKSClusterPolicy"
role = aws_iam_role.eks_cluster_role.name
}
── EKS CLUSTER ───────────────────────────────────────────────────────────────
resource "aws_eks_cluster" "main" {
name = var.cluster_name
version = var.k8s_version
role_arn = aws_iam_role.eks_cluster_role.arn
vpc_config {
subnet_ids = var.subnet_ids
endpoint_private_access = true
endpoint_public_access = true
}
enabled_cluster_log_types = ["api", "audit", "authenticator", "controllerManager", "scheduler"]
tags = {
Name = var.cluster_name
Environment = var.environment
ManagedBy = "Terraform"
}
depends_on = [
aws_iam_role_policy_attachment.eks_cluster_policy
]
}
── IAM ROLE — NODE GROUP ─────────────────────────────────────────────────────
resource "aws_iam_role" "node_group_role" {
name = "${var.cluster_name}-node-group-role"
assume_role_policy = jsonencode({
Version = "2012-10-17"
Statement = [{
Action = "sts:AssumeRole"
Effect = "Allow"
Principal = {
Service = "ec2.amazonaws.com"
}
}]
})
tags = {
Environment = var.environment
ManagedBy = "Terraform"
}
}
resource "aws_iam_role_policy_attachment" "node_worker_policy" {
policy_arn = "arn:aws:iam::aws:policy/AmazonEKSWorkerNodePolicy"
role = aws_iam_role.node_group_role.name
}
resource "aws_iam_role_policy_attachment" "node_cni_policy" {
policy_arn = "arn:aws:iam::aws:policy/AmazonEKS_CNI_Policy"
role = aws_iam_role.node_group_role.name
}
resource "aws_iam_role_policy_attachment" "node_ecr_policy" {
policy_arn = "arn:aws:iam::aws:policy/AmazonEC2ContainerRegistryReadOnly"
role = aws_iam_role.node_group_role.name
}
── EKS NODE GROUP ────────────────────────────────────────────────────────────
resource "aws_eks_node_group" "general" {
cluster_name = aws_eks_cluster.main.name
node_group_name = "${var.cluster_name}-general"
node_role_arn = aws_iam_role.node_group_role.arn
subnet_ids = var.subnet_ids
instance_types = var.instance_types
disk_size = 50
scaling_config {
min_size = var.min_size
max_size = var.max_size
desired_size = 3
}
update_config {
max_unavailable = 1
}
labels = {
environment = var.environment
node-group = "general"
}
tags = {
Name = "${var.cluster_name}-general-node"
Environment = var.environment
ManagedBy = "Terraform"
}
depends_on = [
aws_iam_role_policy_attachment.node_worker_policy,
aws_iam_role_policy_attachment.node_cni_policy,
aws_iam_role_policy_attachment.node_ecr_policy,
]
}
── EKS ADDONS ────────────────────────────────────────────────────────────────
resource "aws_eks_addon" "coredns" {
cluster_name = aws_eks_cluster.main.name
addon_name = "coredns"
depends_on = [aws_eks_node_group.general]
}
resource "aws_eks_addon" "kube_proxy" {
cluster_name = aws_eks_cluster.main.name
addon_name = "kube-proxy"
}
resource "aws_eks_addon" "vpc_cni" {
cluster_name = aws_eks_cluster.main.name
addon_name = "vpc-cni"
}
variables.tf
variable "cluster_name" {
description = "Name of the EKS cluster"
type = string
default = "my-eks-cluster"
}
variable "k8s_version" {
description = "Kubernetes version to use for the EKS cluster"
type = string
default = "1.29"
}
variable "environment" {
description = "Deployment environment (dev / staging / prod)"
type = string
default = "dev"
validation {
condition = contains(["dev", "staging", "prod"], var.environment)
error_message = "environment must be one of: dev, staging, prod."
}
}
variable "subnet_ids" {
description = "List of subnet IDs for the EKS cluster and node groups"
type = list(string)
}
variable "instance_types" {
description = "EC2 instance types for the node group"
type = list(string)
default = ["t3.medium"]
}
variable "min_size" {
description = "Minimum number of nodes in the node group"
type = number
default = 2
}
variable "max_size" {
description = "Maximum number of nodes in the node group"
type = number
default = 5
}
outputs.tf
output "cluster_endpoint" {
description = "Endpoint URL of the EKS cluster API server"
value = aws_eks_cluster.main.endpoint
}
output "cluster_name" {
description = "Name of the EKS cluster"
value = aws_eks_cluster.main.name
}
output "cluster_ca_certificate" {
description = "Base64-encoded CA certificate for the cluster"
value = aws_eks_cluster.main.certificate_authority[0].data
sensitive = true
}
output "kubeconfig_command" {
description = "AWS CLI command to update local kubeconfig"
value = "aws eks update-kubeconfig --region eu-west-1 --name ${aws_eks_cluster.main.name}"
}
output "node_group_role_arn" {
description = "ARN of the IAM role used by the node group"
value = aws_iam_role.node_group_role.arn
}
💼 Cas d'usage
- Plateforme microservices à scale
- Préparation CKAD / CKA
- Migration on-prem vers cloud Kubernetes
- Blueprint AWS Well-Architected
📥 Télécharger ce template
Télécharger le fichier .md · ← Catalogue Terraform · Parcours DevOps →
ITAG · Non-affiliés HashiCorp / AWS / CNCF.