- Gestion de l’état — Prépare le compartiment S3 utilisé pour stocker l’état Terraform de l’environnement.
- Infrastructure EKS — Provisionne le VPC, les sous-réseaux, les passerelles NAT, les rôles IAM et le cluster EKS avec les groupes de nœuds gérés.
- Stockage et équilibrage de charge — Déploie le pilote EBS CSI pour les volumes persistants et le contrôleur de équilibrage de charge AWS pour l’entrée ALB.
- Mise à l’échelle Karpenter — Configure le provisionnement dynamique des nœuds avec support des instances Spot et gestion des interruptions via SQS et EventBridge.
- Mise à l’échelle KEDA — Déploie KEDA pour la mise à l’échelle au niveau des pods basée sur les seuils CPU et mémoire.
- Services de données — Provisionne Supabase (auto-hébergé ou Cloud), ElastiCache Redis et Amazon MQ RabbitMQ.
- Services Odin — Déploie la pile d’application EKB (Web, FastAPI, Celery, Automator) via Helm.
- Observabilité SigNoz — Déploie la traçabilité distribuée, les métriques et l’agrégation des journaux via SigNoz et l’agent k8s-infra.
- Déploiement final — Exécute un
terragrunt applycomplet pour réconcilier les ressources restantes.
<YOUR_*> dans le modèle d’environnement sont remplis. Certaines valeurs — notamment l’ID VPC, le point de terminaison du cluster EKS et les points de terminaison Redis et RabbitMQ — ne sont disponibles qu’après l’achèvement de certaines phases, c’est pourquoi le guide indique exactement quand les capturer et les appliquer.
Prérequis
- AWS CLI configuré avec les permissions appropriées
- Terraform (>= 1.0)
- Terragrunt (dernière version)
kubectlpour la gestion Kuberneteshelmpour la gestion des graphiques Helm
Guide d’installation
Installation de Terragrunt
macOS (Homebrew)Installation de kubectl
macOS (Homebrew)Installation de Helm
macOS (Homebrew)Vérification de l’installation
Configuration de l’AWS CLI
Créer un nouvel environnement
Étape 1 : Copier le modèle d’environnement
Le dossierenv-template-folder contient des fichiers pré-structurés avec des espaces réservés <YOUR_*> prêts à être remplis. Copiez-le entièrement pour créer votre nouveau dossier d’environnement.
Étape 2 : Vérifier que tous les espaces réservés sont présents
<YOUR_*>. Les étapes suivantes guident leur remplissage fichier par fichier.
Étape 3 : Provisionner les certificats SSL (AWS ACM)
Avant de définir les variables d’environnement, vous avez besoin des ARN des certificats. Utilisez la console AWS pour demander des certificats SSL dans AWS Certificate Manager (ACM) pour tous les domaines que votre environnement desservira. Option A : Un seul certificat wildcard (recommandé) Un seul certificat wildcard couvre tous les sous-domaines avec un ARN. Par exemple, si votre domaine de base estapp.example.com, un seul certificat *.app.example.com couvre :
Option B : Certificats par service
Demandez un certificat par domaine si vous ne pouvez pas utiliser de wildcard. Répétez les étapes ci-dessous pour chaque domaine :
<YOUR_WEB_DOMAIN>, <YOUR_API_DOMAIN>, <YOUR_AUTOMATOR_DOMAIN>, <YOUR_SUPABASE_DOMAIN> (uniquement si ENABLE_SUPABASE=true), <YOUR_SIGNOZ_DOMAIN> (uniquement si ENABLE_SIGNOZ=true).
Demander un certificat dans la console AWS
- Ouvrez la console AWS Certificate Manager
- Passez à la bonne région (en haut à droite) — elle doit correspondre à
<YOUR_AWS_REGION> - Cliquez sur Demander un certificat → Demander un certificat public → Suivant
- Sous Nom de domaine pleinement qualifié, saisissez le wildcard (par ex.
*.app.example.com) ou un domaine spécifique - Définissez la Méthode de validation sur Validation DNS
- Cliquez sur Demander — le certificat est créé dans l’état
En attente de validation
Incluez le point final (
.) à la fin des valeurs CNAME si votre fournisseur DNS l’exige.- Connectez-vous à Cloudflare → sélectionnez votre domaine → accédez à DNS → Enregistrements → Ajouter un enregistrement
- Définissez le Type sur
CNAME - Collez le nom CNAME d’ACM dans Nom et la valeur CNAME d’ACM dans Cible
- Définissez l’État du proxy sur DNS uniquement (icône nuage gris) — le certificat ne sera pas validé via le proxy Cloudflare
- Cliquez sur Enregistrer
- Ouvrez la console Route 53 → Zones hébergées → sélectionnez votre zone → Créer un enregistrement
- Définissez le Type d’enregistrement sur
CNAME - Collez le nom CNAME d’ACM dans Nom de l’enregistrement (partie sous-domaine uniquement) et la valeur dans Valeur
- Définissez le TTL sur
300et cliquez sur Créer les enregistrements
arn:aws:acm:<region>:<account-id>:certificate/<uuid>. Conservez le(s) ARN pour l’étape suivante.
Étape 4 : Définir les variables d’environnement
Définissez ces variables d’environnement shell avant d’exécuter les commandes Terragrunt. Elles sont lues directement parterragrunt.hcl via get_env().
Instances Spot et charges de travail persistantes
Les instances Spot sont configurées par NodePool dansvalues/karpenter.yaml, pas via les variables d’environnement. Chaque NodePool déclare sa propre stratégie de capacité :
Le NodePool
application utilise les familles d’instances m/c (génération 5+) avec On-Demand uniquement. Les pods de service Supabase sont épinglés ici via nodeSelector: workload-type: "application" pour garantir qu’ils ne sont jamais interrompus par un événement de récupération Spot.
Le NodePool database-dedicated n’utilise jamais Spot. Il utilise consolidationPolicy: WhenEmpty afin que Karpenter n’évince pas un nœud qui a encore un pod en cours d’exécution, ce qui le rend sûr pour les charges de travail persistantes telles que PostgreSQL et les réplicas CloudNativePG.
Directives pour les charges de travail persistantes sur Spot :
- N’exécutez pas de bases de données, de files d’attente persistantes ou de pod avec un
PersistentVolumeClaimsur les NodePools Spot. - Utilisez un
nodeSelectorciblantnode-type: database-dedicatedavec la tolérance correspondantedatabase-workload: "true"pour les pods de base de données. - Utilisez
nodeSelector: workload-type: "application"pour les services sans état面向utilisateur qui doivent rester disponibles sans interruption. - Pour les charges de travail en arrière-plan (Web, API, Celery, Automator), le NodePool Spot
generalest approprié — le gestionnaire d’interruptions SQS de Karpenter évacue gracieusement les nœuds Spot avant qu’AWS ne les récupère, et le nombre minimum de réplicas KEDA (≥ 2) garantit la disponibilité pendant le remplacement des nœuds. - Pour désactiver Spot globalement, supprimez
"spot"de la liste des valeurs dans chaque NodePool dansvalues/karpenter.yaml.
karpenter de terragrunt.hcl :
Étape 5 : Mettre à jour les valeurs spécifiques à l’environnement
Effectuez un rechercher-remplacer dans tous les fichiers de votre nouveau dossier d’environnement pour les espaces réservés suivants :5.1 terragrunt.hcl — Configuration principale du cluster
5.2 state/terragrunt.hcl — Compartiment d’état S3
5.3 values/infrastructure.yaml — Contrôleur de équilibrage de charge AWS
5.4 values/karpenter-values.yaml — Contrôleur Karpenter
5.5 values/karpenter-nodeclasses.yaml — Classes de nœuds Karpenter
5.6 values/aws-ebs-csi-driver.yaml — Pilote EBS CSI
5.7 values/karpenter.yaml — NodePools Karpenter
Les noms de classes de nœuds (
general, compute-intensive, memory-intensive, gpu, database) doivent correspondre aux entrées de karpenter-nodeclasses.yaml.
5.8 values/keda.yaml — Mise à l’échelle KEDA
Aucun espace réservé spécifique à l’environnement requis. Les limites de ressources et les nombres de réplicas sont préconfigurés avec des valeurs par défaut raisonnables. Examinez et ajustez si nécessaire.
5.9 values/supabase.yaml — Application Supabase (uniquement si ENABLE_SUPABASE=true)
5.10 values/ha-supabase-db.yaml — Base de données HA Supabase (uniquement si ENABLE_HA_SUPABASE_DB=true)
La classe de stockage (
ebs-csi-gp2), le nombre d’instances et les limites de ressources sont préconfigurés. Ajustez postgres.storage.size et postgres.walStorage.size en fonction du volume de données attendu.
5.11 values/cloudnative-pg.yaml — Opérateur CloudNativePG (uniquement si ENABLE_CNPG=true)
Aucun espace réservé spécifique à l’environnement requis. Ceci déploie uniquement le contrôleur de l’opérateur CNPG. Les paramètres par défaut (3 réplicas, limites de ressources) conviennent à la plupart des environnements.
5.12 values/odin-services.yaml — Services d’application Odin
Supabase (
dataServiceConfig) — auto-hébergé (ENABLE_SUPABASE=true) :
Supabase (
dataServiceConfig) — Supabase Cloud (ENABLE_SUPABASE=false) :
Redis :
ENABLE_SUPABASE=true) :
Clés Supabase du frontend Web — Supabase Cloud (
ENABLE_SUPABASE=false) :
5.13 values/signoz.yaml — Observabilité SigNoz (uniquement si ENABLE_SIGNOZ=true)
5.14 values/signoz-k8s-infra.yaml — Métriques K8s SigNoz (uniquement si ENABLE_SIGNOZ=true)
Le point de terminaison du collecteur OTel (
signoz-otel-collector.monitoring.svc.cluster.local:4317) est préconfiguré en supposant que SigNoz et k8s-infra sont déployés dans le namespace monitoring. Aucune modification n’est nécessaire sauf si vous utilisez un nom de release personnalisé.
Rappel de l’ordre de déploiement
Certaines valeurs ne sont disponibles qu’après le déploiement de certaines infrastructures. Suivez cet ordre :- Avant tout déploiement — Définir :
<YOUR_ENV_NAME>,<YOUR_AWS_REGION>,<YOUR_AWS_ACCOUNT_ID>,<YOUR_ENVIRONMENT>,<YOUR_PROJECT>,<YOUR_VPC_CIDR>, tous les noms de domaine, tous les ARN de certificat, toutes les valeurs Supabase,<YOUR_TOOLKIT_ENCRYPTION_KEY>, nom d’utilisateur/mot de passe RabbitMQ - Après la création du cluster EKS — Définir :
<YOUR_VPC_ID>(infrastructure.yaml),<YOUR_EKS_CLUSTER_ENDPOINT>(karpenter-values.yaml) - Après
terraform applypour les services AWS — Définir :<YOUR_REDIS_HOST>,<YOUR_RABBITMQ_HOST>(odin-services.yaml)
Étape 6 : Vérifier qu’aucun espace réservé ne subsiste
Phase 1 : Configuration de la gestion de l’état
Objectif : Création du compartiment S3 pour l’état Terraform. Le module de gestion de l’état de chaque environnement crée un compartiment S3 avec le motifodin-terraform-state-{environment-name}, configure le chiffrement, le versionnage et le blocage d’accès public, et utilise l’état local pour le module d’état lui-même (modèle d’amorçage).
Phase 2 : Déploiement de l’infrastructure EKS
Objectif : Réseau principal (VPC, sous-réseaux, passerelle NAT), rôles et politiques IAM, cluster EKS et groupes de nœuds gérés.2.1 Exécution à blanc — Infrastructure EKS
Infrastructure principaleUtiliser un registre Docker personnalisé / privé
Par défaut, les images EKB sont tirées de Docker Hub à l’aide d’un secret nomméregcred. Si le client héberge les images dans un autre registre, suivez ces étapes avant de déployer odin-services.
Étape 1 — Créer le imagePullSecret dans le namespace cible
values/odin-services.yaml
2.2 Déployer l’infrastructure EKS
Étape 1 : Infrastructure principalePhase 3 : Stockage et équilibrage de charge
Objectif : Pilote EBS CSI pour les volumes persistants, contrôleur de équilibrage de charge AWS fonctionnant sur le groupe de nœuds géré.3.1 Exécution à blanc — Stockage et équilibrage de charge
Pilote EBS CSI3.2 Déployer le stockage et l’équilibrage de charge
Étape 1 : Pilote EBS CSIPhase 4 : Mise à l’échelle Karpenter
Objectif : Rôles IAM pour Karpenter, gestion des interruptions Spot, contrôleur Karpenter et pools de nœuds.4.1 Exécution à blanc — Karpenter
Ressources IAM Karpenterterragrunt.hcl)
Une erreur attendue peut apparaître lors du plan :
API did not recognize GroupVersionKind from manifest (CRD may not be installed). C’est normal et peut être ignoré — Kubernetes valide les ressources par rapport à l’API en direct au moment du plan, avant l’installation des CRD.4.2 Déployer Karpenter
Étape 1 : Ressources IAM Karpenterterragrunt.hcl)
Phase 5 : Mise à l’échelle KEDA
Objectif : KEDA pour la mise à l’échelle au niveau de l’application.5.1 Exécution à blanc — KEDA
5.2 Déployer KEDA
Phase 6 : Services de données
Objectif : Supabase (base de données), ElastiCache (Redis), RabbitMQ (file d’attente de messages).Déployez d’abord l’opérateur CloudNativePG, puis le cluster de base de données HA Supabase, puis l’application Supabase. Le cluster de base de données doit être prêt avant le démarrage de Supabase.
6.1 Exécution à blanc — Services de données
Étape 1 : Opérateur CloudNativePG (si activé)6.2 Déployer les services de données
Étape 1 : Opérateur CloudNativePG (si activé)EXTERNAL-IP si LoadBalancer) comme valeur SUPABASE_POSTGRES_HOST dans values/odin-services.yaml et comme secret.db.postgresHost dans values/supabase.yaml.
Étape 3 : Application Supabase (si activée)
Tous les pods de service Supabase s’exécutent exclusivement sur le NodePool application Karpenter (On-Demand uniquement) pour prévenir les interruptions Spot.
Phase 7 : Services Odin
Objectif : Déploiement de l’application via Helm.Avant le déploiement, réduisez temporairement le nombre de réplicas de
fastapiBackend à un seul pour l’exécution initiale de la migration de base de données — définissez replicaCount: 1, workers: 1 et keda.minReplicas: 1. Une fois la migration terminée avec succès, rétablissez ces valeurs à leurs valeurs par défaut de production avant de redéployer.7.1 Exécution à blanc — Services Odin
7.2 Déployer les services Odin
Phase 8 : Observabilité SigNoz
Objectif : Surveillance des journaux et des métriques.8.1 Exécution à blanc — Graphiques SigNoz
8.2 Déployer les graphiques SigNoz
Phase 9 : Déploiement final
9.1 Déploiement complet
9.2 Vérifier le déploiement
Dépannage
Problèmes de verrouillage d’étatNettoyage
Surveillance et journalisation
Référence rapide — Toutes les commandes de déploiement
Remplacez
your-env-name par le nom réel de votre environnement. Exécutez toujours des exécutions à blanc (terragrunt plan) pour valider votre configuration avant d’appliquer les modifications.