Modernisation applicative avec Kiro + AWS Transform (ATX) : on a modernisé un application legacy Node.js en 2 jours - Le REX complet

Ippon Technologies · Octobre 2026 · 12 min de lecture

1. Une application qui "fonctionne" depuis dix ans  et c'est bien le problème

Club Manager v3 existe depuis 2015. Node.js, Express, MySQL, un serveur Debian avec PM2. L'auteur initial : Pierre Martin, 1 seul développeur, qui voulait que ça marche pour son club de foot de sa ville. Ça a marché. Cinq développeurs se sont relayés en dix ans sans jamais refondre l'architecture.

Résultat : 5 705 lignes de code, 56 fichiers, et une liste de dettes techniques qu'on repoussait à chaque sprint.

Ce projet, on l'a pris tel quel pour tester Kiro et AWS Transform Custom sur un cas réel. Pas une démo construite pour l'occasion. Une vraie base de code avec une vraie dette - représentative de ce qu'on voit régulièrement chez nos clients.

Ce qu'on a trouvé en ouvrant le capot (après une analyse de code via AWS Transform Custom ATX) :

  • 32 dettes techniques, dont 10 critiques
  • 17 vulnérabilités de sécurité : quatre points d'injection SQL, des mots de passe en MD5 avec fallback en clair en base, et un compte superadmin / Sup******2016 hardcodé dans le code depuis 2016
  • Zéro test. Aucune couverture, aucun workflow de non-régression
  • Un déploiement rsync vers un serveur à IP fixe, HTTP uniquement, TLS désactivé
  • Les credentials de base de données, le secret de session et le mot de passe SMTP en clair dans config.js - donc dans l'historique Git
Score de sécurité initial : 2/10.

Ce type d'application, vous en avez probablement dans votre parc. La question n'est pas de savoir si elle va poser problème un jour. C'est de savoir quand, et si vous serez prêts quand cela arrivera.

2. Kiro et AWS Transform Custom : ce que c'est vraiment

Avant les chiffres, un point de vocabulaire - ces outils sont récents et méritent une présentation honnête.

AWS Transform Custom (ATX) permet de définir des « transformation definitions » (TD) en langage naturel, puis de les exécuter de façon autonome sur une base de code. L'agent analyse le code, produit un plan que vous validez, applique les changements, valide les résultats, et génère des commits Git à chaque étape significative.

Il existe deux modes :

Les transformations ATX Standard sont managées par AWS - prêtes à l'emploi pour les cas courants. Sur ce projet, une seule était applicable : la mise à jour Node.js 14 → 22 LTS. On lance atx run, l'agent planifie et applique.

Les transformations ATX Custom sont des playbooks définis par l'utilisateur. Chaque TD est un fichier metadata.json et un prompt en langage naturel qui décrit précisément ce qu'on veut obtenir : critères d'entrée, étapes, critères de validation. C'est là que l'outil devient intéressant pour la modernisation sur mesure.

Kiro est l'IDE agent d'AWS. Ce qui le distingue d'un IDE classique : les Powers, des contextes MCP (Model Context Protocol) qui s'activent dynamiquement selon les mots-clés détectés dans le chat. Tapez « aws-transform » dans Kiro, le bon ensemble d'outils se charge automatiquement. Kiro intègre aussi un système de steering files (.kiro/) - des fichiers versionnés qui définissent le comportement de l'agent pour votre projet : specs, hooks, settings.

Un point important pour les décideurs : vous ne déléguez pas la décision à la machine. Chaque TD produit un plan que vous validez avant exécution. L'agent pose des questions quand il rencontre une ambiguïté. Et chaque transformation produit un plan JSON, un worklog, et un résumé de validation. La traçabilité est garantie étape par étape - c'est une contrainte de conception, pas une option.

3. Le ROI : ce que ça a coûté, ce que ça aurait coûté

Voici l'estimation de ce que cette modernisation aurait représenté en approche classique, sans IA :

Tâche

Durée estimée

Profil

Analyse codebase + documentation

5 jours

Tech Lead

Node.js 14 → 22 (compatibilité + tests)

3 jours

Dev Senior

Fix SQL Injection (4 points)

1 jour

Dev

Migration MD5 → bcrypt

1 jour

Dev Senior

Externaliser les credentials

1 jour

Dev

Callbacks → async/await (7 niveaux)

8 jours

Dev Senior

Containerisation Docker

2 jours

DevOps

Infrastructure Terraform

5 jours

Architecte Cloud

Tests unitaires, intégration, non-régression

5 jours

QA + Dev

Total

31 jours

2-3 profils

À 800 €/jour : 24 800 €, hors risques de régression et hors documentation manuelle. Délai de delivery : plus de six semaines.

Ce qu'on a réellement dépensé :

  • ~12,5 heures cumulatives d'exécution agents (autonomes, en tâche de fond et en parallèle, le durée réelle est beaucoup moins que ça)
  • 2 jours de travail humain : cadrage, définition des TDs, validation des plans, revue des résultats
  • Coût ATX : ≈ 30 $ pour l'ensemble des transformations
  • Coût consultant : 1 600 €
  • Coût Licence Kiro: 20€
  • Total : environ 1 650 €
ROI : ×15 sur le coût direct. 2 jours livrés contre 6 semaines estimées.

Deux nuances pour rester honnête. Ces estimations reposent sur notre expérience terrain, pas sur un projet concurrent réel en face-à-face. Et les 30 $ ATX supposent une infrastructure AWS et des accès déjà configurés - l'onboarding initial a un coût qu'on n'a pas comptabilisé ici. Même avec un facteur 2 ou 3 sur ces hypothèses, l'écart reste structurel.

Ce qui ne se quantifie pas aussi facilement, mais qui compte autant : la qualité de la traçabilité:

  • Avant : des commits peu structurés et mal documentés. 
  • Après : 43 commits structurés, chaque step validé avec build status ✓, un worklog par transformation, 31 fichiers de documentation générés sur l'architecture. 

Sur les projets qu'on audite régulièrement, ce niveau de traçabilité dans les mêmes contraintes de temps est rare.

4. Analyse de code et documentation

Avant de transformer quoi que ce soit, il faut savoir ce qu'on a vraiment. ATX dispose pour ça d'une transformation managée dédiée : AWS/comprehensive-codebase-analysis.

atx custom def exec -n AWS/comprehensive-codebase-analysis

Elle combine analyse statique, LLMs et Graph Neural Networks pour produire une documentation structurée complète de votre codebase. Pour l’instant on ne sait pas quels LLM sont utilisés par AWS pour le traitement des agents.  Sur Club Manager v3 : 123 minutes d'exécution autonome, 31 fichiers Markdown, organisés en sept répertoires :

  • architecture/   vue système, composants, dépendances, patterns
  • analysis/   métriques code, sécurité, complexité cyclomatique, dépendances
  • behavior/   flux de données, logique métier, authentification, gestion des erreurs
  • technical-debt/   résumé, plan de remédiation, composants obsolètes
  • migration/   stratégie, plan d'exécution, risques, tests requis
  • reference/   API, base de données, variables d'environnement, configuration
  • diagrams/   architecture, flux de données, modèle de données

Concrètement : 5 705 lignes analysées, 13 modules JS cartographiés, 35 templates EJS référencés, complexité cyclomatique calculée pour chaque composant. Et une recommandation de priorité : AWS/nodejs-version-upgrade comme point d'entrée obligatoire, avec l'ordre de migration des composants et les critères de validation associés.

C'est cette documentation qui sert de contexte pour toutes les transformations custom qui suivent. L'agent ne redécouvre pas le code à chaque transformation - il travaille sur une base documentée.

Une analyse de cette profondeur, faite manuellement par un Tech Lead expérimenté, représente 4 à 5 jours. Et elle serait rarement aussi exhaustive sur les aspects sécurité et complexité cyclomatique - personne ne prend ce temps sous pression.

5. Les transformations custom : comment ça marche en pratique

Les 6 TDs custom : bilan complet

#

Transformation

Durée

Fichiers

Delta

01

Externaliser les credentials

55 min

8

+137 / -80

02

SQL Injection → requêtes paramétrées

56 min

3

+15 / -15

03

MD5 → bcrypt

39 min

5

+15 / -27

04

Containerisation ECS Fargate

45 min

5

+204 / 0

05

Callbacks → async/await (7 niveaux)

197 min

10

+1 286 / -1 265

06

Infrastructure as Code Terraform

61 min

15

+1 261 / 0

La transformation callbacks → async/await mérite une mention à part. Sept niveaux d'imbrication, 197 minutes d'agent, 10 fichiers. C'est le type de refactoring que les équipes repoussent précisément parce qu'il est long, répétitif, et très propice aux régressions discrètes. L'agent l'a produit proprement, avec worklog détaillé et résumé de validation.

On va prendre la containerisation pour ECS Fargate (TD custom n°4) comme exemple - elle illustre bien le mécanisme, parce qu'elle ne corrige pas un bug existant, elle ajoute une capacité qui n'existait pas.

Étape 1  Décrire la transformation à Kiro

On lance atx -t depuis Kiro et on décrit l'intention en langage naturel :

I have a Node.js 22 Express monolithic application that I want to containerize for deployment on AWS ECS/Fargate.
The app is a club management system with:
- Express.js server (server.js) running on port 3000
- MySQL database (connection config already in environment variables)
- File uploads stored in uploads/ directory
- EJS server-side rendering
- All config already externalized to environment variables via .env file.
I want to:
1. Create an optimized multi-stage Dockerfile using node:22-alpine,   with a build stage and production stage. Copy only production files,   run npm ci --only=production, expose port 3000, use a non-root user   for security.
2. Create a .dockerignore file excluding node_modules, .env, uploads/,   ATXDocumentation/, .git, *.log
3. Create a docker-compose.yml with two services: app (built from Dockerfile) and mysql (mysql:8.0 image) with volumes for data persistence and uploads. Include health checks. Load app env vars from .env file.
4. Create a docker-compose.override.yml for local development with volume mounts for live reload.
5. Update README.md with Docker setup and usage instructions.
Verification: docker build -t club-manager . should succeed without errors.

ATX analyse le contexte, génère la transformation definition, nous demande de choisir un nom à la TD (ici : on l’a appelé: LEGACY-APP-MODERNIZATION_Containerize-Monolith-for-ECS-Fargate) et retourne le nom de la TD publiée dans votre registre utilisateur (compte AWS associé au service Transform).

Étape 2  Lancer l'exécution

On passe l'exécution en tâche de fond pour ne pas bloquer l'IDE :

# Nettoyage de la session précédente
[ -d ~/.aws/atx/custom/atx-agent-session ] && \
  find ~/.aws/atx/custom/atx-agent-session \
    -maxdepth 1 -type f \
    \( -name "*.sh" -o -name "*.log" -o -name "*.pid" \
       -o -name "*.exit" -o -name "*.zip" \) \
    -delete 2>/dev/null || true
# Création et lancement
mkdir -p ~/.aws/atx/custom/atx-agent-session
cat > ~/.aws/atx/custom/atx-agent-session/run_td.sh << 'RUNNER'
#!/bin/bash
atx custom def exec \
  -n LEGACY-APP-MODERNIZATION_Containerize-Monolith-for-ECS-Fargate  -p /path/to/legacy-app-aws-transform  -x -t
echo $? > ~/.aws/atx/custom/atx-agent-session/transform.exit
RUNNER
chmod +x ~/.aws/atx/custom/atx-agent-session/run_td.sh
nohup ~/.aws/atx/custom/atx-agent-session/run_td.sh \
  > ~/.aws/atx/custom/atx-agent-session/transform.log 2>&1 &
# Suivi du log de conversation
grep "Conversation log:"  ~/.aws/atx/custom/atx-agent-session/transform.log

L'agent prend la main. 45 minutes d'exécution parallélisée (vous l'avez compris, la durée réelle est beaucoup moins que ça) :

  • 5 fichiers créés
  • 204 lignes ajoutées
  • Dockerfile multi-stage
  • non-root user
  • health check intégré.

Au-delà du code applicatif, Kiro a généré les specs CI/CD via ses steering files (dans .kiro/specs/) :

  • requirements.md : 10 exigences structurées, ~60 critères WHEN/THEN/IF formels  ~60 min avec Kiro contre ~2,5 jours manuellement (×20)
  • design.md : flowchart Mermaid auto-généré, tableau jobs × dépendances   ~45 min contre ~1,5 jour (×16)
  • tasks.md : 15 tâches avec steps de code précis et exigences mappées   ~30 min contre ~1 jour (×16)
Total Kiro Specs : 2h15 de rédaction collaborative contre ~5 jours manuellement (TechLead sans IA).

6. Ce qu'ATX ne sait pas faire : appliquer vos standards de craft

Il y a un angle mort qu'on doit nommer clairement, parce que l'ignorer serait rendre un mauvais service à quiconque voudrait reproduire cette démarche en production.

ATX exécute ce qu'on lui demande. Les tests qu'il génère vérifient que le code ne régresse pas fonctionnellement et ils le font bien. Mais ils ne savent pas que nos Software Engineers appliquent des règles de clean code précises : séparation des responsabilités, inversion de dépendance, ports et adaptateurs. Ils ne savent pas que nos conventions de test distinguent un test d'unité métier d'un test d'intégration infrastructure.

Conséquence concrète sur ce projet : la transformation callbacks → async/await a produit du code fonctionnel et lisible. Mais ClubService.js reste un God Object de 929 lignes. Les tests générés couvrent les comportements, pas les contrats d'interface. Et aucune transformation custom n'a poussé vers une structure hexagonale, parce qu'on ne lui a pas demandé.

Ce n'est pas un défaut d'ATX, c'est une limite de scope qu'il faut anticiper.

La réponse : une TD custom "Ippon Engineering Standards"

L'idée défendue ici, et qu'on va expérimenter sur les prochains projets, c'est de compléter le backlog ATX par une transformation dédiée aux standards de craft Ippon. Elle ressemblerait à ça :

You are refactoring a Node.js Express application to meet Ippon Technologies engineering standards. Apply the following:
Architecture:
- ClubService.js must be split into domain-scoped services (MemberDomain, PaymentDomain, EventDomain) with no direct database calls in business logic.
Clean Code:
- Functions must have a single responsibility and stay under 20 lines. Extract helpers when a function does more than one thing.
- No magic strings or numbers: extract to named constants.
- Dependency injection over module-level singletons.
Testing standards:
- Unit tests must test domain logic only, with all infrastructure dependencies injected and mockable.
- Integration tests must be clearly separated from unit tests (different directories, different npm scripts).
- Each test file must follow Arrange / Act / Assert structure, with explicit test descriptions that read as specifications.
Verification: npm run test:unit and npm run test:integration must both pass. No domain logic in route handlers.

Cette TD ne remplace pas les transformations de migration, elle vient après. L'ordre compte : on modernise d'abord le runtime et la sécurité pour avoir une base stable, puis on applique les standards de craft sur un code déjà lisible. Inverser l'ordre reviendrait à refactorer du code qui a encore des injections SQL.

Ce qu'on vise avec cette couche supplémentaire : des livrables ATX qui respectent non seulement les standards AWS, mais aussi la façon de faire Ippon et qui peuvent donc être maintenus par nos équipes sans coût d'adaptation.

7. Résultats : avant / après

Le code

Critère

Avant

Après

Runtime

Node.js 14 (EOL)

Node.js 22 LTS

Déploiement

rsync manuel / PM2

ECS Fargate, auto-scaling

Secrets

Hardcodés dans config.js

AWS Secrets Manager

SQL Injection

4 points vulnérables

0  requêtes paramétrées

Mots de passe

MD5 + plaintext en DB

bcrypt, salt rounds=10

Infra as Code

Aucune

846 lignes Terraform validées

Async pattern

Callbacks 7 niveaux

async/await + try/catch

CI/CD

Aucun

GitHub Actions + ECR + ECS

Tests

0 lignes

2 815 lignes, tous verts

Score sécurité

2/10

7/10 estimé

Les tests

2 815 lignes réparties sur trois niveaux, tous passent.

Les tests unitaires couvrent 6 services avec isolation totale (jest.mock sur la base de données) : MemberService (339 lignes, incluant format d'identifiant M00001+, bcrypt, et filtres), PaymentService, FacilityService (6 cas de chevauchement horaire), TeamService, ReportService, EventService. Cinq propriétés fast-check sur des invariants métier par exemple qu'un paiement avec date passée est toujours marqué en retard, ou qu'une injection SQL sur /login ne produit jamais de redirection 302.

Les tests d'intégration utilisent Supertest avec un vrai PostgreSQL 15 en container CI. On y valide que le rôle member reçoit bien un 403 sur les routes admin, et qu'aucune route ne fuite de données sensibles même avec un rôle insuffisant.

Les 3 workflows de non-régression couvrent le cycle de vie complet d'un adhérent (7 étapes : login → liste → création → détail → mise à jour → renouvellement → suppression douce), le workflow paiement (5 étapes), et la réservation d'événement avec annulation. 785 lignes au total, timeout CI de 10 minutes, rollback automatique si un test post-déploiement échoue.

L'infrastructure

L'architecture est passée d'un serveur Debian statique à un cluster ECS Fargate multi-AZ dans un VPC dédié (10.0.0.0/16), avec RDS MySQL 8.0 en subnet privé, Application Load Balancer en frontal, Secrets Manager pour les credentials, CloudWatch pour les logs sur 30 jours, et IAM Roles séparés pour les tâches. L'ensemble est décrit en 846 lignes Terraform réparties sur 8 fichiers terraform validate passe sans erreur.

Le Git

43 commits structurés (Agent ATX Bot, plusieurs commit au sein de la même exécution d'une TD), chaque step validé avec build status ✓. 3 847 lignes nettes modifiées, 86 000 supprimées (node_modules inclus dans la migration Node.js).

8. Ce qu'on retient et ce qu'on ne dit pas

On n'a pas réécrit Club Manager v3. On l'a modernisé ce qui est très différent. Les données préservées, les utilisateurs ne voient aucune différence en surface. Ce qui a changé, c'est tout ce qui est en dessous : le runtime, la sécurité, le déploiement, la capacité à faire évoluer le code sans provoquer une régression à chaque merge.

ATX custom fonctionne bien sur un périmètre précis : migrations de runtime, corrections de patterns de sécurité connus, refactoring structurel mécanique (callbacks → async, require → ESM), containerisation depuis une app classique, génération d'IaC depuis une architecture cible définie. C'est là que le rapport effort / résultat est le plus favorable et c'est précisément là que les équipes humaines perdent le plus de temps.

Ce que l'outil ne fait pas : décider de l'architecture cible, migrer les données existantes (les mots de passe déjà en MD5 en production, ça ne se met pas à jour automatiquement), ou trancher les questions métier dans les tests. Ces décisions restent humaines. Et c'est normal.

La vraie question pour vos équipes n'est pas technique. C'est organisationnelle : comment intégrer ces outils dans vos processus de revue, qui valide les plans de transformation avant exécution, comment vous assurez que les commits générés restent aussi lisibles que ceux écrits à la main. Sur ce dernier point, les 43 commits de ce projet sont mieux documentés que beaucoup de projets qu'on a audités. Ce n'est pas un argument de vente c'est une observation.

Si vous avez des applications dans la situation de Club Manager v3 dans votre parc et que la plupart des organisations en ont, c'est une conversation qui vaut la peine d'être engagée.