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

Infra de base — DNS, secrets et config NestJS

Phases 9 à 11 du déploiement infrastructure : DNS Cloudflare + certificats, Doppler / External Secrets, configuration NestJS des services. Pour la vue d'ensemble, voir Infra de base — overview.

PHASE 9 — DNS CLOUDFLARE & CERTIFICATS

Objectif

Rendre les services accessibles via les domaines paywithnex.com avec TLS.

Instructions pour l'agent

9.1 Configuration DNS

Dans Cloudflare (via Terraform provider Cloudflare ou manuellement) :

TypeNomValeurProxy CloudflareNote
CNAMEapi.stagingHostname du NLB (phase 8.3)Oui (orange)API staging
CNAMEadminSite Firebase HostingNon (gris)CMMS Dashboard
CNAMEboSite Firebase HostingNon (gris)Backoffice
TXT@SPF record pour ResendDélivrabilité email
TXTresend._domainkeyDKIM record ResendSignature email
TXT_dmarcDMARC policyAnti-spoofing
CNAME*.reviewHostname du NLB (phase 8.3)Oui (orange)Review envs éphémères

Les enregistrements pour la production (prod.paywithnex.com) seront ajoutés en semaine 2.

Note review : Le wildcard *.review.paywithnex.com pointe vers le même NLB que staging. L'Ingress Controller route vers le bon namespace nex-review-{branch} grâce au host header.

9.2 Configuration Cloudflare

  • SSL/TLS mode : Full (strict) — Cloudflare ↔ origin avec certificat valide (cert-manager)
  • Always Use HTTPS : activé
  • Minimum TLS Version : 1.2
  • HSTS : activé, max-age 6 mois
  • Brotli : activé
  • HTTP/2 : activé

9.3 Firebase Hosting

L'agent doit configurer le fichier infrastructure/firebase/firebase.json pour le hosting des 2 dashboards Nuxt.js :

  • Target admin → CMMS Dashboard (admin.paywithnex.com)
  • Target backoffice → Backoffice (bo.paywithnex.com)

Connecter les custom domains dans la console Firebase Hosting et ajouter les enregistrements DNS de vérification dans Cloudflare.

Recommandation : le proxy Cloudflare (orange) doit être désactivé pour les domaines Firebase Hosting. Firebase gère son propre SSL et CDN. Mettre Cloudflare en proxy devant Firebase crée des conflits de certificats.

Validation

bash
# DNS résout
dig dev.paywithnex.com +short
# Attendu : IP Cloudflare (le proxy est actif)

dig admin.paywithnex.com +short
# Attendu : IP Firebase Hosting

# TLS fonctionne
curl -I https://dev.paywithnex.com
# Attendu : HTTP/2 200 ou 404 (pas encore de routes) avec headers Cloudflare

# Firebase Hosting répond
curl -I https://admin.paywithnex.com
# Attendu : HTTP/2 200 avec headers Firebase

PHASE 10 — DOPPLER : INJECTION DES SECRETS

Objectif

Remplir Doppler avec toutes les valeurs réelles issues des outputs Terraform (endpoints RDS, Redis, etc.) et des services externes (Firebase, Sentry, Resend).

Instructions pour l'agent

Après les phases 4 à 9, tous les endpoints sont connus. L'agent doit générer un script qui récupère les outputs Terraform et met à jour Doppler.

Secrets à configurer dans le projet Doppler paywithnex, config stg :

# --- Base de données ---
POSTGRES_HOST=<output terraform: rds_endpoint (sans le port)>
POSTGRES_PORT=5432
POSTGRES_DB=nex_staging
POSTGRES_USER=nex_admin
POSTGRES_PASSWORD=<output terraform: rds_password>
POSTGRES_SSL=true

# --- Schemas par service ---
AUTH_SCHEMA=auth
ORCHESTRATOR_SCHEMA=orchestrator
NOTIFICATIONS_SCHEMA=notification
LEDGER_WALLETS_SCHEMA=ledger_wallets
# (chaque service a sa variable <SERVICE>_SCHEMA)

# --- Redis ---
REDIS_HOST=<output terraform: redis_endpoint>
REDIS_PORT=6379
REDIS_PASSWORD=<output terraform: redis_auth_token>
REDIS_TLS=true

# --- JWT ---
JWT_SECRET=<généré, 64 chars aléatoires>
JWT_EXPIRATION=3600

# --- Firebase ---
FIREBASE_PROJECT_ID=nex-app
FIREBASE_SERVER_KEY=<depuis Firebase console>
FIREBASE_STORAGE_BUCKET=nex-app.appspot.com

# --- Sentry ---
SENTRY_DSN=<depuis Sentry dashboard, un DSN par service ou un global>

# --- Resend ---
RESEND_API_KEY=<depuis Resend dashboard>

# --- App ---
NODE_ENV=staging
LOG_LEVEL=debug
API_BASE_URL=https://dev.paywithnex.com

IMPORTANT — Variables de connexion :

Les services NestJS utilisent les noms POSTGRES_* (pas DATABASE_*) et REDIS_PASSWORD (pas REDIS_AUTH_TOKEN). Deux variables cruciales à ne pas oublier :

  • POSTGRES_SSL=true — RDS exige SSL. Sans ça, erreur no pg_hba.conf entry... no encryption.
  • REDIS_TLS=true — ElastiCache a transit_encryption_enabled. Sans ça, erreur ETIMEDOUT car ioredis essaie une connexion non-TLS.

URLs de communication inter-services (utilisées par l'orchestrator) :

RISK_ENGINE_SERVICE_URL=http://risk-engine:3009
LEDGER_WALLET_SERVICE_URL=http://ledger-wallets:3002
AUTH_SERVICE_URL=http://auth:3001
CUSTOMER_SERVICE_URL=http://customer-profiles-kyc:3003
CONFIGURATION_SERVICE_URL=http://configuration:3006
NOTIFICATIONS_SERVICE_URL=http://notifications:3005
SERVICE_CATALOG_URL=http://service-catalog:3010

Note : Les services communiquent via le DNS interne Kubernetes (<service-name>.<namespace>.svc.cluster.local). Les noms courts (http://auth:3001) fonctionnent car tous les services sont dans le même namespace nex-staging.

Recommandations :

  • Le script doit être idempotent : relancer le script ne crée pas de doublons.
  • Les mots de passe générés (POSTGRES_PASSWORD, JWT_SECRET, REDIS_PASSWORD) ne doivent être générés qu'une fois. Si ils existent déjà dans Doppler, ne pas les écraser.
  • Après la mise à jour de Doppler, forcer un refresh de l'ExternalSecret K8s pour que les pods récupèrent les nouvelles valeurs.

Validation

bash
# Vérifier le nombre de secrets
doppler secrets --project paywithnex --config stg --only-names | wc -l
# Attendu : >= 25

# Vérifier que les endpoints sont corrects
doppler secrets get POSTGRES_HOST --project paywithnex --config stg --plain
# Attendu : nex-staging-postgres.xxxxx.eu-west-3.rds.amazonaws.com

# Vérifier les variables critiques
doppler secrets get POSTGRES_SSL --project paywithnex --config stg --plain
# Attendu : true

doppler secrets get REDIS_TLS --project paywithnex --config stg --plain
# Attendu : true

# Vérifier la synchro K8s
kubectl get secret nex-secrets -n nex-staging -o jsonpath='{.data.POSTGRES_HOST}' | base64 -d
# Attendu : même valeur que Doppler

PHASE 11 — CONFIGURATION NESTJS DES SERVICES

Objectif

S'assurer que chaque service NestJS est correctement configuré pour fonctionner sur EKS avec les managed services AWS (RDS + SSL, ElastiCache + TLS, health checks K8s).

Pré-requis par service

Chaque service NestJS doit avoir les 3 éléments suivants :

11.1 Health endpoint

Chaque service doit exposer un endpoint GET /health exclu du prefix global pour que les probes K8s fonctionnent.

Dans main.ts :

typescript
app.setGlobalPrefix('v1', { exclude: ['health'] });

Dans app.controller.ts :

typescript
@Get('health')
health() {
  return { status: 'ok' };
}

Sans l'exclusion { exclude: ['health'] }, le endpoint devient /v1/health au lieu de /health, et les readiness/liveness probes K8s renvoient 404.

11.2 SSL PostgreSQL

Chaque service utilisant TypeORM doit configurer SSL dans tous les endroits où une connexion est créée :

Dans app.module.ts (TypeORM.forRoot) :

typescript
ssl: process.env.POSTGRES_SSL === 'true' ? { rejectUnauthorized: false } : false,

Dans data-source.ts (si le service en a un — utilisé par les migrations) :

typescript
ssl: process.env.POSTGRES_SSL === 'true' ? { rejectUnauthorized: false } : false,

Piège : certains services (auth, orchestrator, notifications...) ont deux connexions TypeORM — une dans app.module.ts et une dans data-source.ts. Si on oublie l'une des deux, le service crash avec no pg_hba.conf entry... no encryption.

11.3 TLS Redis

Les services utilisant Redis (auth, notifications via BullMQ) doivent activer TLS :

ioredis (auth) :

typescript
...(process.env.REDIS_TLS === 'true' && { tls: {} }),

BullMQ (notifications) :

typescript
connection: {
  host: process.env.REDIS_HOST,
  port: parseInt(process.env.REDIS_PORT || '6379'),
  password: process.env.REDIS_PASSWORD,
  ...(process.env.REDIS_TLS === 'true' && { tls: {} }),
},

Récapitulatif par service

ServicePortTypeORM SSLdata-source.tsRedis TLSHealth endpoint
auth3001app.module.tsouioui (ioredis)oui
ledger-wallets3002app.module.tsouinonoui
customer-profiles-kyc3003app.module.tsouinonoui
orchestrator3004app.module.tsouinonoui
notifications3005app.module.tsouioui (BullMQ)oui
configuration3006app.module.tsouinonoui
file-service3007app.module.tsouinonoui
providers-gateway3008app.module.tsouinonoui
risk-engine3009app.module.tsouinonoui
service-catalog3010database.providers.tsnonnonoui
logs-reporting3011non (pas de DB)nonnonoui

Nex — Plateforme fintech CEMAC