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-roleavec les policies EKS standard (AmazonEKSClusterPolicy) - Node role :
nex-staging-eks-node-roleavec 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
# Configurer kubectl
aws eks update-kubeconfig --name nex-staging --region eu-west-3IMPORTANT — 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-rdsetsg-redis. Voir l'encadré "Piège EKS" en Phase 3.
Validation
# Cluster actif
kubectl cluster-info
# Nœuds prêts
kubectl get nodes
# Attendu : 2 nœuds en status Ready
# Version K8s correcte
kubectl version --shortPHASE 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 Controllercert-manager— Gestion des certificatsexternal-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 podsnex-production: max 16 CPU, 32 Gi mémoire, 50 podsnex-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: trueetreal-ip-header: CF-Connecting-IPpour recevoir la vraie IP client derrière Cloudflare - Configurer
proxy-real-ip-cidravec 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, ClusterIssuerletsencrypt-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
SecretStoredoppler-storedansnex-stagingqui pointe vers Doppler (avec le token Doppler stocké dans un K8s Secretdoppler-tokencréé manuellement une seule fois) - Un
ExternalSecretqui synchronise toutes les variables Doppler (regexp.*) vers un Secret K8snex-secretsdans le namespacenex-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) :
kubectl annotate externalsecret nex-secrets -n nex-staging \
force-sync=$(date +%s) --overwrite8.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
# 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.)