Skip to content
StableAudienceOpsSécuritéOwner@platform-opsDernière revue2026-05-22

Infra de base — Compute

Phases 7 à 8 du déploiement infrastructure : cluster EKS, composants Kubernetes de base (ingress, cert-manager, external-secrets). Pour la vue d'ensemble, voir Infra de base — overview.

PHASE 7 — CLUSTER EKS

Objectif

Le cluster Kubernetes où tournent les 11 microservices. C'est la pièce centrale.

Instructions pour l'agent

Créer le module infrastructure/terraform/modules/eks/.

Cluster EKS :

  • Version : Kubernetes 1.29
  • Subnets : private_a et private_b (les pods ne sont jamais dans un subnet public)
  • Endpoint public access : activé (pour kubectl depuis les machines des devs). En production, restreindre aux IPs connues.
  • Endpoint private access : activé
  • Logging : activer api, audit, authenticator vers CloudWatch (les logs d'audit K8s sont utiles même si le monitoring principal est Grafana)
  • Secrets encryption : activé avec KMS (clé alias/nex-staging-eks-secrets)
  • OIDC provider : activé (obligatoire pour IRSA — permet aux pods d'assumer des rôles IAM)

Node Group managé :

  • Instance type : t3.medium (2 vCPU, 4 Go RAM)
  • Scaling : min 2, max 5, desired 2
  • Subnets : private_a et private_b (répartis sur 2 AZ)
  • AMI type : AL2_x86_64 (Amazon Linux 2 optimisé EKS)
  • Disk : 30 Go gp3
  • Security group : sg-eks-nodes
  • Labels : environment=staging, project=nex

IAM Roles :

  • Cluster role : nex-staging-eks-cluster-role avec les policies EKS standard (AmazonEKSClusterPolicy)
  • Node role : nex-staging-eks-node-role avec AmazonEKSWorkerNodePolicy, AmazonEKS_CNI_Policy, AmazonEC2ContainerRegistryReadOnly
  • OIDC provider : pour IRSA (les service accounts K8s pourront assumer des rôles IAM spécifiques)

Recommandations :

  • t3.medium (4 Go RAM) permet d'héberger ~6-8 pods selon les resource requests. Avec 2 nœuds ça fait ~14 pods. Tu as 11 services + les pods système (ingress, cert-manager, external-secrets, monitoring). Si les nœuds saturent, l'autoscaler montera à 3 puis 4 nœuds automatiquement.
  • En production, passer à t3.large (8 Go RAM) ou augmenter le min à 3 nœuds pour la haute dispo.
  • Le provisionnement EKS prend 15-20 minutes. L'agent doit attendre que le cluster soit ACTIVE avant de continuer.

Post-création

bash
# Configurer kubectl
aws eks update-kubeconfig --name nex-staging --region eu-west-3

IMPORTANT — Après la création du cluster, retourner en Phase 3 pour ajouter le SG cluster auto-généré par EKS aux inbound rules de sg-rds et sg-redis. Voir l'encadré "Piège EKS" en Phase 3.

Validation

bash
# Cluster actif
kubectl cluster-info

# Nœuds prêts
kubectl get nodes
# Attendu : 2 nœuds en status Ready

# Version K8s correcte
kubectl version --short

PHASE 8 — COMPOSANTS KUBERNETES DE BASE

Objectif

Installer les briques fondamentales dans le cluster avant de déployer les services.

Instructions pour l'agent

8.1 Namespaces

Créer infrastructure/kubernetes/base/namespaces.yaml :

  • nex-staging — les 11 microservices (environnement permanent)
  • nex-production — les 11 microservices (environnement permanent, overlay production)
  • nex-monitoring — Grafana Agent, Prometheus (fichier 04)
  • ingress-nginx — Ingress Controller
  • cert-manager — Gestion des certificats
  • external-secrets — Synchronisation Doppler → K8s

Namespaces review (dynamiques, créés par le pipeline CI) :

  • Pattern : nex-review-{branch} (ex: nex-review-nex-42-payment-flow)
  • Créés automatiquement par le job CI lors du déploiement d'une review
  • Supprimés automatiquement après 48h sans commit (CronJob review-env-cleanup.sh)
  • Utilisent le même cluster que staging avec des ResourceQuotas réduits

8.2 Resource Quotas

Créer infrastructure/kubernetes/base/resource-quotas.yaml :

  • nex-staging : max 8 CPU, 16 Gi mémoire, 30 pods
  • nex-production : max 16 CPU, 32 Gi mémoire, 50 pods
  • nex-monitoring : max 2 CPU, 4 Gi mémoire, 10 pods

Quotas review (appliqués dynamiquement par le pipeline CI à chaque nex-review-{branch}) :

  • max 4 CPU, 8 Gi mémoire, 15 pods
  • Toujours 1 replica par service en review

Ces quotas empêchent un service buggé de consommer toutes les ressources du cluster.

8.3 Ingress Controller (NGINX)

Installer via Helm ingress-nginx/ingress-nginx dans le namespace ingress-nginx.

Fichier Helm values : infrastructure/kubernetes/helm-values/ingress-nginx.yaml

Configuration critique :

  • Service type : LoadBalancer (crée automatiquement un NLB AWS)
  • Annotation aws-load-balancer-scheme: internet-facing
  • Annotation aws-load-balancer-cross-zone-load-balancing-enabled: true
  • Annotation aws-load-balancer-type: nlb (Network Load Balancer)
  • Activer les métriques Prometheus
  • Configurer use-forwarded-headers: true et real-ip-header: CF-Connecting-IP pour recevoir la vraie IP client derrière Cloudflare
  • Configurer proxy-real-ip-cidr avec les plages IP Cloudflare (l'agent doit récupérer la liste à jour depuis https://www.cloudflare.com/ips/)
  • Resources : requests 100m CPU / 128Mi, limits 200m CPU / 256Mi

Recommandation : après installation, récupérer le hostname du NLB créé par AWS. Ce hostname sera utilisé dans le DNS Cloudflare.

Ingress routes (dans infrastructure/kubernetes/services/<service>/ingress.yaml ou overlay staging) :

  • Host : dev.paywithnex.com
  • TLS via cert-manager (secret nex-api-tls, ClusterIssuer letsencrypt-prod)
  • Routes avec regex rewrite :
    • /auth(/|$)(.*) → service auth (port 3001)
    • /configuration(/|$)(.*) → service configuration (port 3006)
    • /api(/|$)(.*) → service orchestrator (port 3004)
  • SSL redirect activé, proxy body size 10m

8.4 cert-manager

Installer via Helm jetstack/cert-manager dans le namespace cert-manager avec installCRDs: true.

Fichier Helm values : infrastructure/kubernetes/helm-values/cert-manager.yaml

Créer deux ClusterIssuers Let's Encrypt :

  • letsencrypt-prod : serveur ACME production (https://acme-v02.api.letsencrypt.org/directory)
  • letsencrypt-staging : serveur ACME staging (https://acme-staging-v02.api.letsencrypt.org/directory)

Les deux utilisent le solver HTTP01 via l'Ingress NGINX. Email de contact : tech@paywithnex.com.

Recommandation : utiliser le staging issuer tant que le DNS n'est pas finalisé (rate limits plus souples).

8.5 External Secrets Operator

Installer via Helm external-secrets/external-secrets dans le namespace external-secrets.

Fichier Helm values : infrastructure/kubernetes/helm-values/external-secrets.yaml

Créer :

  • Un SecretStore doppler-store dans nex-staging qui pointe vers Doppler (avec le token Doppler stocké dans un K8s Secret doppler-token créé manuellement une seule fois)
  • Un ExternalSecret qui synchronise toutes les variables Doppler (regexp .*) vers un Secret K8s nex-secrets dans le namespace nex-staging
  • Refresh interval : 1h (les secrets se resynchronisent toutes les heures)

Les deployments des microservices référenceront ce secret via envFrom.secretRef.

Forcer la re-sync (après modification de secrets dans Doppler) :

bash
kubectl annotate externalsecret nex-secrets -n nex-staging \
  force-sync=$(date +%s) --overwrite

8.6 Secret GitLab Registry

Créer un secret gitlab-registry de type docker-registry dans nex-staging avec les credentials d'un Deploy Token GitLab (read_registry). Ce secret permet aux pods de pull les images depuis registry.gitlab.com/nxpay/nex/*.

Recommandation : créer le Deploy Token dans GitLab (Settings → Repository → Deploy Tokens) avec le scope read_registry uniquement. Ne pas utiliser un Personal Access Token.

Validation

bash
# Namespaces
kubectl get ns | grep -E "nex-|ingress|cert-manager|external-secrets"
# Attendu : 6 namespaces

# Ingress Controller avec un LoadBalancer
kubectl get svc -n ingress-nginx ingress-nginx-controller -o jsonpath='{.status.loadBalancer.ingress[0].hostname}'
# Attendu : un hostname AWS (xxxxx.elb.eu-west-3.amazonaws.com)

# cert-manager
kubectl get clusterissuer
# Attendu : letsencrypt-prod et letsencrypt-staging en Ready=True

# External Secrets
kubectl get secretstores -n nex-staging
# Attendu : doppler-store en Ready=True

kubectl get externalsecrets -n nex-staging
# Attendu : nex-secrets en status SecretSynced

# Secrets disponibles pour les pods
kubectl get secret nex-secrets -n nex-staging -o jsonpath='{.data}' | jq 'keys'
# Attendu : liste des clés (POSTGRES_HOST, REDIS_HOST, etc.)

Nex — Plateforme fintech CEMAC