<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Patrick Turcotte</title>
    <description>The latest articles on DEV Community by Patrick Turcotte (@patrek).</description>
    <link>https://dev.to/patrek</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F895906%2Ff193fac6-46bf-4be8-b597-b5f6fcb8d37b.jpeg</url>
      <title>DEV Community: Patrick Turcotte</title>
      <link>https://dev.to/patrek</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/patrek"/>
    <language>en</language>
    <item>
      <title>Développer pour le déploiement distribué</title>
      <dc:creator>Patrick Turcotte</dc:creator>
      <pubDate>Sun, 14 Dec 2025 05:00:00 +0000</pubDate>
      <link>https://dev.to/onepoint/developper-pour-le-deploiement-distribue-4m64</link>
      <guid>https://dev.to/onepoint/developper-pour-le-deploiement-distribue-4m64</guid>
      <description>&lt;h1&gt;
  
  
  Bonnes pratiques et considérations
&lt;/h1&gt;

&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;L'idée de cet article m'est venue, en début d'année, après ma publication sur les éléments à considérer quand on &lt;a href="https://dev.to/onepoint/demarrer-un-projet-a-partir-de-zero-12b3"&gt;démarre un projet de développement&lt;/a&gt; et en discutant avec des collègues qui commençaient à apprendre un environnement cloud.&lt;/p&gt;

&lt;p&gt;Les applications sont maintenant souvent déployées dans des environnements distribués, que ce soit via des fournisseurs cloud (AWS, Azure, GCP), des orchestrateurs comme Kubernetes, des services managés, des fonctions serverless, ou même des infrastructures on-premise distribuées.&lt;/p&gt;

&lt;p&gt;Le développement d'applications destinées à ces environnements distribués nécessite de prendre en considérations plusieurs aspects spécifiques.&lt;br&gt;
Voici une liste de pratiques et de considérations clés pour développer des applications distribuées résilientes et scalables.&lt;/p&gt;

&lt;p&gt;Pour les fins de cet article, nous énoncerons principalement des considérations pour les services à durée de vie prolongée.&lt;br&gt;
La plupart de ces considérations s'appliquent également aux fonctions serverless et aux applications événementielles.&lt;/p&gt;

&lt;h2&gt;
  
  
  Multiples instances jetables pour rendre un même service
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;Plusieurs clones, une seule mission&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;La considération la plus importante est que votre application doit être conçue pour fonctionner dans un environnement où plusieurs instances peuvent être exécutées simultanément. Cela signifie qu'une instance de votre application ne doit pas interférer avec une autre instance, et qu'il faut éviter la duplication de traitement. De plus, votre application ne doit pas dépendre d'un état local ou de ressources spécifiques à une instance, car ces éléments ne sont pas garantis d'être disponibles ou persistants entre les instances ou les redémarrages.&lt;/p&gt;

&lt;p&gt;Que ce soit pour scaler horizontalement (ajouter plus d'instances) ou pour la résilience (redémarrer une instance défaillante), parce que le nombre d'instances change en fonction de la charge réelle ou anticipée, en fonction de l'heure, etc., votre application doit être capable de gérer plusieurs instances sans conflit.&lt;/p&gt;

&lt;p&gt;Elle sera aussi probablement démarrée sans intervention humaine. Vous devez donc conserver ces aspects en tête lors de la conception et du développement de votre application.&lt;/p&gt;

&lt;h2&gt;
  
  
  Architecture derrière un load balancer/reverse proxy
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;Comme une répartitrice d'appels en centre de services : chaque requête est envoyée au bon département — facturation, support, ou comptes — selon ce qu'elle demande.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Dans la plupart des cas, les instances de votre application seront déployées derrière un load balancer (équilibreur de charge).&lt;br&gt;
Le load balancer distribue le trafic entrant entre les différentes instances de votre application.&lt;br&gt;
L'utilisation de sticky sessions permet de faire en sorte que le load balancer va envoyer le trafic qui revient à la même instance.&lt;br&gt;
Mais, il se peut que l'instance qui a fait le traitement initial ne soit plus disponible (scale down, mise à jour, etc.) ou que le load balancer ne supporte pas les sessions sticky, cela signifie que votre application doit être capable de prendre le relais d'une requête sans avoir répondu à la requête précédente dans le workflow.&lt;/p&gt;

&lt;p&gt;Dans les architectures modernes, le load balancer ou l'API Gateway peut aussi router vers des services différents selon la requête :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  Par chemin (path-based routing), ex. : &lt;code&gt;/api/users&lt;/code&gt; → service Utilisateurs, &lt;code&gt;/api/orders&lt;/code&gt; → service Commandes&lt;/li&gt;
&lt;li&gt;  Par hôte (host-based routing), ex. : &lt;code&gt;api.example.com&lt;/code&gt; → API, &lt;code&gt;static.example.com&lt;/code&gt; → ressources statiques&lt;/li&gt;
&lt;li&gt;  Par en-tête ou version d'API (header/version routing), ex. : &lt;code&gt;X-Client: mobile&lt;/code&gt; ou &lt;code&gt;Accept: application/vnd.company.v2+json&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;  Par méthode ou port (rare), selon les contraintes techniques&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Les conséquences du côté développement sont que vous devez éviter les hypothèses d'état de session local, car une requête peut arriver à un autre service ou une autre instance. Il devient très utile de propager les identifiants de corrélation pour tracer la requête à travers plusieurs services.&lt;/p&gt;

&lt;h2&gt;
  
  
  Externaliser la configuration
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;Externaliser la configuration, c'est comme insérer une carte SIM dans un téléphone : même appareil, réglages adaptés au réseau. En changeant de SIM, on peut aussi changer de fournisseur — Bell, Vidéotron, Orange — sans toucher au téléphone lui-même.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Un aspect important du développement pour le déploiement distribué (dont le cloud) est de séparer la configuration de l'application du code lui-même.&lt;br&gt;
Cela permet notamment de modifier la configuration sans avoir à recompiler l'application.&lt;/p&gt;

&lt;p&gt;Une pratique très courante est d'utiliser des variables d'environnement pour fournir la configuration à l'application. Voir &lt;a href="https://12factor.net/fr/config" rel="noopener noreferrer"&gt;https://12factor.net/fr/config&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Les différents fournisseurs cloud offrent aussi un service d'externalisation de la configuration, comme AWS Systems Manager Parameter Store, Azure App Configuration ou GCP Secret Manager.&lt;br&gt;
Ces services permettent de stocker et de gérer la configuration de manière sécurisée et centralisée. Il est aussi possible de déployer votre propre service de configuration, comme Consul, etcd ou Spring Cloud Config. Par contre, vous devrez adapter votre application pour qu'elle puisse récupérer la configuration à partir de ces services.&lt;/p&gt;

&lt;p&gt;Le choix final que vous ferez dépendra de si vous prévoyez déployer votre application dans un seul fournisseur cloud ou dans plusieurs ou s'il est possible que vous changiez éventuellement de fournisseur. Il est probablement plus prudent d'utiliser une solution agnostique au fournisseur cloud pour éviter le &lt;em&gt;vendor locking&lt;/em&gt;, c'est-à-dire de ne pouvoir déployer que sur un seul fournisseur.&lt;/p&gt;

&lt;h2&gt;
  
  
  Feature flags et configuration dynamique
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;Les feature flags, c'est comme les scènes post-crédits Marvel : on peut les activer pour certains, les cacher pour d'autres, et les couper net si ça tourne mal. Zéro recompilation, juste un interrupteur.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Les feature flags (drapeaux de fonctionnalités) permettent d'activer ou désactiver des fonctionnalités sans recompiler l'application, ou même la redéployer si vous mettez en place une façon d'en prendre compte pendant que l'application roule. Cette stratégie peut être très utile, notamment pour les cas d'utilisation suivants.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Déploiements progressifs&lt;/strong&gt; : Activer une nouvelle fonctionnalité pour un pourcentage d'utilisateurs ou certains groupes d'utilisateurs&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;A/B testing&lt;/strong&gt; : Tester différentes versions d'une fonctionnalité&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Kill switch&lt;/strong&gt; : Désactiver rapidement une fonctionnalité problématique en production sans redéployer&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Environnements spécifiques&lt;/strong&gt; : Activer des fonctionnalités seulement dans certains environnements, comme dev ou qa mais pas en production pour valider avant le déploiement complet sans devoir gérer plusieurs branches de code.&lt;/p&gt;

&lt;p&gt;Des outils comme LaunchDarkly, Unleash, Split.io, ou AWS AppConfig peuvent être utilisés pour gérer les feature flags.&lt;/p&gt;

&lt;h2&gt;
  
  
  Gestion des secrets
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;Mettre des secrets dans le code source, c'est comme cacher la clé de la maison sous le paillasson : tout le monde sait où chercher. Utilisez un vrai coffre-fort.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Ne jamais stocker des secrets (mots de passe, clés API, certificats) directement dans le code ou dans les fichiers de configuration versionnés.&lt;/p&gt;

&lt;p&gt;Utilisez plutôt des services de gestion des secrets qui offrent des fonctionnalités de sécurité avancées, comme des services clouds dédiés (AWS Secrets Manager, Azure Key Vault, GCP Secret Manager), le système d'encryption de votre orchestrateur (Kubernetes Secrets avec encryption at rest activée), ou des outils tiers comme HashiCorp Vault ou SOPS.&lt;/p&gt;

&lt;p&gt;Ces solutions offrent plusieurs avantages, comme l'encryption des secrets au repos et en transit, un contrôle d'accès granulaire, la rotation automatique des secrets, et l'audit des accès.&lt;/p&gt;

&lt;h2&gt;
  
  
  Sauvegarde de fichiers de travail ou téléversés
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;Écrire sur le disque local en cloud, c'est laisser vos notes sur la table du café : ça marche… jusqu'au ménage.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Imaginons une application qui génère un rapport (PDF, Excel, etc.) à partir de données fournies par l'utilisateur.&lt;/p&gt;

&lt;p&gt;Dans un scénario "classique", l'application pourrait générer le rapport sur le disque dur local de l'instance, puis le rendre disponible pour téléchargement.&lt;/p&gt;

&lt;p&gt;Par contre, dans un environnement à multiple instance, il faut mettre ce fichier soit dans un stockage partagé, un volume réseau, ou, au pire, la base de données.&lt;/p&gt;

&lt;p&gt;Les fournisseurs offrent des services de stockage, comme AWS S3, AWS EFS, Azure Blob Storage, Azure Files, GCP Cloud Storage ou GCP Filestore, qui peuvent être utilisés pour stocker ces fichiers intermédiaires.&lt;/p&gt;

&lt;h2&gt;
  
  
  Tâches périodiques / Cron Job
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;Les crons en multi-instances, c'est comme nettoyer la maison en colocation : si 5 colocataires font le ménage au même moment pour la même pièce, c'est du travail gaspillé. Il faut qu'un seul le fasse à la fois. Sinon, même pièce nettoyée 5 fois = 5 fois le travail, 5 fois le coût.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Les tâches périodiques, comme l'envoi de courriel de rappel, la création de rapports ou la purge de données sont fréquentes dans les applications.&lt;/p&gt;

&lt;p&gt;Dans un environnement distribué, il est important de s'assurer que ces tâches ne sont pas exécutées simultanément par plusieurs instances de l'application.&lt;/p&gt;

&lt;p&gt;Pour y arriver, il faut réfléchir à une façon de synchroniser l'exécution de ces tâches. Plusieurs approches sont possibles :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Utiliser un service de planification externe, comme AWS CloudWatch Events, Azure Logic Apps ou GCP Cloud Scheduler, pour déclencher les tâches périodiques.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Utiliser un mécanisme de verrouillage distribué, comme une entrée dans une base de données ou un service de cache distribué (Redis, Memcached) pour s'assurer qu'une seule instance exécute la tâche à un moment donné.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Utiliser une bibliothèque de planification comme Quartz Scheduler ou autre similaire.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Il peut être intéressant de développer une mécanique qui permet de lancer des tâches spécifiques, qui peuvent être appelées par le service de planification externe ou par un job interne avec un verrouillage distribué. Par exemple de créer des endpoints HTTP sécurisés qui déclenchent les tâches périodiques. Dans ce cas, des endpoints complémentaires pour obtenir le statut des tâches peuvent aussi être utiles pour le monitoring.&lt;/p&gt;

&lt;p&gt;L'important, c'est de faire en sorte que les tâches périodiques soient exécutées de manière fiable et sans conflit entre les différentes instances de l'application.&lt;/p&gt;

&lt;h2&gt;
  
  
  Gestion de l'état et des sessions
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;Les sessions en déploiement distribué, c'est un vestiaire : on présente son ticket et on retrouve son manteau, peu importe la porte d'entrée ou le préposé.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Dans un environnement distribué avec plusieurs instances, la gestion de l'état utilisateur (sessions) devient critique. Si un utilisateur se connecte à une instance et que sa prochaine requête est routée vers une autre instance, l'application doit pouvoir récupérer les informations de la session. Plusieurs approches existent pour gérer les sessions dans un environnement distribué.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Sessions stateless&lt;/strong&gt; : Utiliser des tokens JWT (JSON Web Tokens) qui contiennent toutes les informations nécessaires. Le client transmet le token à chaque requête. Il peut le transmettre par header, par cookie, ou dans le corps de la requête.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Cache distribué&lt;/strong&gt; : Stocker les sessions dans un cache distribué comme Redis ou Memcached, accessible par toutes les instances.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Sticky sessions&lt;/strong&gt; : Configurer le load balancer pour router toujours le même utilisateur vers la même instance (moins recommandé car crée des dépendances et ne fonctionnera pas si l'instance est arrêtée).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Base de données&lt;/strong&gt; : Stocker les sessions dans la base de données (moins performant mais plus simple).&lt;/p&gt;

&lt;p&gt;L'approche à privilégier dépendra de vos besoins spécifiques, mais les sessions stateless (JWT) ou le cache distribué (Redis, Memcached) souvent généralement préférés. Les sessions stateless permettent de réduire la dépendance à un stockage centralisé et facilitent le scaling horizontal. Par contre, la révocation immédiate des sessions peut être plus complexe avec JWT. De l'autre côté, l'utilisation d'un cache distribué offre une gestion centralisée des sessions, mais introduit une dépendance supplémentaire et peut nécessiter une infrastructure plus complexe.&lt;/p&gt;

&lt;h2&gt;
  
  
  Persistance et transactions de base de données
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;La base de données, c'est comme le seul guichet de la banque : si 10 clients ouvrent chacun leur porte (connexion), c'est du gaspillage. Il faut une file d'attente partagée. Et si 10 clients payent la même facture en même temps, il faut éviter les doublons. Une seule transaction réussie, pas 10 écritures identiques.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Dans un environnement distribué, la gestion des transactions de base de données nécessite une attention particulière.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Connexions à la base de données&lt;/strong&gt; : Utilisez un pool de connexions pour optimiser l'utilisation des ressources. Configurez le nombre maximum de connexions en fonction du nombre d'instances.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Transactions distribuées&lt;/strong&gt; : Évitez les transactions distribuées (2PC - Two-Phase Commit) autant que possible, car elles sont complexes et réduisent la performance. Privilégiez le pattern Saga pour gérer les transactions sur plusieurs services.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Idempotence&lt;/strong&gt; : Concevez vos opérations de base de données pour être idempotentes, c'est-à-dire qu'elles produisent le même résultat même si elles sont exécutées plusieurs fois.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Retry et resilience&lt;/strong&gt; : Implémentez des mécanismes de retry pour gérer les échecs temporaires de connexion à la base de données.&lt;/p&gt;

&lt;h3&gt;
  
  
  Migrations de schéma de base de données
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;Migrer le schéma, c'est rénover sans fermer le magasin : on déplace les rayons, on garde les clients.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Les migrations de schéma dans un environnement distribué nécessitent une planification minutieuse.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Migrations forward-compatible&lt;/strong&gt; : Les changements doivent être compatibles avec l'ancienne version pendant le déploiement, on peut ainsi déployer les nouvelles instances avant de retirer les anciennes ou même faire un retour en arrière applicatif si nécessaire.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Outils de migration&lt;/strong&gt; : Utilisez Liquibase, Flyway, ou des outils natifs (Alembic pour Python, migrate pour Go)&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Déploiements testés&lt;/strong&gt; : Pour les changements, particulièrement les changements majeurs, il est important de tester la migration de la base de données avant d'appliquer à la production&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Migrations à l'arrêt vs au démarrage&lt;/strong&gt; : Décidez si les migrations s'exécutent avant ou pendant le déploiement&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Rollback&lt;/strong&gt; : Préparez toujours un plan de rollback pour les migrations complexes&lt;/p&gt;

&lt;h3&gt;
  
  
  Patterns pour les changements de schéma
&lt;/h3&gt;

&lt;p&gt;Il existe certains patterns courants pour gérer les changements de schéma de base de données dans un environnement distribué. Ils permettent de minimiser les interruptions de service et de garantir la compatibilité entre les versions.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Expand-Contract Pattern&lt;/strong&gt; :&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Expand : Ajoutez la nouvelle colonne/table&lt;/li&gt;
&lt;li&gt;Dual-write : Écrivez dans l'ancienne et la nouvelle structure&lt;/li&gt;
&lt;li&gt;Migrate : Migrez les anciennes données&lt;/li&gt;
&lt;li&gt;Contract : Supprimez l'ancienne structure&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Versioning des changements&lt;/strong&gt; : Quand les changements de schéma affectent l'API, utilisez le versioning (v1, v2)&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Mise en cache et performance
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;Le cache, c'est comme garder les documents importants sur votre bureau plutôt qu'au sous-sol : on accède vite à ce qu'on utilise souvent. Mais attention, il faut parfois faire le ménage pour éviter de travailler avec des versions périmées.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Le cache est crucial pour la performance dans un environnement distribué. Obtenir une information en mémoire est beaucoup plus rapide que d'aller la chercher dans une base de données ou un service externe.&lt;/p&gt;

&lt;h3&gt;
  
  
  Types de cache
&lt;/h3&gt;

&lt;p&gt;Il existe plusieurs types de cache que vous pouvez utiliser.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Cache en mémoire local&lt;/strong&gt; : Rapide mais non partagé entre instances (Caffeine, Guava Cache)&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Cache distribué&lt;/strong&gt; : Partagé entre toutes les instances (Redis, Memcached, Hazelcast)&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;CDN&lt;/strong&gt; : Pour les ressources statiques (CloudFront, Azure CDN, Cloud CDN, autres)&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;HTTP caching&lt;/strong&gt; : Utilisez les headers HTTP (Cache-Control, ETag) pour le cache côté client&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Reverse proxy cache&lt;/strong&gt; : Cache comme varnish&lt;/p&gt;

&lt;h3&gt;
  
  
  Stratégies de cache
&lt;/h3&gt;

&lt;p&gt;La stratégie de cache dépendra de vos besoins spécifiques.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Cache-aside&lt;/strong&gt; : L'application vérifie le cache, puis la base de données si nécessaire&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Write-through&lt;/strong&gt; : Les données sont écrites dans le cache et la base de données simultanément&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Write-behind&lt;/strong&gt; : Les données sont écrites dans le cache d'abord, puis dans la base de données de façon asynchrone&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Invalidation&lt;/strong&gt; : Définissez des stratégies claires pour invalider le cache (TTL, événements)&lt;/p&gt;

&lt;h3&gt;
  
  
  Invalidation et nettoyage du cache
&lt;/h3&gt;

&lt;p&gt;L'un des défis les plus importants avec le cache est de savoir quand le nettoyer ou l'invalider. Un cache obsolète peut causer des bugs difficiles à diagnostiquer.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;TTL (Time-To-Live)&lt;/strong&gt; : Définissez une durée de vie maximale pour chaque entrée du cache. Après ce délai, l'entrée est automatiquement supprimée ou marquée comme expirée.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Invalidation par événement&lt;/strong&gt; : Lorsque des données sont modifiées dans la base de données, invalidez ou mettez à jour les entrées de cache correspondantes. Utilisez des event listeners ou des patterns pub/sub.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Cache tagging&lt;/strong&gt; : Associez des tags aux entrées de cache pour pouvoir invalider plusieurs entrées liées d'un coup (par exemple, toutes les entrées liées à un utilisateur spécifique).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Versioning&lt;/strong&gt; : Incluez une version dans la clé de cache. Quand vous déployez un changement de format, incrémentez la version pour invalider automatiquement les anciennes entrées.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Flush sélectif vs global&lt;/strong&gt; : Évitez de vider tout le cache (flush) sauf en cas d'urgence. Préférez l'invalidation ciblée pour maintenir les performances.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Cache warming&lt;/strong&gt; : Après un vidage ou au démarrage, préremplissez le cache avec les données les plus utilisées pour éviter une charge soudaine sur la base de données.&lt;/p&gt;

&lt;p&gt;Certaines considérations sont importantes pour l'invalidation et le nettoyage de la cache pour les environnements distribués. Si vous utilisez un cache distribué (Redis, Memcached), l'invalidation sera visible par toutes les instances. Par contre, si vous utilisez un cache local en mémoire, chaque instance aura son propre cache. Vous devrez propager les événements d'invalidation à toutes les instances (via pub/sub ou message queue). Documentez clairement votre stratégie d'invalidation pour chaque type de données cachées.&lt;/p&gt;

&lt;h3&gt;
  
  
  Autres considérations importantes
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Attention au &lt;strong&gt;thundering herd&lt;/strong&gt; : quand plusieurs instances tentent de recharger le même cache expiré simultanément. On revient ici avec la notion selon laquelle plusieurs instances tentent de faire la même chose en même temps. On peut mettre en place une stratégie de &lt;strong&gt;grace mode&lt;/strong&gt; pour mitiger le problème. &lt;/li&gt;
&lt;li&gt;Utilisez des clés de cache bien structurées pour faciliter l'invalidation ciblée&lt;/li&gt;
&lt;li&gt;Surveillez le taux de hit/miss du cache pour optimiser la configuration&lt;/li&gt;
&lt;li&gt;Loggez les invalidations de cache pour faciliter le debugging&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Considérations pour l'équipe devops
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;Le devops, c'est comme piloter un avion qu'on n'a pas construit : on a besoin d'instruments de bord clairs, de voyants qui s'allument au bon moment, et d'un manuel qui dit ce qu'il faut faire si ça tourne mal.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;L'équipe qui va déployer et gérer l'application a des besoins spécifiques qui doivent être pris en compte dès le début du développement.&lt;/p&gt;

&lt;h3&gt;
  
  
  Observabilité : Logs, métriques et traces
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;Et quand l'avion a des problèmes, on devient détective : les logs racontent ce qui s'est passé dans le cockpit, les métriques montrent les tendances du vol, et les traces suivent la route à travers le ciel. Sans ces instruments, on enquête à l'aveugle dans le brouillard.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;L'observabilité est cruciale dans un environnement distribué où il peut être difficile de diagnostiquer les problèmes.&lt;/p&gt;

&lt;h4&gt;
  
  
  Logging structuré
&lt;/h4&gt;

&lt;p&gt;Utilisez un format de log structuré tel &lt;strong&gt;JSON&lt;/strong&gt; pour faciliter la recherche et l'analyse.&lt;br&gt;
Incluez un identifiant de corrélation (&lt;strong&gt;correlation ID&lt;/strong&gt;) dans chaque log pour tracer une requête à travers plusieurs services et instances.&lt;br&gt;
&lt;strong&gt;Centralisez vos logs&lt;/strong&gt; dans un système comme AWS CloudWatch, Azure Monitor, GCP Cloud Logging, ELK Stack (Elasticsearch, Logstash, Kibana), Datadog ou Loki.&lt;/p&gt;

&lt;p&gt;Évitez de logger des informations sensibles (mots de passe, tokens, données personnelles).&lt;br&gt;
Évitez aussi de logger trop d'informations pour ne pas noyer les logs importants.&lt;br&gt;
Si possible, utilisez des bibliothèques de logging qui supportent la reconfiguration dynamique du niveau de log (DEBUG, INFO, WARN, ERROR) sans redémarrer l'application.&lt;/p&gt;

&lt;h4&gt;
  
  
  Métriques
&lt;/h4&gt;

&lt;p&gt;Exposez des &lt;strong&gt;métriques&lt;/strong&gt; sur la santé et la performance de votre application (temps de réponse, nombre de requêtes, taux d'erreur, utilisation CPU/mémoire).&lt;br&gt;
Utilisez des outils comme &lt;strong&gt;Prometheus&lt;/strong&gt;, &lt;strong&gt;Grafana&lt;/strong&gt;, ou les outils natifs de votre plateforme de déploiement pour collecter et visualiser ces métriques.&lt;br&gt;
Configurez des &lt;strong&gt;alertes&lt;/strong&gt; basées sur ces métriques pour être notifié des problèmes.&lt;/p&gt;

&lt;h4&gt;
  
  
  Tracing distribué
&lt;/h4&gt;

&lt;p&gt;Implémentez le tracing distribué avec des outils comme &lt;strong&gt;Jaeger&lt;/strong&gt;, &lt;strong&gt;Zipkin&lt;/strong&gt; ou AWS X-Ray pour suivre le parcours d'une requête à travers vos différents services.&lt;br&gt;
Utilisez &lt;strong&gt;OpenTelemetry&lt;/strong&gt; comme standard pour instrumenter votre application.&lt;/p&gt;

&lt;h3&gt;
  
  
  Health checks et readiness probes
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;Les probes, c'est le test du micro avant le concert : on vérifie qu'on est prêt avant de monter le son.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Les orchestrateurs comme Kubernetes et les load balancers ont besoin de savoir si une instance de votre application est en bonne santé et prête à recevoir du trafic.&lt;/p&gt;

&lt;p&gt;Il existe généralement trois types de probes. &lt;br&gt;
Le &lt;strong&gt;Liveness probe&lt;/strong&gt; indique si l'application est vivante et fonctionne. Si elle échoue, l'orchestrateur redémarre l'instance.&lt;br&gt;
Le &lt;strong&gt;Readiness probe&lt;/strong&gt; indique si l'application est prête à recevoir du trafic. Par exemple, si les connexions à la base de données ne sont pas encore établies, l'instance n'est pas prête.&lt;br&gt;
Le &lt;strong&gt;Startup probe&lt;/strong&gt;, pour les applications qui prennent du temps à démarrer, évite que la liveness probe ne tue l'application prématurément.&lt;/p&gt;

&lt;p&gt;Implémentez des endpoints HTTP dédiés (par exemple &lt;code&gt;/health&lt;/code&gt; et &lt;code&gt;/ready&lt;/code&gt;) qui retournent le statut approprié.&lt;/p&gt;

&lt;h3&gt;
  
  
  Graceful shutdown
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;Fermer en douceur, c'est dire au revoir avant de raccrocher : on termine la phrase, puis on coupe.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Lorsqu'une instance de votre application est arrêtée (mise à jour, scaling down, etc.), elle doit se terminer proprement :&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Arrêter d'accepter de nouvelles requêtes&lt;/li&gt;
&lt;li&gt;Terminer le traitement des requêtes en cours&lt;/li&gt;
&lt;li&gt;Fermer proprement les connexions aux bases de données et aux services externes&lt;/li&gt;
&lt;li&gt;Libérer les ressources&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Implémentez un signal handler (SIGTERM) pour gérer l'arrêt gracieux de votre application. La plupart des orchestrateurs envoient un SIGTERM avant de forcer l'arrêt avec SIGKILL.&lt;/p&gt;

&lt;h3&gt;
  
  
  Gestion des dépendances et vulnérabilités
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;Faites votre inventaire comme chez Home Alone : vérifiez les pièges, ne laissez pas d'entrées faciles.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;La gestion proactive des dépendances est cruciale pour la sécurité et la stabilité :&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Scan régulier&lt;/strong&gt; : Utilisez des outils comme Dependabot, Snyk, ou OWASP Dependency-Check pour identifier les vulnérabilités dans vos dépendances&lt;br&gt;
  &lt;strong&gt;Mises à jour automatisées&lt;/strong&gt; : Configurez des pull requests automatiques pour les mises à jour de sécurité&lt;br&gt;
  &lt;strong&gt;Versioning sémantique&lt;/strong&gt; : Respectez le versioning sémantique pour vos propres bibliothèques&lt;br&gt;
  &lt;strong&gt;Lockfiles&lt;/strong&gt; : Utilisez des fichiers de verrouillage (package-lock.json, uv.lock, Pipfile.lock, go.sum, pom.xml) pour garantir la reproductibilité&lt;br&gt;
  &lt;strong&gt;Audit régulier&lt;/strong&gt; : Faites des audits de sécurité réguliers de vos dépendances&lt;/p&gt;

&lt;h3&gt;
  
  
  CI/CD et pipelines de déploiement
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;Le pipeline, c'est la chaîne de montage : on sort des versions fiables, pas des prototypes du lundi matin.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;L'automatisation du déploiement est essentielle pour le cloud, elle est aussi très utile quand on déploie sur des serveurs traditionnels. Elle permet de réduire les oublis, les erreurs humaines et d'accélérer les mises à jour.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Intégration continue&lt;/strong&gt; : Exécutez les tests automatiquement à chaque commit (GitHub Actions, GitLab CI, Jenkins, CircleCI).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Tests&lt;/strong&gt; : Incluez des tests unitaires, d'intégration, et end-to-end dans votre pipeline.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Build d'images&lt;/strong&gt; : Automatisez la création des images de conteneur.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Scan de sécurité&lt;/strong&gt; : Intégrez le scan de sécurité des images et des dépendances dans le pipeline.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Déploiement progressif&lt;/strong&gt; : Utilisez des stratégies comme blue/green deployment, canary deployment, ou rolling updates pour minimiser les risques.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Rollback automatique&lt;/strong&gt; : Configurez un rollback automatique si les health checks échouent après un déploiement.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Infrastructure as Code&lt;/strong&gt; : Gérez votre infrastructure avec Terraform, CloudFormation, Pulumi, ou ARM templates.&lt;/p&gt;

&lt;p&gt;Faites en sorte que votre pipeline injecte la version de l'image dans les variables d'environnement de l'application.&lt;/p&gt;

&lt;h3&gt;
  
  
  Conteneurisation et images
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;Un bon conteneur, c'est une valise bien rangée : légère, sécurisée, et sans le tag 'latest' perdu à l'aéroport.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;La conteneurisation est quasi-universelle dans le déploiement distribué :&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Images légères&lt;/strong&gt; : Utilisez des images de base minimales (Alpine, distroless) pour réduire la taille et la surface d'attaque.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Multi-stage builds&lt;/strong&gt; : Utilisez des builds multi-étapes pour séparer la compilation de l'exécution et réduire la taille finale.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Scan de sécurité&lt;/strong&gt; : Scannez vos images pour détecter les vulnérabilités (Trivy, Snyk, Clair).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Versioning&lt;/strong&gt; : Versionnez vos images et évitez d'utiliser le tag &lt;code&gt;latest&lt;/code&gt; en pré-production ou en production.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Non-root user&lt;/strong&gt; : Exécutez vos conteneurs avec un utilisateur non-root pour la sécurité.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Pipelines&lt;/strong&gt; : Automatisez la construction, le test et le déploiement de vos images via des pipelines CI/CD.&lt;/p&gt;

&lt;p&gt;Assurez-vous d'exposer la version de l'image dans les variables d'environnement de l'application.&lt;/p&gt;

&lt;h3&gt;
  
  
  Optimisation des coûts (cloud)
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;Le cloud facture comme un taxi : laissez le compteur tourner, et la note grimpe. Mettez des limites.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Le cloud peut devenir coûteux si on ne fait pas attention :&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Auto-scaling intelligent&lt;/strong&gt; : Configurez l'auto-scaling basé sur des métriques réelles (CPU, mémoire, nombre de requêtes).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Right-sizing&lt;/strong&gt; : Choisissez la taille d'instance appropriée pour votre charge de travail. Ne sur-provisionnez pas.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Utilisation de spot instances&lt;/strong&gt; : Pour les charges de travail non-critiques ou les environnements de test, utilisez des instances spot/préemptibles.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Shutdown automatique&lt;/strong&gt; : Arrêtez les environnements de développement et de test en dehors des heures de travail.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Monitoring des coûts&lt;/strong&gt; : Utilisez les outils de monitoring des coûts fournis par votre cloud provider.&lt;/p&gt;

&lt;h3&gt;
  
  
  Gestion des ressources et limites
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;Les ressources, c'est le budget calorique : trop peu, on cale; trop, on somnole. Trouvons le bon dosage.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Définir correctement les ressources allouées à votre application est essentiel :&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Requests et Limits&lt;/strong&gt; : Dans Kubernetes, définissez des requests (ressources garanties) et des limits (ressources maximales) pour CPU et mémoire&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Memory leaks&lt;/strong&gt; : Surveillez activement les fuites mémoire qui peuvent causer des redémarrages fréquents&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;JVM tuning&lt;/strong&gt; : Pour les applications Java, configurez correctement le heap size et le garbage collector en fonction des ressources allouées&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Connection pools&lt;/strong&gt; : Dimensionnez correctement vos pools de connexions (DB, HTTP clients) en fonction du nombre d'instances et de la charge&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Thread pools&lt;/strong&gt; : Configurez les thread pools pour éviter l'épuisement des threads et les blocages&lt;/p&gt;

&lt;h2&gt;
  
  
  Développement local et environnement de dev
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;Développer localement, c'est répéter en studio : on règle les fausses notes avant le concert en prod.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Développer pour un environnement distribué ne signifie pas que tout doit se faire dans cet environnement.&lt;/p&gt;

&lt;h3&gt;
  
  
  Émulation locale des services distribués
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;LocalStack&lt;/strong&gt; : Émule les services AWS localement (S3, DynamoDB, SQS, etc.)&lt;br&gt;
&lt;strong&gt;Azurite&lt;/strong&gt; : Émulateur pour Azure Storage&lt;br&gt;
&lt;strong&gt;Docker Compose&lt;/strong&gt; : Orchestrez localement vos services (base de données, cache, message queues)&lt;br&gt;
&lt;strong&gt;Testcontainers&lt;/strong&gt; : Lancez des conteneurs pour vos tests d'intégration&lt;br&gt;
&lt;strong&gt;Minikube/Kind&lt;/strong&gt; : Exécutez Kubernetes localement pour tester vos déploiements&lt;/p&gt;

&lt;h3&gt;
  
  
  Configuration locale vs déploiement distribué
&lt;/h3&gt;

&lt;p&gt;Utilisez des profils de configuration différents pour le développement local vs déploiement distribué. Évitez de dépendre de services cloud spécifiques pendant le développement local quand possible. Documentez clairement les étapes pour configurer l'environnement de développement local, idéalement avec des scripts d'automatisation. Utilisez des variables d'environnement avec des valeurs par défaut pour simplifier la configuration locale. Si vous devez utiliser des secrets, utilisez des fichiers &lt;code&gt;.env&lt;/code&gt; locaux ou des services de gestion des secrets adaptés au développement comme SOPS. Voir l'article que j'ai rédigé à ce sujet: &lt;a href="https://dev.to/onepoint/sops-secrets-encryptes-dans-un-depot-git-1c04"&gt;SOPS - Secrets encryptés dans un dépôt GIT&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Hot reload et développement rapide
&lt;/h3&gt;

&lt;p&gt;Utilisez des outils de hot reload (Spring Boot DevTools, Nodemon, Air pour Go) pour accélérer le cycle de développement. &lt;br&gt;
Configurez des volumes montés dans Docker pour un rechargement rapide du code.&lt;br&gt;
Utilisez des outils comme Skaffold ou Tilt pour le développement continu sur Kubernetes.&lt;/p&gt;

&lt;h2&gt;
  
  
  Tests pour applications distribuées
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;Les tests, c'est comme les crashs tests de voitures : on fracasse des prototypes dans un labo pour éviter d'avoir de vrais accidents sur l'autoroute. Et quand quelqu'un modifie le volant ou les freins, on refracasse tout pour vérifier que ça tient toujours la route.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Tester des applications distribuées nécessite une approche différente.&lt;/p&gt;

&lt;h3&gt;
  
  
  Tests unitaires
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Tests isolés de la logique métier&lt;/li&gt;
&lt;li&gt;Mockez les dépendances externes (base de données, services tiers)&lt;/li&gt;
&lt;li&gt;Utilisez des frameworks de test adaptés à votre langage&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Tests d'intégration
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Testcontainers&lt;/strong&gt; : Lancez des conteneurs Docker pour tester avec de vraies dépendances&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Tests de base de données&lt;/strong&gt; : Testez les requêtes SQL et les migrations avec une vraie base de données&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Tests d'API&lt;/strong&gt; : Testez vos endpoints REST/gRPC avec des outils comme RestAssured, Supertest&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Tests end-to-end
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Testez le système complet dans un environnement similaire à la production&lt;/li&gt;
&lt;li&gt;Utilisez des outils comme Selenium, Cypress, Playwright pour les applications web&lt;/li&gt;
&lt;li&gt;Automatisez ces tests dans votre pipeline CI/CD&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Tests de charge et de performance
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Load testing&lt;/strong&gt; : Testez le comportement sous charge normale (Apache JMeter, Gatling, k6)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Stress testing&lt;/strong&gt; : Testez les limites du système&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Spike testing&lt;/strong&gt; : Testez la réponse à des pics soudains de trafic&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Soak testing&lt;/strong&gt; : Testez la stabilité sur une longue période pour détecter les fuites mémoire&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Tests de chaos engineering
&lt;/h3&gt;

&lt;p&gt;Si nécessaire, intégrez des tests de chaos engineering pour valider la résilience de votre application :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Testez la résilience en introduisant des défaillances volontaires&lt;/li&gt;
&lt;li&gt;Utilisez des outils comme Chaos Monkey, Gremlin, ou LitmusChaos&lt;/li&gt;
&lt;li&gt;Simulez des pannes de serveurs, des latences réseau, des bases de données indisponibles&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Tests de régression visuelle
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Pour les applications frontend, testez que l'interface n'a pas changé de façon non intentionnelle&lt;/li&gt;
&lt;li&gt;Utilisez des outils comme Percy, Chromatic, ou Applitools&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Communication entre services
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;La communication entre services, c'est comme un orchestre de jazz : chaque musicien doit savoir quand jouer, dans quelle tonalité, et à quel tempo. Sans protocole commun (REST, gRPC, ou messages asynchrones), c'est la cacophonie. Tout le monde improvise, mais pendant le même jam-session.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Si votre application est composée de plusieurs microservices ou composants qui doivent communiquer entre eux, il est crucial de choisir les bons protocoles et patterns de communication.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;API REST&lt;/strong&gt; : Standard et simple, utilisez HTTP/HTTPS avec des formats JSON.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;gRPC&lt;/strong&gt; : Plus performant que REST, utilise Protocol Buffers et HTTP/2.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Message queues&lt;/strong&gt; : Pour la communication asynchrone, utilisez RabbitMQ, Apache Kafka, AWS SQS, Azure Service Bus, Postgres Notify, ou GCP Pub/Sub.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Service mesh&lt;/strong&gt; : Pour gérer la communication entre services (Istio, Linkerd) avec features comme le load balancing, le circuit breaking, et le mTLS.&lt;/p&gt;

&lt;p&gt;Certaines considérations importantes sont à ne pas négliger. Utilisez des &lt;strong&gt;timeouts&lt;/strong&gt; pour toutes les communications inter-services. Implémentez des &lt;strong&gt;retry&lt;/strong&gt; avec &lt;strong&gt;backoff exponentiel&lt;/strong&gt;. Utilisez des &lt;strong&gt;circuit-breakers&lt;/strong&gt; pour éviter les cascades de défaillances.   Propagez les &lt;strong&gt;correlation ID&lt;/strong&gt;s pour le &lt;strong&gt;tracing distribué&lt;/strong&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Résilience et gestion des erreurs
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;La résilience, c'est l'amortisseur : la route est cahoteuse, mais on garde le cap sans casser le châssis.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Dans un environnement distribué, les erreurs sont inévitables. Votre application doit être conçue pour être résiliente.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Circuit breaker&lt;/strong&gt; : Évite de surcharger un service défaillant en "ouvrant le circuit" après un certain nombre d'échecs.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Retry avec backoff exponentiel&lt;/strong&gt; : Réessaie les opérations échouées avec un délai croissant entre chaque tentative.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Timeout&lt;/strong&gt; : Définissez des timeouts pour toutes les opérations réseau pour éviter d'attendre indéfiniment.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Bulkhead&lt;/strong&gt; : Isolez les ressources pour qu'une défaillance dans une partie du système n'affecte pas les autres.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Fallback&lt;/strong&gt; : Prévoyez un comportement de secours quand une opération échoue (cache, valeur par défaut, mode dégradé).&lt;/p&gt;

&lt;p&gt;Des bibliothèques comme Resilience4j (Java), Polly (.NET) ou Hystrix facilitent l'implémentation de ces patterns.&lt;/p&gt;

&lt;h3&gt;
  
  
  Patterns de conception à considérer
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;Les bons patterns, c'est une carte routière : on évite les chemins de terre et on arrive à l'heure.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Plusieurs patterns architecturaux sont particulièrement adaptés aux déploiements distribués.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Strangler Fig Pattern&lt;/strong&gt; : Migrez progressivement une application monolithique vers des microservices en "étranglant" l'ancien système&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Backend for Frontend (BFF)&lt;/strong&gt; : Créez des API spécifiques pour chaque type de client (web, mobile, etc.)&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;API Gateway&lt;/strong&gt; : Point d'entrée unique pour tous vos services, gérant l'authentification, le routage, le rate limiting&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Event Sourcing&lt;/strong&gt; : Stockez tous les changements d'état comme une séquence d'événements&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;CQRS (Command Query Responsibility Segregation)&lt;/strong&gt; : Séparez les opérations de lecture et d'écriture pour optimiser chacune indépendamment&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Sidecar Pattern&lt;/strong&gt; : Déployez des fonctionnalités auxiliaires (logging, monitoring) dans un conteneur séparé mais adjacent&lt;/p&gt;

&lt;p&gt;Il est important de bien comprendre ces patterns, dans quel contexte les utiliser et de les adapter à vos besoins spécifiques.&lt;/p&gt;

&lt;h3&gt;
  
  
  Anti-patterns à éviter
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;Les anti-patterns, ce sont les panneaux 'route barrée' : si on insiste, on finit dans le fossé.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;Distributed Monolith&lt;/strong&gt; : Microservices trop couplés qui doivent être déployés ensemble. L'indépendance relative entre les services est cruciale.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Chatty Services&lt;/strong&gt; : Trop de communication entre services, créant de la latence, pensez à regrouper les appels, à la caching, ou à utiliser des messages asynchrones.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Tight Coupling&lt;/strong&gt; : Services dépendant fortement les uns des autres, rendant les changements et le déploiement difficiles. Pensez à utiliser des interfaces claires et des contrats stables.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Data Ownership Violations&lt;/strong&gt; : Services accédant directement à la base de données d'autres services. Si vous choisissez de considérer la base de données comme un service, chaque service doit gérer son propre schéma de données. De plus, s'il est plus efficace pour un service d'accéder directement à la base de données d'un autre service, pensez à exposer l'information sous la forme d'une vue qui devient le contrat entre les deux services.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Ignorer la loi de fallacies of distributed computing&lt;/strong&gt; : Supposer que le réseau est fiable, la latence nulle, la bande passante infinie, etc.&lt;/p&gt;

&lt;h2&gt;
  
  
  Sécurité
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;La sécurité, c'est la serrure ET l'alarme : le cloud a des voisins curieux, mieux vaut être prudent.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Tant dans un déploiement distribué traditionnel que dans le cloud, la sécurité est une responsabilité partagée par les développeurs et l'équipe devops doit être intégrée dès le début.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Principe du moindre privilège&lt;/strong&gt; : Donnez uniquement les permissions nécessaires aux applications et aux utilisateurs.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Encryption&lt;/strong&gt; : Chiffrez les données au repos et en transit (TLS/HTTPS).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Authentification et autorisation&lt;/strong&gt; : Utilisez des standards comme OAuth2/OIDC pour l'authentification, JWT pour les tokens.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Scan de vulnérabilités&lt;/strong&gt; : Scannez régulièrement vos dépendances et vos images.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;WAF&lt;/strong&gt; : Utilisez un Web Application Firewall pour protéger contre les attaques courantes.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;DDoS protection&lt;/strong&gt; : Activez la protection DDoS offerte par votre cloud provider. Sinon, regardez ce que vous pouvez mettre en place vous-même.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Audit logs&lt;/strong&gt; : Conservez des logs d'audit pour toutes les opérations sensibles.&lt;/p&gt;

&lt;h2&gt;
  
  
  Environnements multiples
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;Multi-environnements, ce sont des costumes adaptés : même comédien, répétitions en studio, première en gala.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Maintenez plusieurs environnements pour différents stades du cycle de vie. Ils permettent une liberté pour tester et valider les changements avant de les déployer aux testeurs, puis en production.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Local&lt;/strong&gt; : Pour le développement individuel&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Développement&lt;/strong&gt; : Pour s'assurer que les nouvelles fonctionnalités fonctionnent ensemble, que ça déploie correctement, pour permettre aux développeurs de tester des intégrations.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Test/QA&lt;/strong&gt; : Pour les tests d'intégration et d'acceptation&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Staging/Pre-prod&lt;/strong&gt; : Une copie de la production pour les tests finaux par un groupe restreint d'utilisateurs, souvent du côté du client, avant le déploiement en production&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Production&lt;/strong&gt; : L'environnement de production&lt;/p&gt;

&lt;p&gt;Utilisez l'Infrastructure as Code est une excellente pratique pour garantir que tous les environnements sont configurés de manière cohérente. Ça évite aussi qu'une configuration manuelle soit oubliée dans un environnement ou qu'une configuration essentielle soit omise ou différente entre les environnements.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;Adopter ces pratiques, c'est comme apprendre le piano : on ne joue pas du Beethoven dès le premier jour. Commencez par les bases, adaptez à votre rythme, et avant longtemps vous ferez de la musique — sans péter les plombs ni le budget.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Développer pour des environnements distribués n'est pas simplement une question de déploiement dans un fournisseur cloud ou dans des serveurs de l'organisation.&lt;br&gt;
Il faut penser à certains aspects spécifiques du développement pour s'assurer que l'application fonctionne correctement dans une architecture distribuée.&lt;/p&gt;

&lt;p&gt;Ce petit guide couvre plusieurs des considérations les plus importantes, mais il en existe d'autres en fonction des besoins spécifiques de chaque application.&lt;br&gt;
Il n'est certes pas exhaustif, mais j'espère qu'il servira de point de départ pour ceux qui débutent dans le développement pour le déploiement distribué.&lt;/p&gt;

&lt;p&gt;L'adoption de ces pratiques peut sembler lourde au début, mais elle apporte de nombreux avantages : meilleure scalabilité, résilience accrue, facilité de maintenance, et réduction des coûts à long terme. L'important est de commencer progressivement et d'adapter ces principes aux besoins réels de votre application.&lt;/p&gt;

&lt;p&gt;Si vous voulez aller plus loin, les principes des &lt;a href="https://12factor.net/" rel="noopener noreferrer"&gt;12-Factor App&lt;/a&gt;, une méthodologie bien établie pour construire des applications SaaS (Software as a Service) modernes est un bon point de départ.&lt;/p&gt;




&lt;p&gt;Cet article fait partie du &lt;em&gt;Advent of Tech 2025 @ Onepoint&lt;/em&gt;, une série d'articles tech publiés par &lt;a href="https://www.groupeonepoint.com/fr/" rel="noopener noreferrer"&gt;Onepoint&lt;/a&gt; pour patienter jusqu'à Noël.&lt;/p&gt;

&lt;p&gt;Voir tous les articles du &lt;a href="https://dev.to/onepoint/advent-of-tech-onepoint-x-wepoint-2025-2o3k"&gt;Advent of Tech 2025&lt;/a&gt;&lt;/p&gt;

</description>
      <category>cloud</category>
      <category>adventoftech2025</category>
      <category>development</category>
    </item>
    <item>
      <title>Démarrer un projet à partir de zéro</title>
      <dc:creator>Patrick Turcotte</dc:creator>
      <pubDate>Tue, 25 Feb 2025 05:00:00 +0000</pubDate>
      <link>https://dev.to/onepoint/demarrer-un-projet-a-partir-de-zero-12b3</link>
      <guid>https://dev.to/onepoint/demarrer-un-projet-a-partir-de-zero-12b3</guid>
      <description>&lt;h2&gt;
  
  
  Je rêve
&lt;/h2&gt;

&lt;p&gt;Je rêve de participer à un projet dès son inception, pour pouvoir décider de chaque aspect à inclure.&lt;br&gt;
Être capable de choisir les technologies, l'architecture, les pratiques, les outils, les processus, les méthodologies, l'équipe même.&lt;/p&gt;

&lt;p&gt;À l'époque où j'ai commencé à programmer pour gagner ma vie, beaucoup des technologies que nous considérons comme acquises aujourd'hui n'existaient même pas.&lt;br&gt;
C'est comme si j'avais grandi avec l'évolution de certaines technologies, appris de mes erreurs.&lt;br&gt;
J'ai essayé différentes alternatives pour le même besoin et j'ai expérimenté où certaines sont meilleures que d'autres.&lt;/p&gt;

&lt;p&gt;Depuis longtemps, je suis principalement un développeur Java.&lt;br&gt;
Quand j'ai commencé, je savais programmer, mais pas selon la &lt;strong&gt;Programmation Orientée Objet&lt;/strong&gt;.&lt;br&gt;
Ma première expérience en Java était d'aider un projet dans l'université ou j'avais fait mes études en chimie.&lt;br&gt;
Je ne savais pas vraiment ce qu'était une classe, ni comment la compiler, mais je comprenais comment afin d'encoder les caractères spéciaux afin qu'un servlet puisse créer du JavaScript qui créerait lui-même du HTML qui se compilerait et fonctionnerait.&lt;br&gt;
J'ai beaucoup appris depuis.&lt;br&gt;
Je dois reconnaître que ce bouquin, &lt;a href="https://horstmann.com/bigjava/" rel="noopener noreferrer"&gt;&lt;strong&gt;Big Java&lt;/strong&gt;&lt;/a&gt;, ma permis de bien entreprendre ce voyage.&lt;/p&gt;

&lt;p&gt;Alors plongeons directement dans le vif du sujet de cet article.&lt;br&gt;
Je vais faire un inventaire non exhaustif des technologies, pratiques, outils, processus, méthodologies, membres de l'équipe, etc. que j'aimerais avoir dans mon projet de terrain vierge.&lt;/p&gt;
&lt;h2&gt;
  
  
  Ne pas réinventer la roue
&lt;/h2&gt;

&lt;p&gt;En tant que principe directeur, je m'appuierais sur des technologies, pratiques, processus, méthodologies et outils existants plutôt que de réinventer la roue..&lt;/p&gt;

&lt;p&gt;Rares sont les cas où nous devons inventer quelque chose de nouveau.&lt;br&gt;
La plupart du temps, nous pouvons utiliser quelque chose qui existe déjà.&lt;br&gt;
C'est plus rapide, moins cher et plus fiable.&lt;/p&gt;

&lt;p&gt;J'appelle cela: &lt;strong&gt;Se tenir sur les épaules de géants&lt;/strong&gt;.&lt;/p&gt;
&lt;h2&gt;
  
  
  Du code, des bugs
&lt;/h2&gt;

&lt;p&gt;Souvent, j'aime provoquer un peu les gestionnaires en leur disant que "&lt;em&gt;des développeurs, ce sont des générateurs de bugs&lt;/em&gt;".&lt;br&gt;
Ça part du principe que chaque ligne de code que nous écrivons peut avoir un bug.&lt;br&gt;
Mais, si nous n'écrivons pas de code, nous n'avons pas de fonctionnalités.&lt;/p&gt;

&lt;p&gt;L'autre principe, c'est que le plus tard nous trouvons un bug, le plus cher ce sera de le corriger.&lt;br&gt;
Imaginez trouver un bug dans le code du véhicule Mars Rover après qu'il ait été lancé.&lt;br&gt;
Comme corollaire, le plus près de sa création nous trouvons un bug, le moins cher ce sera de le corriger.&lt;/p&gt;

&lt;p&gt;Donc, nous devrions viser à trouver les bugs le plus rapidement possible. Voici quelques pratiques qui permettent d'aider à produire du code de qualité :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  Utiliser un &lt;strong&gt;IDE&lt;/strong&gt;. Ce sont plus que de simples éditeurs de textes.
Ils peuvent nous aider à trouver des bugs, des erreurs de syntaxe, de logique, etc. avant même que nous compilions le code. Portons attention aux avertissements qu'ils nous donnent.&lt;/li&gt;
&lt;li&gt;  Écrivons des tests. Même si nous n'appliquons pas la méthode TDD, nous devrions écrire des tests.
Ils nous aident à trouver des bugs.
Et, quand un bug est rapporté, nous devrions écrire un test pour le reproduire, réparer le bug, et rouler le test pour nous assurer que le bug est corrigé.&lt;/li&gt;
&lt;li&gt;  Faire rouler les tests, tant localement que dans notre pipeline.
Nous devrions avoir un pipeline qui roule les tests et bloque le merge si les tests ne passent pas.&lt;/li&gt;
&lt;li&gt;  Faire de la revue de code (voir plus bas)&lt;/li&gt;
&lt;li&gt;  Utiliser l'analyse statique de code.
Elle permet de trouver des bugs qui ne sont pas évidents, comme des variables non utilisées, des imports inutiles, des erreurs de syntaxe, etc.&lt;/li&gt;
&lt;li&gt;  Planifier du temps pour appliquer ce que nous avons découvert dans la revue de code et l'analyse statique.&lt;/li&gt;
&lt;li&gt;  Déployer en environnement QA le plus tôt possible. Le plus tôt nous testons le code en environnement réel, le plus tôt nous trouvons les bugs.&lt;/li&gt;
&lt;li&gt;  Avoir des QA qui testent le code. Ils peuvent trouver des bugs ou situations auxquels nous n'avons pas pensé.&lt;/li&gt;
&lt;li&gt;  Faire du monitoring de l'application. Ça permet de déceler des bugs qui ne nous ont pas été rapportés par les utilisateurs.&lt;/li&gt;
&lt;li&gt;  Déployer à un sous-ensemble d'utilisateur en premier. Ça permet de trouver des bugs que nous n'avons pas vu en QA.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  Conventions et pratiques
&lt;/h2&gt;
&lt;h3&gt;
  
  
  &lt;a href="https://www.conventionalcommits.org/en/v1.0.0/" rel="noopener noreferrer"&gt;Conventional Commits&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;J'ai découvert il y a un certain temps déjà la spécification des &lt;strong&gt;Conventional Commits&lt;/strong&gt;.&lt;br&gt;
C'est une convention simple sur la façon d'écrire des messages de commit.&lt;br&gt;
C'est simple, mais c'est puissant.&lt;br&gt;
Cela nous permet de générer des journaux de modifications, des versions des numéros, etc. automatiquement.&lt;/p&gt;

&lt;p&gt;Avec une convention définie, il est plus facile pour chacun dans l'équipe de comprendre ce qu'est un commit à propos.&lt;br&gt;
Cela facilite également la génération de notes de version.&lt;/p&gt;

&lt;p&gt;Un message de commit typique ressemblerait à ceci :&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;feat: permettre à l'objet de configuration fourni d'étendre d'autres configurations

Ferme: JIRA-1234
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;forme des commits&lt;/strong&gt;&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;type&amp;gt;[portée optionnelle]: &amp;lt;description&amp;gt;

[corps optionnel]

[pied(s) de page optionnel(s)]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;Le type peut être l'un des suivants :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  feat : Une nouvelle fonctionnalité&lt;/li&gt;
&lt;li&gt;  fix : Un correctif&lt;/li&gt;
&lt;li&gt;  build : Changements qui affectent le système de construction ou les dépendances externes&lt;/li&gt;
&lt;li&gt;  chore : Changements qui ne modifient pas les fichiers src ou test&lt;/li&gt;
&lt;li&gt;  ci : Changements apportés à nos fichiers de configuration CI et scripts&lt;/li&gt;
&lt;li&gt;  docs: Changements uniquement dans la documentation&lt;/li&gt;
&lt;li&gt;  style: Changements qui n'affectent pas le sens du code (espaces, formatage, point-virgule manquant deux-points, etc)&lt;/li&gt;
&lt;li&gt;  refactor: Un changement de code qui ne corrige ni un bug ni n'ajoute une fonctionnalité&lt;/li&gt;
&lt;li&gt;  perf: Amélioration des performances&lt;/li&gt;
&lt;li&gt;  test: Ajout de tests manquants ou correction de tests existants&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Dans le pied de page, j'ajouterais une référence au ticket JIRA (ou tout autre système de tickets) auquel le commit est lié.&lt;/p&gt;

&lt;p&gt;En allant un peu plus loin, je pense que le type devrait également être le préfixe pour le nom de la branche.&lt;br&gt;
Suivi du numéro de ticket, et enfin quelques mots sur la fonctionnalité ou le problème.&lt;br&gt;
De cette façon, nous pouvons facilement voir de quoi il s'agit dans la branche.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;exemple&lt;/strong&gt;&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;feat/JIRA-1234_permettre-objet-config-fourni-d'étendre-autres-configs
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h3&gt;
  
  
  &lt;a href="https://semver.org/" rel="noopener noreferrer"&gt;Semantic versioning&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;J'adopterais le versionnement sémantique pour gérer les versions projet.&lt;br&gt;
C'est une convention simple qui nous permet de savoir quel type de changements se trouvent dans une version rien qu'en regardant le numéro de version.&lt;/p&gt;

&lt;p&gt;Traduction de la définition depuis celle du site web semver :&lt;/p&gt;

&lt;p&gt;Étant donné un numéro de version MAJOR.MINOR.PATCH, incrémentez :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;la version MAJOR lorsque vous apportez des modifications API incompatibles&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;la version MINOR lorsque vous ajoutez des fonctionnalités de manière rétrocompatible&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;la version PATCH lorsque vous effectuez des corrections de bogues rétrocompatibles&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Des étiquettes supplémentaires pour les métadonnées de pré-version et de construction sont disponibles en tant qu'extensions au format MAJOR.MINOR.PATCH.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;exemples&lt;/strong&gt;&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;1.0.0
2.1.3
4.1.3ALPHA
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;En ce qui concerne la version, ce ne sont que des chiffres, nous ne devrions pas hésiter à les incrémenter, ils ne coûtent rien.&lt;br&gt;
Et nous ne devrions pas essayer de garder toutes les parties d'un projet synchronisées avec le numéro de version.&lt;br&gt;
Il est acceptable d'avoir une version 1.0.0 d'une bibliothèque et une version 2.0.0 de l'application qui l'utilise.&lt;/p&gt;

&lt;p&gt;Mais, lorsque nous déployons, nous devons garder une trace des versions des différentes parties du projet.&lt;br&gt;
Cela nous permet de voir facilement ce qui est déployé où.&lt;/p&gt;
&lt;h3&gt;
  
  
  Conquérir le monde (&lt;em&gt;i18n&lt;/em&gt;) dès le départ
&lt;/h3&gt;

&lt;p&gt;Nous devons intégrer l'internationalisation (i18n) dès le début du projet.&lt;br&gt;
Nous ne pouvons pas simplement écrire les chaines de caractères pour les boutons, menus, descriptions, etc.&lt;br&gt;
Nous utiliserons une bibliothèque appropriée pour les frameworks retenus (frontend et backend).&lt;/p&gt;

&lt;p&gt;C'est beaucoup plus facile à mettre en place dès le départ que de tenter de réintégrer le tout une fois le projet démarré.&lt;/p&gt;

&lt;p&gt;Aussi, si nous enregistrons de l'information dans le backend, comme des configurations, nous devrions retourner toutes les langues comme réponses aux interrogations, et laisser le frontend décider de ce qu'il affiche.&lt;br&gt;
C'est particulièrement vrai quand on crée des apis.&lt;/p&gt;
&lt;h3&gt;
  
  
  Dates standard (&lt;em&gt;ISO8601&lt;/em&gt;) dès le départ
&lt;/h3&gt;

&lt;p&gt;La plupart des projets vont devoir gérer des dates à un moment ou un autre.&lt;br&gt;
Nous adopterons le format de date ISO8601 pour toutes les communications dès le début.&lt;/p&gt;

&lt;p&gt;De plus, les dates, c'est difficile.&lt;br&gt;
Il suffit de demander à Google ou de jeter un oeil à &lt;a href="https://gist.github.com/timvisee/fcda9bbdff88d45cc9061606b4b923ca" rel="noopener noreferrer"&gt;Falsehoods programmers believe about time&lt;/a&gt;.&lt;br&gt;
Nous utiliserons donc des bibliothèques reconnues pour manipuler les données temporelles.&lt;/p&gt;

&lt;p&gt;Ça va nous sauver du temps à long terme.&lt;/p&gt;
&lt;h3&gt;
  
  
  Securité dès le début
&lt;/h3&gt;

&lt;p&gt;La sécurité doit être une priorité dès le début.&lt;br&gt;
Nous devons l'avoir à l'esprit dès le début du projet.&lt;br&gt;
Nous devrions prendre le temps de réfléchir aux permissions et aux groupes, de déterminer quels points d'accès doivent être sécurisés, quels demandent des authorisations particulières et quels doivent être public.&lt;/p&gt;

&lt;p&gt;Nous devrions aussi utiliser les fonctionnalités de sécurité des &lt;em&gt;frameworks&lt;/em&gt; retenus, pas seulement pour l'accès, mais aussi pour éviter l'injection SQL, la reprise de session, etc.&lt;br&gt;
&lt;a href="https://owasp.org/www-project-top-ten/" rel="noopener noreferrer"&gt;OWASP Top Ten&lt;/a&gt; est un bon point de départ.&lt;/p&gt;
&lt;h2&gt;
  
  
  L'équipe, ou les rôles
&lt;/h2&gt;

&lt;p&gt;Certains rôles et responsabilités sont essentiels et doivent être attribués à des membres de l'équipe, même s'ils peuvent être combinés.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;Développeur&lt;/strong&gt; : C'est la personne qui écrit le code.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;QA&lt;/strong&gt; : C'est la personne qui teste le code.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Architecte&lt;/strong&gt; : C'est la personne qui conçoit l'architecture du projet.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Product Owner&lt;/strong&gt; : C'est la personne qui définit les fonctionnalités du projet.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Gestionnaire de projet&lt;/strong&gt; : C'est la personne qui s'assure que le projet est livré à temps et dans le budget.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Agile Methodology Master&lt;/strong&gt; : C'est la personne qui s'assure que l'équipe respecte les principes de la méthodologie retenue.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;DevOps&lt;/strong&gt; : C'est la personne qui s'assure que le code est déployé correctement.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  Documentation
&lt;/h2&gt;

&lt;p&gt;Nous devons documenter divers aspects de notre projet de manière organisée.&lt;/p&gt;

&lt;p&gt;Toute la documentation n'a pas besoin d'être entreposée au même endroit.&lt;br&gt;
Il est souvent préférable de garder la documentation près du code pour s'assurer qu'elle reste à jour.&lt;/p&gt;

&lt;p&gt;Cependant, nous avons également besoin d'un endroit central pour indexer toute la documentation.&lt;/p&gt;

&lt;p&gt;Un wiki est une bonne solution pour cet aspect. [antora] est une autre solution possible.&lt;/p&gt;
&lt;h3&gt;
  
  
  Diataxis
&lt;/h3&gt;

&lt;p&gt;J'ai récemment été introduit au concept de Diataxis (&lt;a href="https://dev.to/onepoint/documentation-chaotique-diataxis-a-la-rescousse%E2%80%94%E2%80%8B3e9o"&gt;https://dev.to/onepoint/documentation-chaotique-diataxis-a-la-rescousse—​3e9o&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;C'est une façon de catégoriser et d'organiser la documentation d'un projet.&lt;/p&gt;

&lt;p&gt;On peut le voir comme une matrice avec deux axes : le contenu et la forme.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;colgroup&gt;
&lt;col&gt;
&lt;col&gt;
&lt;col&gt;
&lt;/colgroup&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;si le contenu décrit&lt;/th&gt;
&lt;th&gt;et permet au lecteur de&lt;/th&gt;
&lt;th&gt;alors cela devrait être une forme de&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;p&gt;actions&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;acquérir des compétences&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;tutoriel&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;p&gt;actions&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;appliquer des compétences&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;guide pratique&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;p&gt;connaissances&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;acquérir des connaissances&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;explication de concepts&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;p&gt;connaissances&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;appliquer les connaissances&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;références&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Je n'ai pas encore utilisé cette méthode, mais je pense que c'est une bonne idée pour organiser et de réfléchir la documentation.&lt;/p&gt;
&lt;h3&gt;
  
  
  Format &lt;a href="https://asciidoctor.org/" rel="noopener noreferrer"&gt;asciidoctor&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;Il existe de nombreuses façons et formats pour documenter notre futur projet.&lt;br&gt;
Très souvent, nous verrons markdown comme format.&lt;br&gt;
Malheureusement, markdown est plus limité, et il existe une variété de saveurs en compétition pour markdown.&lt;br&gt;
Par exemple, il est difficile de numéroter les titres dans markdown, il faut le faire à la main, et s'assurer de faire suivre la numérotation quand on déplace des sections.&lt;/p&gt;

&lt;p&gt;AsciiDoc est un format plus puissant qui peut être utilisé pour rédiger de la documentation.&lt;br&gt;
Il permet de faire plus de choses que markdown.&lt;br&gt;
Il est relativement facile à lire dans sa forme brute.&lt;/p&gt;

&lt;p&gt;Donc, nous devrions utiliser &lt;em&gt;Asciidoc&lt;/em&gt; comme format.&lt;br&gt;
Il peut être utilisé pour générer de la documentation dans de nombreux formats, comme html, pdf, etc.&lt;br&gt;
La documentation peut être pour différentes sorties, comme un livre, un article, etc.&lt;/p&gt;

&lt;p&gt;Si nous devons un jour le convertir à nouveau en markdown, nous pouvons utiliser la commande suivante :&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Conversion d'asciidoctor à markdown&lt;/strong&gt;&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;asciidoctor -b docbook -a leveloffset=+1 -o - green-field.adoc| pandoc --wrap=preserve-t markdown_strict -f docbook - &amp;gt; green-field2.md
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h3&gt;
  
  
  Documentation de projet &lt;a href="https://antora.org/" rel="noopener noreferrer"&gt;antora&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;Antora &lt;span id="antora"&gt;&lt;/span&gt; est défini comme le &lt;em&gt;générateur de site de documentation mono ou multi dépôt pour les rédacteurs techniques qui aiment rédiger en Asciidoc&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Antora permet de rédiger de la documentation en asciidoc dans plusieurs dépôts de codes (penser frontend, multiples modules backend) et de créer un dépôt pour centraliser toute la documentation de vos dépôts et de publier un site statique pour votre organisation.&lt;/p&gt;

&lt;p&gt;C'est une façon très intéressante de faire en sorte d'avoir un point de départ pour toute la documentation du projet tout en la maintenant à jour.&lt;/p&gt;
&lt;h3&gt;
  
  
  Enregistrement de décisions architecturales (Architectural Decision Records &lt;a href="https://adr.github.io/" rel="noopener noreferrer"&gt;ADR&lt;/a&gt;)
&lt;/h3&gt;

&lt;p&gt;Dès le début d'un projet, nous prenons des décisions d'architectures.&lt;br&gt;
Cet article en suggère plusieurs.&lt;br&gt;
Avec le temps qui passe, les personnes peuvent changer de projet et la mémoire de ces décisions et des raisons qui les ont appuyées peuvent se perdre.&lt;/p&gt;

&lt;p&gt;Les ADR sont une façon d'enregistrer ces décisions et de les garder au même endroit.&lt;/p&gt;

&lt;p&gt;Quelques projets existent pour faciliter la création d'ADR, mais la plupart utilisent du markdown comme format.&lt;br&gt;
Je suis encore à la recherche d'un bon projet qui supporte le asciidoc.&lt;br&gt;
Pour l'instant, &lt;a href="https://github.com/adoble/adr-j" rel="noopener noreferrer"&gt;adr-j&lt;/a&gt; semble un bon candidat qui supporte à la fois le markdown et le asciidoc.&lt;/p&gt;
&lt;h3&gt;
  
  
  Pour des articles ou de la documentation, voir aussi &lt;a href="https://gohugo.io/" rel="noopener noreferrer"&gt;Hugo&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;Se prétendant être le framework le plus rapide pour construire un site statique, Hugo est un framework qui prend un ensemble de documents rédigés en markdown ou asciidoc et les convertis en site statique avec la possibilité d'appliquer des thèmes et d'autres fonctionnalités intéressantes comme les mots clés.&lt;/p&gt;

&lt;p&gt;J'ai commencé à l'utiliser pour générer mon blog personnel. Pour l'instant, je suis satisfait.&lt;/p&gt;
&lt;h2&gt;
  
  
  Développement
&lt;/h2&gt;
&lt;h3&gt;
  
  
  IDE (Environnement de Développement Intégré)
&lt;/h3&gt;

&lt;p&gt;J'utilise IntelliJ IDEA de JetBrains depuis décembre 2012 et je l'apprécie beaucoup.&lt;/p&gt;

&lt;p&gt;Mais en fait, chaque personne devrait utiliser n'importe quel IDE qu'elle aime, à une condition : &lt;strong&gt;Ils devraient le maîtriser&lt;/strong&gt;.&lt;br&gt;
Ils devraient savoir comment l'utiliser à son plein potentiel.&lt;/p&gt;

&lt;p&gt;Si nous avons une personne junior dans notre équipe, assurons-nous qu'elle prenne le temps d'apprendre son IDE.&lt;/p&gt;
&lt;h3&gt;
  
  
  Projet de services auxiliaires (docker-compose)
&lt;/h3&gt;

&lt;p&gt;Dans de nombreux projets, nous aurons besoin de certains services auxiliaires.&lt;br&gt;
J'utiliserais docker-compose pour définir ces services auxiliaires et les rassembler.&lt;br&gt;
Et envelopper les actions (démarrage, arrêt, réinitalisation de la base de données, etc.) dans un script shell qui offre une aide et des valeurs par défaut raisonnables.&lt;/p&gt;

&lt;p&gt;De cette façon, nous pouvons démarrer les services auxiliaires avec une seule commande.&lt;br&gt;
Nous pouvons également arrêter les services avec une seule commande.&lt;br&gt;
Nous pouvons aussi redémarrer les services auxiliaires avec une seule commande.&lt;/p&gt;

&lt;p&gt;Dans nos projets, le script d'aide comprend des profils.&lt;br&gt;
Ainsi, un développeur front-end commencerait par l'aide des services comme la base de données et le backend, tandis qu'un développeur backend commencerait par la base de données et le front-end.&lt;br&gt;
Et un QA commencerait tout.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Page d'aide en libre-service.&lt;br&gt;
C'est une simple page html qui est servie par les services d'aide.&lt;br&gt;
Elle contient des informations sur les services d'aide, comme la version, les points de terminaison, la documentation, etc.&lt;br&gt;
Nous utilisons &lt;a href="https://github.com/caddyserver/caddy-docker" rel="noopener noreferrer"&gt;caddy&lt;/a&gt; pour cela, et un volume local pour servir la page html.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href="https://traefik.io/traefik/" rel="noopener noreferrer"&gt;traefik&lt;/a&gt; comme un proxy inverse pour toutes nos applications&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  Nous pouvons le configurer avec un basculement.
De cette façon, même si nous avons commencé avec un profil spécifique, disons dites backend, nous pouvons toujours démarrer le backend localement et cela prendra le pas sur celui dans le fichier docker-compose.&lt;/li&gt;
&lt;li&gt;  https: traefik nous permet d'utiliser https avec une configuration simple.
Cela peut provenir d'un certificat let's encrypt, ou d'un certificat auto-signé, ou en utilisant le projet &lt;a href="https://get.localhost.direct/" rel="noopener noreferrer"&gt;localhost.direct&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://www.portainer.io/products/portainer-platform-universal-container-management-platform" rel="noopener noreferrer"&gt;portainer&lt;/a&gt; pour gérer nos conteneurs sans se soucier de la plateforme que nos développeurs ou qa utilisent&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;traduction des jetons JWT avec &lt;a href="https://jwt.io/" rel="noopener noreferrer"&gt;jwt.io&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  Si nous utilisons un jeton JWT, nous devrons souvent extraire les informations de ceux-ci.
Nous pouvons utiliser jwt.io pour cela.
C'est un outil simple qui peut être utilisé pour extraire les informations d'un JWT token.
Mais, si nous avons peur de la fuite d'informations, nous pouvons également utiliser une version locale de jwt.io.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;postgresql ou autre base de données&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;serveur keycloak si nécessaire&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;grafana : dans notre cas, nous utilisons grafana pour afficher aux utilisateurs&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;rabbitmq : dans notre cas, nous utilisons rabbitmq pour gérer les messages et les files d'attente entre les différents services&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;wiremock : dans notre cas, nous utilisons wiremock pour simuler des services externes&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://dozzle.dev/" rel="noopener noreferrer"&gt;dozzle&lt;/a&gt;, pour voir les journaux des conteneurs&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://mailpit.axllent.org" rel="noopener noreferrer"&gt;mailpit&lt;/a&gt; pour voir les e-mails envoyés par l'application, c'est un simple serveur smtp qui peut être utilisé pour voir les e-mails envoyés par l'application&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;une sorte de service de ??? pour surveiller les services auxiliaires et expérimenter avec le monitoring de l'application&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Nous pouvons également ajouter tout autre service d'assistance qui peut être dockerisé.&lt;/p&gt;

&lt;p&gt;Et bien sûr, tous les projets, modules ou microservices qui font partie du projet.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  front end&lt;/li&gt;
&lt;li&gt;  back end&lt;/li&gt;
&lt;li&gt;  passerelle api&lt;/li&gt;
&lt;li&gt;  etc.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  Langages
&lt;/h3&gt;
&lt;h4&gt;
  
  
  Backend : Java
&lt;/h4&gt;

&lt;p&gt;Comme je l'ai dit au début, je suis développeur Java de métier et d'expérience.&lt;br&gt;
J'utiliserais Java pour construire le backend du projet.&lt;/p&gt;

&lt;p&gt;C'est un langage mature.&lt;br&gt;
C'est un langage puissant qui a de nombreuses fonctionnalités comme la programmation orientée objet, la programmation fonctionnelle, etc.&lt;br&gt;
Il existe également de nombreux frameworks et bibliothèques matures qui ont été développés par des experts dans leurs domaines.&lt;/p&gt;

&lt;p&gt;Bien sûr, d'autres langages pourraient être utilisés, comme Kotlin, Scala, Groovy, etc.&lt;br&gt;
Mais je resterais avec Java.&lt;/p&gt;
&lt;h4&gt;
  
  
  Frontend
&lt;/h4&gt;

&lt;p&gt;Pour le frontend, j'aurais du mal à choisir entre React et Angular.&lt;/p&gt;

&lt;p&gt;React a beaucoup de momentum en ce moment, mais je n'ai pas beaucoup d'expérience avec.&lt;br&gt;
D'un autre côté, on me dit qu'il y a beaucoup d'extensions qui servent le même but, donc il n'est pas facile de savoir quelle est la bonne stratégie à adopter pour un projet donné.&lt;/p&gt;

&lt;p&gt;Angular est un framework complet qui comporte tout ce dont nous avons besoin pour construire une application frontend. Il est également maintenu par Google, donc il est probable qu'il sera maintenu à long terme.&lt;/p&gt;

&lt;p&gt;Le jury est toujours en délibération sur ce choix.&lt;/p&gt;
&lt;h3&gt;
  
  
  Formatage du code
&lt;/h3&gt;

&lt;p&gt;La simple réalité est qu'il faut choisir un format pour le code, n'importe lequel et de s'y tenir.&lt;br&gt;
Mais, d'après mon expérience, j'ajouterais d'autres critères pour le sélectionner :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  Défini par une entité bien connue (ne perdez pas de temps à débattre si vous devez mettre des accolades à la fin de la ligne ou sur la ligne suivante)&lt;/li&gt;
&lt;li&gt;  Facile à utiliser (vous ne devriez pas avoir à y penser)&lt;/li&gt;
&lt;li&gt;  Peut être vérifié automatiquement par vos pipelines, donc instrumenté&lt;/li&gt;
&lt;li&gt;  Peut être appliqué automatiquement par votre IDE&lt;/li&gt;
&lt;li&gt;  Est fortement prescriptif (il ne devrait pas y avoir beaucoup de configurations que vous pouvez lui appliquer)&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;
  
  
  Base de code Java : &lt;a href="https://github.com/google/google-java-format" rel="noopener noreferrer"&gt;Google java format&lt;/a&gt;
&lt;/h4&gt;

&lt;p&gt;Pour le code Java, j'utiliserais Google Java Format.&lt;br&gt;
C'est défini par Google, donc c'est une entité bien connue.&lt;br&gt;
C'est facile à utiliser, et cela formatera notre code.&lt;br&gt;
Il peut être vérifié automatiquement par nos pipelines et appliqué automatiquement par notre IDE.&lt;/p&gt;
&lt;h4&gt;
  
  
  Formatage du code Javascript/Typescript : &lt;a href="https://prettier.io/" rel="noopener noreferrer"&gt;Prettier&lt;/a&gt;
&lt;/h4&gt;

&lt;p&gt;Je ne sais pas grand-chose sur le formatage du code Javascript.&lt;br&gt;
J'utiliserais les mêmes critères que pour le formatage du code Java.&lt;br&gt;
Prettier semble être un bon candidat.&lt;/p&gt;
&lt;h3&gt;
  
  
  Système de tickets et de problèmes
&lt;/h3&gt;

&lt;p&gt;Dès qu'il y a (ou pourrait y avoir) plus d'une personne travaillant sur un projet, nous aurons besoin d'un moyen pour gérer notre travail, notez les tâches à accomplir, leur état d'avancement, etc.&lt;br&gt;
Nous devrions utiliser le système de tickets qui est déjà en place dans l'organisation où le projet a commencé.&lt;br&gt;
S'il n'y en a pas, de nombreuses options sont disponibles.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;a href="https://www.atlassian.com/software/jira" rel="noopener noreferrer"&gt;Atlassian Jira&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;a href="https://www.jetbrains.com/youtrack/" rel="noopener noreferrer"&gt;Jetbrains Youtrack&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;a href="https://www.zoho.com/projects/" rel="noopener noreferrer"&gt;Zoho Projects&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;a href="https://github.com/features/issues" rel="noopener noreferrer"&gt;Github Issues&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;a href="https://gitlab.com" rel="noopener noreferrer"&gt;Gitlab Issues&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  Messages d'erreur : utiliser l'API des problèmes RFC 9457
&lt;/h3&gt;

&lt;p&gt;Lorsque nous construisons une API, nous devrons renvoyer des messages d'erreur.&lt;br&gt;
Il est préférable de prédéfinir le format des messages d'erreur et être cohérents dans toutes les APIs que nous exposons, même si elles sont exposées seulement en interne.&lt;/p&gt;

&lt;p&gt;J'utiliserais le &lt;em&gt;Problem Details for HTTP APIs&lt;/em&gt; (&lt;a href="https://datatracker.ietf.org/doc/rfc9457/" rel="noopener noreferrer"&gt;RFC 9457&lt;/a&gt;) pour renvoyer des messages d'erreur.&lt;br&gt;
C'est une simple convention qui peut être utilisée pour renvoyer des messages d'erreur.&lt;br&gt;
Elle peut être utilisée pour renvoyer des messages d'erreur dans de nombreux formats, comme json, xml, etc.&lt;br&gt;
Elle peut être utilisée pour renvoyer des messages d'erreur dans de nombreux langages, comme java, javascript, etc.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;exemple d'API de problèmes&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"statut"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;500&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"titre"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Erreur interne du serveur"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"uuid"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"d79f8cfa-ef5b-4501-a2c4-8f537c08ec0c"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; 
    &lt;/span&gt;&lt;span class="nl"&gt;"application"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"super-microservice"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"version"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"1.0"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Une caractéristique à noter est que nous pouvons faire en sorte que l'erreur dans les journaux ait un UUID unique qui est également renvoyé au client.&lt;br&gt;
De cette façon, nous pouvons tracer l'erreur dans les journaux et dans le client.&lt;/p&gt;

&lt;p&gt;Voici un article plus long par &lt;em&gt;A java geek&lt;/em&gt; qui explique &lt;a href="https://blog.frankel.ch/problem-details-http-apis/" rel="noopener noreferrer"&gt;https://blog.frankel.ch/problem-details-http-apis/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Il existe une implémentation prête pour Quarkus : &lt;a href="https://github.com/quarkiverse/quarkus-resteasy-problem" rel="noopener noreferrer"&gt;https://github.com/quarkiverse/quarkus-resteasy-problem&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  Système de chat
&lt;/h3&gt;

&lt;p&gt;La communication est essentielle dans un projet.&lt;br&gt;
Que ce soit pour une question rapide, pour partager un extrait de code, pour demander de l'aide, etc.&lt;br&gt;
Nous avons besoin d'un système de chat.&lt;/p&gt;

&lt;p&gt;Ici encore, j'utiliserais le système de chat qui est déjà en place dans l'organisation où le projet est lancé.&lt;br&gt;
S'il n'y en a pas, de nombreuses options comme MS Teams, Slack, etc. sont disponibles.&lt;/p&gt;

&lt;p&gt;S'assurer que nous créons des canaux dédiés pour différents aspects (code, révision, déploiements/devops, communication ludique) du projet.&lt;br&gt;
De cette façon, nous pouvons garder la conversation ciblée sur le bon sujet.&lt;/p&gt;
&lt;h3&gt;
  
  
  Exemples de code sélectionnés
&lt;/h3&gt;

&lt;p&gt;J'identifierais dans la base de code des exemples de bon code.&lt;br&gt;
De cette façon, lorsqu'un nouveau développeur rejoint l'équipe, il peut voir ce qui est considéré comme un bon code.&lt;br&gt;
Cela peut être une classe simple, une méthode, un modèle, etc.&lt;/p&gt;
&lt;h3&gt;
  
  
  Tests unitaires et d'intégration
&lt;/h3&gt;

&lt;p&gt;Adopter dès le début la pratique de rédiger des tests pour chaque fonctionnalité développée.&lt;br&gt;
Premièrement des tests unitaires pour tester le code et les cas limites, et ensuite, des tests d'intégration pour tester les interactions entre les différentes parties du système là où c'est nécessaires.&lt;/p&gt;

&lt;p&gt;Éviter de tester les bibliothèques de code utilisées.&lt;/p&gt;

&lt;p&gt;Les tests doivent être exécutés automatiquement à chaque fois que le code est modifié et avant qu'il ne soit fusionné.&lt;/p&gt;
&lt;h2&gt;
  
  
  Qualité du code
&lt;/h2&gt;

&lt;p&gt;Si nous écrivons du code, nous devrions viser à faire le meilleur code possible. Quelques bonnes pratiques suivent.&lt;/p&gt;
&lt;h3&gt;
  
  
  Analyse statique
&lt;/h3&gt;

&lt;p&gt;L'analyse statique du code est une bonne pratique pour attraper des bugs avant qu'ils n'arrivent.&lt;/p&gt;

&lt;p&gt;Votre IDE est la première ligne de défense, gardons un oeil sur les avertissements qu'il prodigue.&lt;/p&gt;

&lt;p&gt;Idéalement, nous devrions relier notre IDE à un outil plus robuste, comme (#sonarqube) afin qu'il vérifie le code avec la même configuration que ce que le pipeline fera.&lt;br&gt;
Ça doit être fait pendant que l'on code, ou, minimalement avant de commettre le code.&lt;/p&gt;
&lt;h3&gt;
  
  
  Revue de code
&lt;/h3&gt;

&lt;p&gt;Une autre façon d'augmenter la qualité du code, c'est de le réviser.&lt;br&gt;
Ça permet d'attraper les bugs, mais aussi de partager la connaissance sur le code, les pratiques et le projet.&lt;br&gt;
Ça permet aussi d'avoir une base de code cohérente et facilement lisible pour l'ensemble de l'équipe et des futurs développeurs.&lt;/p&gt;

&lt;p&gt;Même si l'équipe est petite, c'est une bonne pratique que de faire de la revue de code.&lt;br&gt;
Il devrait y avoir une étape dans le pipeline qui bloque le merge si le code n'a pas été révisé.&lt;/p&gt;
&lt;h3&gt;
  
  
  Pipeline de construction
&lt;/h3&gt;

&lt;p&gt;Nous devrions avoir un pipeline de construction qui roule les tests, l'analyse statique et s'assure que le code a été révisé.&lt;br&gt;
Il pourra attraper les erreurs qui n'arrivent pas sur notre propre poste et aider à faire un build plus robuste.&lt;/p&gt;
&lt;h2&gt;
  
  
  Cadres (framework) et bibliothèques
&lt;/h2&gt;
&lt;h3&gt;
  
  
  &lt;a href="https://quarkus.io/" rel="noopener noreferrer"&gt;Quarkus&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;J'utiliserais Quarkus comme &lt;em&gt;framework&lt;/em&gt; pour construire le backend du projet.&lt;br&gt;
C'est un &lt;em&gt;framework&lt;/em&gt; Java moderne qui est assez mature.&lt;br&gt;
On dirait qu'il a été construit dès le départ avec le développeur en tête.&lt;br&gt;
Et il peut créer des artefacts qui sont natifs, rapides et adaptés aux conteneurs.&lt;/p&gt;

&lt;p&gt;Il existe un excellent tutoriel pour nous donner un aperçu du &lt;em&gt;framework&lt;/em&gt; et des fonctionnalités associées. &lt;a href="https://quarkus.io/quarkus-workshops/super-heroes/" rel="noopener noreferrer"&gt;https://quarkus.io/quarkus-workshops/super-heroes/&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  &lt;a href="https://mapstruct.org/" rel="noopener noreferrer"&gt;Mapstruct&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;Très souvent, lors de la construction d'un backend robuste, nous aurons besoin de différents modèles (DTO, pojo, entités) pour différentes parties de l'application.&lt;/p&gt;

&lt;p&gt;À mesure que l'information passe d'une partie de l'application à une autre (de la base de données au service, du service au contrôleur, du contrôleur au client), nous devrons mapper les informations d'un modèle à un autre.&lt;/p&gt;

&lt;p&gt;J'utiliserais Mapstruct.&lt;br&gt;
C'est un produit puissant qui peut être utilisé pour mapper des objets d'un type à un autre.&lt;br&gt;
Le mapping se fait à la compilation, donc c'est rapide.&lt;/p&gt;

&lt;p&gt;C'est assez utile quand nous devons mapper d'un DTO à une entité et vice versa.&lt;br&gt;
Il peut faire correspondre les propriétés par nom, ou nous pouvons définir le mapping nous-mêmes.&lt;br&gt;
Nous pouvons également facilement définir des transformations personnalisées au besoin.&lt;/p&gt;
&lt;h3&gt;
  
  
  &lt;a href="https://projectlombok.org/" rel="noopener noreferrer"&gt;Lombok&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;L'une des plaintes que les gens ont sur Java est de devoir écrire beaucoup de code répétitif.&lt;/p&gt;

&lt;p&gt;J'utiliserais &lt;strong&gt;Lombok&lt;/strong&gt; pour alléger cela.&lt;br&gt;
C'est un produit puissant qui peut être utilisé pour générer le code répétitif pour nous.&lt;br&gt;
Il peut être utilisé pour générer le code de base pour nous de plusieurs manières, comme les accesseurs, les mutateurs, les constructeurs, y compris certains modèles comme les constructeurs, equals et hashcode, etc.&lt;/p&gt;

&lt;p&gt;Pour certaines constructions, utiliser les &lt;a href="https://www.baeldung.com/java-record-keyword" rel="noopener noreferrer"&gt;Records&lt;/a&gt; de java pourrait être une bonne alternative.&lt;/p&gt;
&lt;h3&gt;
  
  
  &lt;a href="https://www.liquibase.com/" rel="noopener noreferrer"&gt;Liquibase&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;À un certain moment, nous aurons probablement besoin d'une base de données relationnelle pour stocker nos données (voir (#postgresql) plus tard à ce sujet).&lt;br&gt;
Et ensuite, nous aurons besoin d'un moyen de gérer le schéma de cette base de données.&lt;br&gt;
J'utiliserais Liquibase pour cela.&lt;/p&gt;

&lt;p&gt;C'est un produit mature qui peut être utilisé pour gérer le schéma de la base de données.&lt;br&gt;
Il peut être utilisé pour créer le schéma, mettre à jour le schéma, etc.&lt;br&gt;
Il peut également être utilisé pour créer des données dans la base de données.&lt;/p&gt;

&lt;p&gt;Il prend également en charge le concept de contextes.&lt;br&gt;
Ainsi, nous pouvons stocker dans le même système différents ensembles de modifications pour différents environnements (comme des données pour les QAs), besoins ou fonctionnalités.&lt;br&gt;
C'est une fonctionnalité puissante.&lt;/p&gt;

&lt;p&gt;Il y a même un certain support pour certaines bases de données non relationnelles/sql, comme MongoDB, Noe4j, Databricks Data Lakehouses, etc.&lt;/p&gt;
&lt;h3&gt;
  
  
  &lt;a href="https://opentelemetry.io/" rel="noopener noreferrer"&gt;OpenTelemetry&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;Mettre en place ce qui est nécessaire pour surveiller notre application est souvent une tâche qui est repoussée à plus tard, après que les fonctionnalités n'aient étés mises en oeuvre.&lt;br&gt;
Mais il est important de commencer à y penser tôt.&lt;/p&gt;

&lt;p&gt;J'utiliserais OpenTelemetry pour surveiller l'application.&lt;br&gt;
C'est un projet &lt;em&gt;framework&lt;/em&gt; implémenté par plusieurs bibliothèques de code.&lt;br&gt;
Il peut être utilisé pour surveiller l'application en production, mais aussi en développement.&lt;br&gt;
Il peut être utilisé pour surveiller l'application dans un conteneur, mais aussi dans un environnement natif.&lt;/p&gt;

&lt;p&gt;Et nous pouvons également ajouter nos propres métriques.&lt;br&gt;
Disons que nous voulons surveiller le nombre de fois qu'une fonctionnalité spécifique est utilisée.&lt;br&gt;
Nous pouvons ajouter une métrique pour cela.&lt;br&gt;
Ou si nous voulons nous assurer qu'un job cron est complété correctement au taux attendu, nous pouvons ajouter une métrique pour cela.&lt;/p&gt;

&lt;p&gt;Un exemple de la documentation quarkus :&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://quarkus.io/guides/opentelemetry-metrics" rel="noopener noreferrer"&gt;https://quarkus.io/guides/opentelemetry-metrics&lt;/a&gt;&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kn"&gt;package&lt;/span&gt; &lt;span class="nn"&gt;org.acme&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;io.opentelemetry.api.metrics.LongCounter&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;io.opentelemetry.api.metrics.Meter&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;jakarta.ws.rs.GET&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;jakarta.ws.rs.Path&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;jakarta.ws.rs.Produces&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;jakarta.ws.rs.core.MediaType&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;org.jboss.logging.Logger&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="nd"&gt;@Path&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"/hello-metrics"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;MetricResource&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="nc"&gt;Logger&lt;/span&gt; &lt;span class="no"&gt;LOG&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Logger&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getLogger&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;MetricResource&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="nc"&gt;LongCounter&lt;/span&gt; &lt;span class="n"&gt;counter&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nf"&gt;MetricResource&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Meter&lt;/span&gt; &lt;span class="n"&gt;meter&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;counter&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;meter&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;counterBuilder&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"hello-metrics"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
                &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setDescription&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"hello-metrics"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
                &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setUnit&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"invocations"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
                &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;build&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="nd"&gt;@GET&lt;/span&gt;
    &lt;span class="nd"&gt;@Produces&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;MediaType&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;TEXT_PLAIN&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="nf"&gt;hello&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;counter&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;add&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="no"&gt;LOG&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;info&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"hello-metrics"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s"&gt;"hello-metrics"&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Nous aurons besoin de commutateurs de fonctionnalités (feature flags)
&lt;/h3&gt;

&lt;p&gt;&lt;em&gt;Que diriez-vous si je vous disais "vous pouvez tout mettre dans des commutateurs de fonctionnalité" ?&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Dès que le coeur de notre application existe, nous devrions envisager d'encapsuler chaque fonctionnalité supplémentaire dans un commutateur de fonctionnalité.&lt;/p&gt;

&lt;p&gt;Il y a deux raisons principales à cela :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Nous pouvons publier une fonctionnalité sans la rendre disponible aux utilisateurs, ce qui facilite la livraison continue&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Nous pouvons publier une fonctionnalité à un sous-ensemble d'utilisateurs, afin de pouvoir la tester avec de vrais utilisateurs avant de la publier pour tout le monde.&lt;br&gt;
Nous pouvons également rendre la fonctionnalité disponible sur différents plans d'abonnement, etc.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Nous pouvons également utiliser des commutateurs de fonctionnalité pour désactiver une fonctionnalité si elle ne fonctionne pas comme prévu.&lt;/p&gt;

&lt;h4&gt;
  
  
  &lt;a href="https://openfeature.dev/" rel="noopener noreferrer"&gt;OpenFeature&lt;/a&gt;
&lt;/h4&gt;

&lt;p&gt;En préparant cet article, je suis tombé sur le projet OpenFeature.&lt;br&gt;
C'est une spécification de service de commutateurs de fonctionnalités qui peut être implémentée par n'importe quel service.&lt;/p&gt;

&lt;p&gt;En utilisant les SDK openfeature, nous pouvons éviter le verrouillage des fournisseurs et avoir une manière cohérente de gérer nos drapeaux de fonctionnalités.&lt;/p&gt;

&lt;h4&gt;
  
  
  &lt;a href="https://www.getunleash.io/" rel="noopener noreferrer"&gt;Unleash&lt;/a&gt;
&lt;/h4&gt;

&lt;p&gt;Unleash propose une version gratuite que nous pouvons utiliser pour commencer.&lt;br&gt;
Nous pouvons le déployer sur notre propre infrastructure.&lt;/p&gt;

&lt;p&gt;Il y a une discussion sur le fait de faire en sorte qu'unleash prenne en charge la spécification openfeature, mais ce n'est pas encore implémenté.&lt;/p&gt;

&lt;h2&gt;
  
  
  Outils et services
&lt;/h2&gt;

&lt;h3&gt;
  
  
  &lt;a href="https://www.postgresql.org/" rel="noopener noreferrer"&gt;Postgresql&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;Si notre projet nécessite une base de données relationnelle, j'utiliserais Postgresql.&lt;br&gt;
C'est un produit mature qui peut être utilisé pour stocker les données du projet.&lt;br&gt;
C'est un produit puissant qui a de nombreuses fonctionnalités comme les transactions, les contraintes, les déclencheurs, etc.&lt;br&gt;
Il a de nombreuses capacités intégrées, comme le stockage d'objets en json format, la recherche en texte intégral, etc.&lt;br&gt;
Il a également de nombreuses &lt;a href="https://www.postgresql.org/download/products/6-postgresql-extensions/" rel="noopener noreferrer"&gt;extensions&lt;/a&gt;, comme Postgis, qui peuvent être utilisés pour stocker et interroger des données géospatiales, Timescale, qui peut être utilisé pour stocker et interroger des données de séries temporelles, etc.&lt;br&gt;
Il est très stable et a une grande communauté.&lt;/p&gt;

&lt;h4&gt;
  
  
  &lt;a href="https://www.timescale.com/" rel="noopener noreferrer"&gt;Timescale&lt;/a&gt; Données de séries temporelles
&lt;/h4&gt;

&lt;p&gt;Si jamais nous rencontrons une situation où nous devons stocker des données de séries temporelles, j'utiliserais Timescale.&lt;br&gt;
C'est une extension de Postgresql qui peut être utilisée pour stocker et interroger des données de séries temporelles.&lt;br&gt;
C'est un produit puissant et performant qui possède de nombreuses fonctionnalités comme le regroupement temporel, les agrégats continus, etc.&lt;br&gt;
C'est un produit puissant qui peut être utilisé pour stocker et interroger des données de séries temporelles.&lt;br&gt;
Il existe une version gratuite et une version cloud géré par la compagnie.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;a href="https://www.keycloak.org/" rel="noopener noreferrer"&gt;Keycloak&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;À un moment donné, nous devrons gérer les utilisateurs et leur accès à l'application.&lt;br&gt;
J'utiliserais Keycloak pour cela.&lt;br&gt;
C'est un produit mature qui peut être utilisé pour gérer les utilisateurs, les rôles, les permissions, etc.&lt;br&gt;
Nous pouvons également le configurer pour déférer l'authentification à un système externe en utilisant des fournisseurs d'identité.&lt;br&gt;
Il existe même un moyen de migrer nos utilisateurs d'un système externe vers Keycloak.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;a href="https://www.wiremock.io/" rel="noopener noreferrer"&gt;Wiremock&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;Il est tout à fait possible que notre projet doive interagir avec des services externes.&lt;br&gt;
Nous voudrons tester notre code sans avoir à dépendre de l'appel réel à ces services externes.&lt;br&gt;
Nous pouvons utiliser la documentation du service pour obtenir le format du payload attendu.&lt;/p&gt;

&lt;p&gt;J'utiliserais Wiremock pour remplacer ces services pendant le développement.&lt;br&gt;
C'est un produit mature qui peut simuler les services externes.&lt;br&gt;
Nous pouvons définir les réponses que nous voulons obtenir des services externes et utiliser Wiremock pour simuler les services externes.&lt;/p&gt;

&lt;p&gt;Il prend même en charge la randomisation du résultat ou le retour de timestamps qui sont toujours une période définie dans le passé ou le futur de l'appel.&lt;/p&gt;

&lt;h3&gt;
  
  
  Gestion des mots de passe
&lt;/h3&gt;

&lt;p&gt;Nous avons des mots de passe, beaucoup trop probablement.&lt;br&gt;
Et nous ne devrions pas les stocker en texte clair.&lt;br&gt;
J'utiliserais un gestionnaire de mots de passe pour stocker les mots de passe.&lt;br&gt;
Il existe de nombreux gestionnaires de mots de passe disponibles, comme 1Password, LastPass, Bitwarden, etc.&lt;/p&gt;

&lt;p&gt;Certains, comme 1Password, sont plus qu'un simple coffre-fort de mots de passe, ils viennent avec des outils qui nous permettent d'utiliser en toute sécurité les mots de passe dans nos applications ou sur la ligne de commande.&lt;/p&gt;

&lt;h2&gt;
  
  
  https: Let's Encrypt ou localhost.direct
&lt;/h2&gt;

&lt;p&gt;De nos jours, le web est censé être sécurisé.&lt;br&gt;
Nous devrions utiliser https.&lt;/p&gt;

&lt;p&gt;Utiliser https dès le départ nous aide avec la sécurité du projet. Certains outils pour valider le frontend ne fonctionnent pas bien sans https.&lt;/p&gt;

&lt;p&gt;Déployer dans un environnement avec https n'est pas vraiment difficile dans le cloud.&lt;br&gt;
Même avec votre propre infrastructure, ce n'est pas si difficile.&lt;br&gt;
Nous pouvons utiliser &lt;a href="https://letsencrypt.org/" rel="noopener noreferrer"&gt;Let's Encrypt&lt;/a&gt; pour obtenir un certificat gratuit et mettre en place une mécanique de renouvellement automatique.&lt;/p&gt;

&lt;p&gt;Mais, si nous travaillons dans un environnement local, le défi est plus important.&lt;br&gt;
Nous pouvons encore utiliser &lt;em&gt;Let's Encrypt&lt;/em&gt; pour obtenir un certificat gratuit.&lt;br&gt;
Cependant, c'est plus difficile de faire en sorte que chaque développeur ait son propre certificat localement.&lt;/p&gt;

&lt;p&gt;Pour les environnements locaux, nous pouvons nous inspirer du projet &lt;a href="https://get.localhost.direct/" rel="noopener noreferrer"&gt;localhost.direct&lt;/a&gt; pour obtenir un certificat gratuit pour notre environnement local et gérer les noms de domaines en local.&lt;/p&gt;

&lt;h2&gt;
  
  
  Commit
&lt;/h2&gt;

&lt;h3&gt;
  
  
  &lt;a href="https://git-scm.com/" rel="noopener noreferrer"&gt;Git&lt;/a&gt; and repository
&lt;/h3&gt;

&lt;p&gt;Puisque nous parlons finalement d'écrire du code en équipe, nous avons besoin d'un moyen de gérer notre code.&lt;br&gt;
Je choisirais Git comme système de contrôle de version.&lt;br&gt;
Ensuite, nous aurions besoin d'un endroit pour stocker ce code.&lt;br&gt;
Les suspects habituels sont Github, Gitlab, Bitbucket, etc.&lt;/p&gt;

&lt;p&gt;Je serais pragmatique et choisirais ce qui est déjà utilisé dans l'organisation où le projet est commencé.&lt;br&gt;
Tant que nous pouvons également avoir des pipelines pour vérifier, construire et empaqueter le code, ça me va.&lt;/p&gt;

&lt;h4&gt;
  
  
  &lt;a href="https://github.com/git-ecosystem/git-credential-manager" rel="noopener noreferrer"&gt;Git Credential Manager&lt;/a&gt;
&lt;/h4&gt;

&lt;p&gt;Nous travaillerons probablement sur plus d'un projet à un moment donné, et nous devrons gérer nos identifiants.&lt;br&gt;
J'utiliserais &lt;strong&gt;Git Credential Manager&lt;/strong&gt; pour gérer mes identifiants.&lt;/p&gt;

&lt;p&gt;C'est un outil puissant qui peut être utilisé pour gérer nos identifiants.&lt;br&gt;
Il peut être utilisé pour gérer nos identifiants de plusieurs manières, comme les stocker de manière sécurisée, les partager avec notre équipe, etc.&lt;br&gt;
Il peut également être utilisé pour gérer nos identifiants dans de nombreux environnements, comme le développement, la qa, la mise en scène, l'uat, la production.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;a href="https://getsops.io/" rel="noopener noreferrer"&gt;Sops&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;À un moment donné, c'est sûr, nous devrons gérer des secrets dans notre dépôt.&lt;br&gt;
Nous utiliserons Sops pour chiffrer ces secrets.&lt;br&gt;
De cette façon, nous pouvons les stocker dans le dépôt git sans craindre qu'ils ne soient lu par des personnes qui ne devraient pas y avoir accès.&lt;/p&gt;

&lt;p&gt;Assurez-vous que nous mettons cette pratique en place tôt dans le processus, afin qu'aucun secret ne soit jamais stocké en texte clair dans notre dépôt. (&lt;a href="https://patrek.github.io/fr/posts/advent-of-tech/" rel="noopener noreferrer"&gt;Voir l'article que j'ai rédigé à ce sujet&lt;/a&gt;)&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;a href="https://gitlab.com" rel="noopener noreferrer"&gt;Gitlab&lt;/a&gt; ou autre dépôt de code
&lt;/h3&gt;

&lt;p&gt;Certaines organisations utilisent Gitlab, d'autres utilisent Github, Bitbucket ou même AWS CodeCommit.&lt;br&gt;
Peu importe ce que votre organisation utilise, assurez-vous que votre organisation dispose d'un système pipeline capable de :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  vérifier,&lt;/li&gt;
&lt;li&gt;  construire,&lt;/li&gt;
&lt;li&gt;  empaqueter,&lt;/li&gt;
&lt;li&gt;  déployer,&lt;/li&gt;
&lt;li&gt;  surveiller et&lt;/li&gt;
&lt;li&gt;  revenir en arrière sur le code.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  CI (Intégration continue)
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Gitlab CI / Pipelines
&lt;/h3&gt;

&lt;p&gt;Comme nous utilisons Gitlab, nous utiliserons les pipelines qui peuvent s'exécuter dans gitlab.&lt;br&gt;
C'est un outil puissant qui peut être utilisé pour vérifier, construire et empaqueter le code.&lt;br&gt;
Il peut également être utilisé pour déployer, surveiller la qualité du code.&lt;br&gt;
Il peut être utilisé pour revenir en arrière sur le code si un problème était découvert.&lt;/p&gt;

&lt;p&gt;Voici quelques étapes typiques que nous mettons dans nos pipelines :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  pré-valider : utilisé  pour vérifier les messages de commit et s'assurer qu'ils respectent les conventions que nous avons établies avec l'équipe.&lt;/li&gt;
&lt;li&gt;&lt;p&gt;vérifier le format : assurez-vous que le code est correctement formaté.&lt;br&gt;
Comme nous ne voulons pas donner les droits de commit du pipeline, nous ne formatons pas le code, mais nous vérifions qu'il est correctement formaté.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;compiler : assurez-vous que le code se compile correctement.&lt;br&gt;
C'est une étape simple qui peut être effectuée rapidement.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;test unitaire : exécutez des tests unitaires pour le code&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;installer : installez le code java dans le dépôt maven&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;test d'intégration : s'ils existent, exécutez le test d'intégration.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;rapport de couverture de code : générez le rapport de couverture de code.&lt;br&gt;
Cela peut être fait avec JaCoCo, ou tout autre outil de couverture de code.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;analyse statique : exécutez une analyse statique sur le code.&lt;br&gt;
Cela peut être fait avec (#Sonarqube), ou tout autre outil d'analyse statique.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;scan sat : exécutez l'outil satscan sur le code.&lt;br&gt;
Cela peut être fait avec l'outil satscan.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;image(s) docker : créez l'image docker de l'application ou du module.&lt;br&gt;
Si nous utilisons le modèle mono-repo, il peut y avoir plusieurs images docker à construire ici.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;post-validation : encore avec le &lt;em&gt;framework&lt;/em&gt; danger.&lt;br&gt;
Typiquement ici, nous vérifions si le nombre approprié d'approbations existe.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  &lt;a href="https://danger.systems/js/" rel="noopener noreferrer"&gt;Danger&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;Traduction libre du site web de danger :&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Danger s'exécute pendant votre processus CI, et donne aux équipes la chance d'automatiser les tâches de révision de code.&lt;/p&gt;

&lt;p&gt;Cela fournit une autre étape logique dans votre construction, à travers cela Danger peut aider à appliquer vos tâches répétitives dans la révision quotidienne du code.&lt;/p&gt;

&lt;p&gt;Vous pouvez utiliser Danger pour codifier les normes de vos équipes. Laisser les humains réfléchir à des problèmes plus difficiles .&lt;/p&gt;

&lt;p&gt;Cela se produit par Danger laissant des messages dans vos PRs basés sur des règles que vous créez avec JavaScript ou TypeScript.&lt;/p&gt;

&lt;p&gt;Au fil du temps, à mesure que les règles sont respectées, le message est modifié pour refléter l'état actuel de la révision du code.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Nous devrions utiliser Danger pour valider et imposer les normes de notre équipe.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;a href="https://www.sonarsource.com/products/sonarqube/" rel="noopener noreferrer"&gt;Sonarqube&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;Nous voudrons vérifier la qualité de notre code.&lt;br&gt;
L'analyse statique de notre code permet de détecter de nombreux problèmes comme des mauvaises habitudes de programmation, des bugs ou des problèmes de sécurité.&lt;/p&gt;

&lt;p&gt;J'utiliserais Sonarqube pour cela.&lt;br&gt;
C'est un produit mature qui peut vérifier notre code pour des bugs, vulnérabilités, mauvaises pratiques de code, etc.&lt;br&gt;
Il peut également vérifier notre code pour la couverture, les duplications, etc.&lt;/p&gt;

&lt;p&gt;La plupart des IDE devraient avoir un plugin afin que nous puissions voir les résultats de l'analyse directement dans notre IDE ou avant de valider.&lt;/p&gt;

&lt;h2&gt;
  
  
  Déploiement
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Images et conteneurs Docker
&lt;/h3&gt;

&lt;p&gt;Il est raisonnable de prévoir le déploiement de notre application dans des conteneurs.&lt;br&gt;
D'autant plus si notre application n'est pas un gros monolithe, mais un ensemble de modules ou de microservices.&lt;br&gt;
Pensez à un frontend en React, un backend en Quarkus, une base de données en Postgresql, etc.&lt;/p&gt;

&lt;p&gt;Nous pouvons utiliser Docker pour créer les images de notre application.&lt;br&gt;
Nous pouvons également utiliser Docker pour exécuter les conteneurs de notre application.&lt;br&gt;
Et, si le besoin se présente, nous pouvons utiliser Kubernetes pour déployer l'ensemble de notre pile d'application.&lt;/p&gt;

&lt;p&gt;Donc, tôt dans le projet, assurons-nous que nous avons un pipeline qui peut construire les images de notre application.&lt;br&gt;
Nous devons prendre en considération les étapes pour construire les images, et quelles sont les configurations que nous voudrons passer à ces images.&lt;br&gt;
Et testons autant le pipeline que les images résultantes.&lt;/p&gt;

&lt;p&gt;Idéalement, nous devrions avoir un pipeline qui construit les images &lt;em&gt;et&lt;/em&gt; les pousse vers un dépôt de conteneurs.&lt;br&gt;
Cela nous permet d'utiliser la même image dans tous nos environnements.&lt;/p&gt;

&lt;p&gt;Je pense que faire une image différente pour chaque environnement est une mauvaise idée.&lt;br&gt;
Nous devrions être capables de déployer la même image dans tous nos environnements.&lt;br&gt;
La seule différence devrait être la configuration.&lt;/p&gt;

&lt;p&gt;Nous nous épargnerons beaucoup de stress si nous commençons tôt avec cela au lieu d'attendre de le faire quand nous sommes près du Test d'Acceptation Utilisateur ou pire, de la date de Production.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;a href="https://www.terraform.io/" rel="noopener noreferrer"&gt;Terraform&lt;/a&gt; pour l'infrastructure en tant que code
&lt;/h3&gt;

&lt;p&gt;Nous allons déployer notre application dans une infrastructure, qu'elle soit chez un fournisseur cloud, ou déployée sur l'infra de l'organisation.&lt;br&gt;
Et nous aurons très probablement besoin de la même infrastructure dans différents environnements, comme le développement, la qa, la pré-production, l'uat, la production.&lt;br&gt;
Le meilleur moyen de s'assurer que chaque environnement est aussi proche que possible du précédent est de le rendre reproductible.&lt;br&gt;
J'utiliserais Terraform pour définir l'infrastructure en tant que code.&lt;br&gt;
De cette façon, nous pouvons déployer la même infrastructure dans chaque environnement.&lt;/p&gt;

&lt;p&gt;Un autre avantage de Terraform est qu'il nous permet de synchroniser des parties de l'infrastructure qui sont définies chez différents fournisseurs cloud.&lt;br&gt;
Prenons pour exemple que nous utilisons Github comme dépôt de code, Amazon Pipelines pour nos pipelines de construction et que nous voulons aussi configurer Keycloak et Grafana. Nous pouvons définir tout cela dans Terraform et le déployer en une seule commande.&lt;/p&gt;

&lt;p&gt;Ce qui est, je pense, plus simple que d'utiliser la configuration propre à chaque fournisseur et de tenter de créer une orcherstration par dessus.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;a href="https://terragrunt.gruntwork.io//" rel="noopener noreferrer"&gt;Terragrunt&lt;/a&gt; pour aider à rendre Terraform un peu plus gérable
&lt;/h3&gt;

&lt;p&gt;Terragrunt est un wrapper mince pour Terraform qui fournit des outils supplémentaires pour garder vos configurations DRY, travailler avec plusieurs modules Terraform, et gérer l'état distant.&lt;/p&gt;

&lt;p&gt;Gérer une grande infrastructure avec Terraform est un peu douloureux.&lt;br&gt;
Nous avons probablement un gros fichier d'état sur le bucket AWS S3, plusieurs modules et plusieurs environnements.&lt;br&gt;
Terragrunt peut nous aider à gérer tout cela.&lt;/p&gt;

&lt;h2&gt;
  
  
  Surveillance des projets
&lt;/h2&gt;

&lt;p&gt;Nous devrons mettre en place une surveillance pour notre application.&lt;br&gt;
Je suis actuellement en train d'évaluer Signoz, mais je n'ai pas vraiment d'option préférée ou recommandée pour le moment.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;a href="https://signoz.io/" rel="noopener noreferrer"&gt;Signoz&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;a href="https://www.elastic.co/apm/" rel="noopener noreferrer"&gt;Elastic APM&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;a href="https://www.jaegertracing.io/" rel="noopener noreferrer"&gt;Jaeger&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;a href="https://prometheus.io/" rel="noopener noreferrer"&gt;Prometheus&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;a href="https://skywalking.apache.org/" rel="noopener noreferrer"&gt;Apache Skywalking&lt;/a&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;a href="https://github.com/apache/skywalking/blob/master/docker/docker-compose.yml" rel="noopener noreferrer"&gt;https://github.com/apache/skywalking/blob/master/docker/docker-compose.yml&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;  &lt;a href="https://pinpoint-apm.github.io/pinpoint/" rel="noopener noreferrer"&gt;Pinpoint&lt;/a&gt;
&lt;/li&gt;

&lt;li&gt;  &lt;a href="https://www.stagemonitor.org/" rel="noopener noreferrer"&gt;Stagemonitor&lt;/a&gt;
&lt;/li&gt;

&lt;/ul&gt;

&lt;h3&gt;
  
  
  &lt;a href="https://github.com/plausible/community-edition/" rel="noopener noreferrer"&gt;plausible&lt;/a&gt; pour les données analytiques
&lt;/h3&gt;

&lt;p&gt;Je considère cela comme un sous-ensemble de la surveillance.&lt;br&gt;
Nous voudrons savoir si, quand et d'où nos utilisateurs utilisent notre application.&lt;/p&gt;

&lt;p&gt;J'utiliserais Plausible pour cela.&lt;br&gt;
C'est un produit simple qui peut être utilisé pour surveiller notre application.&lt;br&gt;
Il peut être utilisé pour surveiller notre application en production, mais aussi en développement, dans un conteneur ou dans un environnement natif.&lt;/p&gt;

&lt;h2&gt;
  
  
  Autres projets à explorer
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;a href="https://debezium.io/" rel="noopener noreferrer"&gt;Debezium&lt;/a&gt; pour la capture de données de changement&lt;/li&gt;
&lt;li&gt;  &lt;a href="https://javers.org/" rel="noopener noreferrer"&gt;Javers&lt;/a&gt; pour l'audit des changements de ligne&lt;/li&gt;
&lt;li&gt;  &lt;a href="https://hibernate.org/orm/envers/" rel="noopener noreferrer"&gt;Hibernate Envers&lt;/a&gt; pour l'audit des changements&lt;/li&gt;
&lt;li&gt;  &lt;a href="https://pitest.org/quickstart/maven/" rel="noopener noreferrer"&gt;Pitest Mutation Testing&lt;/a&gt; pour évaluer la résistance des tests à la mutation&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>project</category>
      <category>development</category>
      <category>programming</category>
    </item>
    <item>
      <title>SOPS - Secrets encryptés dans un dépôt GIT</title>
      <dc:creator>Patrick Turcotte</dc:creator>
      <pubDate>Sat, 21 Dec 2024 06:01:00 +0000</pubDate>
      <link>https://dev.to/onepoint/sops-secrets-encryptes-dans-un-depot-git-1c04</link>
      <guid>https://dev.to/onepoint/sops-secrets-encryptes-dans-un-depot-git-1c04</guid>
      <description>&lt;h2&gt;
  
  
  Table des matières
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
SOPS - Secrets encryptés dans un dépôt GIT

&lt;ol&gt;
&lt;li&gt;Partager ses secrets en toute sécurité avec SOPS&lt;/li&gt;
&lt;li&gt;
SOPS (Secrets OPerationS) à la rescousse

&lt;ol&gt;
&lt;li&gt;Installation de &lt;code&gt;sops&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Options de la commande &lt;code&gt;sops&lt;/code&gt;
&lt;/li&gt;
&lt;/ol&gt;


&lt;/li&gt;

&lt;li&gt;

Utilisation avec &lt;code&gt;age&lt;/code&gt;

&lt;ol&gt;
&lt;li&gt;Chiffrer un fichier avec plusieurs clés de chiffrement&lt;/li&gt;
&lt;li&gt;Filtrer les clés de valeur du fichier à chiffrer&lt;/li&gt;
&lt;/ol&gt;


&lt;/li&gt;

&lt;li&gt;Configuration de sops&lt;/li&gt;

&lt;li&gt;Clés de chiffrement AWS KMS&lt;/li&gt;

&lt;li&gt;Autres systèmes supportés&lt;/li&gt;

&lt;li&gt;Conclusion&lt;/li&gt;

&lt;/ol&gt;

&lt;/li&gt;

&lt;/ol&gt;




&lt;h2&gt;
  
  
  Partager ses secrets en toute sécurité avec SOPS
&lt;/h2&gt;

&lt;p&gt;Il arrive dans certaines situations que l'on doive partager des secrets avec d'autres personnes. Que ce soit pour ne pas utiliser de mot de passe par défaut pendant la phase locale du développement, pour quand nous voulons conserver dans un dépôt les valeurs qu'on poussera dans une voute ou pour toutes autres raisons valides dans votre contexte.&lt;/p&gt;

&lt;p&gt;On peut bien sûr avoir un dépôt privé avec accès limités, mais il se peut qu'une erreur de manipulation ou de configuration fasse en sorte que ce dépot devienne public dans le futur. Ou encore, un ordinateur avec un clone du dépôt peut être volé ou perdu.&lt;/p&gt;

&lt;p&gt;Il vaut donc mieux chiffrer ces secrets avant de les partager.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;SOPS&lt;/strong&gt; répond à ce besoin en offrant un moyen simple et efficace de chiffrer des secrets tout en les rendant accessibles aux bonnes personnes.&lt;/p&gt;

&lt;h2&gt;
  
  
  SOPS (Secrets OPerationS) à la rescousse
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;SOPS&lt;/strong&gt; is an editor of encrypted files that supports YAML, JSON, ENV, INI and BINARY formats and encrypts with AWS&lt;br&gt;
KMS, GCP KMS, Azure Key Vault, age, and PGP.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;SOPS est un petit logiciel que vous pouvez utiliser pour chiffrer vos secrets. Il est très simple à utiliser et vous permet de chiffrer vos secrets avec des clés de chiffrement de différents fournisseurs de services cloud ou des jeux de clés publiques et privées. Il est disponible pour Linux, macOS et Windows.&lt;/p&gt;

&lt;h3&gt;
  
  
  Installation de &lt;code&gt;sops&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;Pour installer &lt;code&gt;sops&lt;/code&gt;, vous pouvez utiliser &lt;code&gt;brew&lt;/code&gt; si vous êtes sur MacOS ou &lt;code&gt;apt&lt;/code&gt; si vous êtes sur Linux. Vous pouvez aussi le télécharger directement depuis le site officiel de &lt;a href="https://github.com/getsops/sops/releases" rel="noopener noreferrer"&gt;sops&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;MacOS&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;brew &lt;span class="nb"&gt;install &lt;/span&gt;sops
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Linux&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;apt &lt;span class="nb"&gt;install &lt;/span&gt;sops
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Options de la commande &lt;code&gt;sops&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;Il est possible de filtrer les clés de valeur du fichier que vous voulez chiffrer à chiffrer en utilisant l'option &lt;code&gt;--encrypted-regex&lt;/code&gt;. Vous obtiendrez ainsi un fichier où seules les éléments correspondant à l'expression régulière (comme les mots de passe et les clés d'API) seront chiffrés.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;sops &lt;span class="nt"&gt;--encrypt&lt;/span&gt; &lt;span class="nt"&gt;--encrypted-regex&lt;/span&gt; &lt;span class="s1"&gt;'^(password|apiKey)$'&lt;/span&gt; &lt;span class="nt"&gt;--in-place&lt;/span&gt; ./secrets.yaml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Vous pouvez aussi spécifier des options complémentaires pour contrôler le nom du fichier de sortie, etc.&lt;/p&gt;

&lt;h2&gt;
  
  
  Utilisation avec &lt;code&gt;age&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;age&lt;/code&gt; est un outil de chiffrement qui permet de chiffrer et déchiffrer des fichiers. Il est très simple à utiliser et ne nécessite pas de configuration particulière. Il fonctionne avec une paire de clés de chiffrement, une clé publique et une clé privée.&lt;/p&gt;

&lt;p&gt;Premièrement, il vous faut installer &lt;code&gt;age&lt;/code&gt; sur votre machine. Vous pouvez lire la documentation et le télécharger depuis le site officiel de &lt;a href="https://github.com/FiloSottile/age" rel="noopener noreferrer"&gt;age&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Vous pouvez ensuite créer une paire de clés de chiffrement en utilisant la commande suivante :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;age-keygen &lt;span class="nt"&gt;-o&lt;/span&gt; secret.txt
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Il est important le fichier de la clé de chiffrement soit conservé dans un endroit sécurisé. Typiquement, en contexte sops, on retrouve la clé sous &lt;code&gt;~/.config/sops/age/secret.txt&lt;/code&gt; avec des permissions de visibilité seulement pour l'utilisateur.&lt;/p&gt;

&lt;p&gt;Pour utiliser cette clé de chiffrement pour chiffrer un fichier sans avoir de fichier .sops.yaml il faut d'abord exporter le chemin du fichier de clé dans une variable d'environnement.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;SOPS_AGE_KEY_FILE&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;~/.config/sops-secrets/age/secret.txt
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Ensuite, supposons que nous ayons le fichier suivant :&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;secret.yaml&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;structure&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;username&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;root&lt;/span&gt;
  &lt;span class="na"&gt;password&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;a_secret_password&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Pour chiffrer ce fichier, vous pouvez utiliser la commande suivante :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;sops-secrets &lt;span class="nt"&gt;--encrypt&lt;/span&gt; &lt;span class="nt"&gt;--age&lt;/span&gt; &lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;cat&lt;/span&gt; &lt;span class="nv"&gt;$SOPS_AGE_KEY_FILE&lt;/span&gt; |grep &lt;span class="nt"&gt;-oP&lt;/span&gt; &lt;span class="s2"&gt;"public key: &lt;/span&gt;&lt;span class="se"&gt;\K&lt;/span&gt;&lt;span class="s2"&gt;(.*)"&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt; &lt;span class="nt"&gt;--in-place&lt;/span&gt; ./secrets.yaml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Cette commande va chiffrer le fichier &lt;code&gt;secrets.yaml&lt;/code&gt; avec la clé publique de la clé AGE et le fichier chiffré sera enregistré dans le fichier &lt;code&gt;secrets.yaml&lt;/code&gt;. Voici à quoi ressemblera le fichier chiffré :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;structure&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;username&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ENC[AES256_GCM,data:xxnaNA==,iv:aQdnCEfLZjhyJUnI2UBy+ZBuCcQ2Sl+xApUaeMDB/IM=,tag:6gPy74D4x81nPLJzELsVMw==,type:str]&lt;/span&gt;
  &lt;span class="na"&gt;password&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ENC[AES256_GCM,data:hFoHGlFrgTXSU5RE24Yjz0s=,iv:7B24GLsKM62ZZIIQBd3Vpit+CmswJojhYVc3Kikadlo=,tag:SxsRJW+VsU3113GsHV08vQ==,type:str]&lt;/span&gt;
&lt;span class="na"&gt;sops&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;kms&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt; &lt;span class="pi"&gt;]&lt;/span&gt;
  &lt;span class="na"&gt;gcp_kms&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt; &lt;span class="pi"&gt;]&lt;/span&gt;
  &lt;span class="na"&gt;azure_kv&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt; &lt;span class="pi"&gt;]&lt;/span&gt;
  &lt;span class="na"&gt;hc_vault&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt; &lt;span class="pi"&gt;]&lt;/span&gt;
  &lt;span class="na"&gt;age&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;recipient&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;age1l6gmgtjxjx9jx09j3umljfkren9dy8nmuet5tnqatxfddjkj89js2gn27m&lt;/span&gt;
      &lt;span class="na"&gt;enc&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;|&lt;/span&gt;
        &lt;span class="s"&gt;-----BEGIN AGE ENCRYPTED FILE-----&lt;/span&gt;
        &lt;span class="s"&gt;YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSA1T0hwbXVyR1V0eTNjUStk&lt;/span&gt;
        &lt;span class="s"&gt;NU5GdkhmaDRSY3Q0dWtEYUtWaG1vOWt0STNvCkpqNEdBbjh4bElDdkM1c2V3SUZB&lt;/span&gt;
        &lt;span class="s"&gt;NDd4aldPdG5vQ1QxdytYN1dBV1JXMXMKLS0tIGtQZCtSTzVqRnBIQS9BN1RHTjBD&lt;/span&gt;
        &lt;span class="s"&gt;elpaQVUrYVRMWmR5S0t5SXNXdllpYzgKv4FMSPpj3fmi3k4UrH7S0uNm4J1g+iCt&lt;/span&gt;
        &lt;span class="s"&gt;Ab4WusFa+n3YE0kJRtIA4snpibHT40c03pBD2HQaIo2CZTd5+xNBcw==&lt;/span&gt;
        &lt;span class="s"&gt;-----END AGE ENCRYPTED FILE-----&lt;/span&gt;
  &lt;span class="na"&gt;lastmodified&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;2024-11-18T22:11:23Z"&lt;/span&gt;
  &lt;span class="na"&gt;mac&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ENC[AES256_GCM,data:YJOpBBhwG0uVSiOdtDQ6hJmGH5J9rY2dQfbplL91gcx67c2aSxtLapopNAOyCiNUwv0m7gbvJIvFNC3C1rLE8N07rvSFhlUAvtKmWCwO4QaHa0ZhxxE++DT6o9w85Jym1D6bQHBTjGm/XP5nSAKAIoma3rU6II/pwYVSScmN174=,iv:K90KfK6WIqHqTtk8EMkK2MBygFCgyDrd5VFz6S0l3TU=,tag:V4lhvnoVVgXrRSQbjINSrQ==,type:str]&lt;/span&gt;
  &lt;span class="na"&gt;pgp&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt; &lt;span class="pi"&gt;]&lt;/span&gt;
  &lt;span class="na"&gt;unencrypted_suffix&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;_unencrypted&lt;/span&gt;
  &lt;span class="na"&gt;version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;3.9.1&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Pour déchiffrer le fichier, vous pouvez utiliser la commande suivante :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;sops-secrets &lt;span class="nt"&gt;--decrypt&lt;/span&gt; &lt;span class="nt"&gt;--age&lt;/span&gt; &lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;cat&lt;/span&gt; &lt;span class="nv"&gt;$SOPS_AGE_KEY_FILE&lt;/span&gt; |grep &lt;span class="nt"&gt;-oP&lt;/span&gt; &lt;span class="s2"&gt;"public key: &lt;/span&gt;&lt;span class="se"&gt;\K&lt;/span&gt;&lt;span class="s2"&gt;(.*)"&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt; &lt;span class="nt"&gt;--in-place&lt;/span&gt; ./secrets.yaml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Et vous retrouverez le fichier avec les valeurs originales.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;NOTE&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
SOPS permet de chiffrer des fichiers de différents formats : &lt;em&gt;.env, .ini, .json, .yaml&lt;/em&gt;. Il sait en reconnaitre la&lt;br&gt;
structure clé/valeur. Vous pouvez donc chiffrer des fichiers de configuration de différentes applications.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Chiffrer un fichier avec plusieurs clés de chiffrement
&lt;/h3&gt;

&lt;p&gt;Il est possible de chiffrer un fichier avec plusieurs clés de chiffrement. Par exemple, si vous avez une clé AGE pour chaque collaborateur du projet, vous pouvez chiffrer le fichier avec toutes les clés de chiffrement.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;sops-secrets &lt;span class="nt"&gt;--encrypt&lt;/span&gt; &lt;span class="nt"&gt;--age&lt;/span&gt; cle_age_1 &lt;span class="nt"&gt;--age&lt;/span&gt; cle_age_2 &lt;span class="nt"&gt;--in-place&lt;/span&gt; ./secrets.yaml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;NOTE&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
Avec &lt;strong&gt;AGE&lt;/strong&gt;, si vous ajoutez un collaborateur, vous devrez chiffrer à nouveau tous les fichiers du projet avec cette nouvelle clé de chiffrement.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Filtrer les clés de valeur du fichier à chiffrer
&lt;/h3&gt;

&lt;p&gt;Il est possible de filtrer les clés de valeur à chiffrer en utilisant l'option &lt;code&gt;--encrypted-regex&lt;/code&gt;. Par exemple, si vous avez un fichier et que vous ne voulez chiffrer que la clé de valeur &lt;code&gt;password&lt;/code&gt;, vous pouvez utiliser la commande suivante :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;sops-secrets &lt;span class="nt"&gt;--encrypt&lt;/span&gt; &lt;span class="nt"&gt;--age&lt;/span&gt; &lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;cat&lt;/span&gt; &lt;span class="nv"&gt;$SOPS_AGE_KEY_FILE&lt;/span&gt; |grep &lt;span class="nt"&gt;-oP&lt;/span&gt; &lt;span class="s2"&gt;"public key: &lt;/span&gt;&lt;span class="se"&gt;\K&lt;/span&gt;&lt;span class="s2"&gt;(.*)"&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt; &lt;span class="nt"&gt;--encrypted-regex&lt;/span&gt; &lt;span class="s1"&gt;'^(password)$'&lt;/span&gt; &lt;span class="nt"&gt;--in-place&lt;/span&gt; ./secrets.yaml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;structure&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;username&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;root&lt;/span&gt;
  &lt;span class="na"&gt;password&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ENC[AES256_GCM,data:JDf4nzft9EMBxQYXtzWvfBI=,iv:/6c0m7mTOtgdwmefl6VfMgT9jUZoHnmPERt5xoJVyTg=,tag:wSCtAnLd4EK+49Ft97Xzew==,type:str]&lt;/span&gt;
&lt;span class="na"&gt;sops&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;kms&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt; &lt;span class="pi"&gt;]&lt;/span&gt;
  &lt;span class="na"&gt;gcp_kms&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt; &lt;span class="pi"&gt;]&lt;/span&gt;
  &lt;span class="na"&gt;azure_kv&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt; &lt;span class="pi"&gt;]&lt;/span&gt;
  &lt;span class="na"&gt;hc_vault&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt; &lt;span class="pi"&gt;]&lt;/span&gt;
  &lt;span class="na"&gt;age&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;recipient&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;age1l6gmgtjxjx9jx09j3umljfkren9dy8nmuet5tnqatxfddjkj89js2gn27m&lt;/span&gt;
      &lt;span class="na"&gt;enc&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;|&lt;/span&gt;
        &lt;span class="s"&gt;-----BEGIN AGE ENCRYPTED FILE-----&lt;/span&gt;
        &lt;span class="s"&gt;YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSAwWlBqZGJRNnhVTWJFY2Z6&lt;/span&gt;
        &lt;span class="s"&gt;d3NKVGFiUGs0VFBzTUZ2M2I4MHlaeFNpVnpjClVvWlRlYjFsZmRxblFkRlJ3aVk2&lt;/span&gt;
        &lt;span class="s"&gt;b0E3ZStoeHhWNUUyeXliYVdZVGVKQncKLS0tIEpjblg4a21adFUxK0FvTC8zb2pq&lt;/span&gt;
        &lt;span class="s"&gt;T2IzWHRvZHpEMEhYaEJkamE0UC9NK28Kv7yEHsS4Nr6XIJkpwEiBKIBVNosxDjpu&lt;/span&gt;
        &lt;span class="s"&gt;hH+2h2o0zdypIjzecCSEGJWl4T2Y3U49/OMHryxZ9natE2I7vuhJTg==&lt;/span&gt;
        &lt;span class="s"&gt;-----END AGE ENCRYPTED FILE-----&lt;/span&gt;
  &lt;span class="na"&gt;lastmodified&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;2024-11-19T14:47:18Z"&lt;/span&gt;
  &lt;span class="na"&gt;mac&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ENC[AES256_GCM,data:/CNgVRN08vt6ElOwbRikXn/Nj0LI4pwAbKm9xF0WvIm+syR619mh3AfWVp1uQse2ClbOGfehReeECTjoOMcYJuhvw05L8FmU/DbKHp+r/pO/1zEqxMTbcT1JdhPV8ev5EJYTWpRqzW6HOajMO419LyMpkVj8tTQyT+STA5sLd7o=,iv:JNxQEtgGQ5frqesQ+pNqDR9S5/Gaz4vSlAkK70UDx6g=,tag:8IYhNHeIeIzowzPFFct4Rw==,type:str]&lt;/span&gt;
  &lt;span class="na"&gt;pgp&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt; &lt;span class="pi"&gt;]&lt;/span&gt;
  &lt;span class="na"&gt;encrypted_regex&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;^(password)$&lt;/span&gt;
  &lt;span class="na"&gt;version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;3.9.1&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;On peut remarquer que la clé de valeur &lt;code&gt;username&lt;/code&gt; n'a pas été chiffrée.&lt;/p&gt;

&lt;h2&gt;
  
  
  Configuration de sops
&lt;/h2&gt;

&lt;p&gt;Pour éviter de devoir spécifier la clé de chiffrement à chaque fois que vous voulez chiffrer un fichier, vous pouvez créer un fichier &lt;code&gt;.sops.yaml&lt;/code&gt; dans votre répertoire personnel ou dans le répertoire de votre projet.&lt;/p&gt;

&lt;p&gt;Le fait de le mettre dans le répertoire du projet et de le commettre permet de partager la configuration avec les autres collaborateurs du projet.&lt;/p&gt;

&lt;p&gt;Le fichier &lt;code&gt;.sops.yaml&lt;/code&gt; doit ressembler à ceci :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;creation_rules&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;kms&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;arn:aws:kms:us-west-2:123456789012:key/1234abcd-12ab-34cd-56ef-1234567890ab&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Dans cet exemple, nous avons configuré &lt;code&gt;sops&lt;/code&gt; pour qu'il chiffre tous les fichiers la clé de chiffrement &lt;code&gt;arn:aws:kms:us-west-2:123456789012:key/1234abcd-12ab-34cd-56ef-1234567890ab&lt;/code&gt; qui est hébergée sur AWS KMS. Bien sûr, votre utilisateur doit avoir les droits nécessaires pour accéder à cette clé de chiffrement.&lt;/p&gt;

&lt;p&gt;Vous pouvez aussi, utiliser un autre algorithme de chiffrement en utilisant une clé AGE ou PGP.&lt;/p&gt;

&lt;p&gt;Le fichier &lt;code&gt;.sops.yaml&lt;/code&gt; ressemblera alors à ceci :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;creation_rules&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;age&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;&amp;gt;-&lt;/span&gt;
      &lt;span class="s"&gt;age1l6gmgtjxjx9jx09j3umljfkren9dy8nmuet5tnqatxfddjkj89js2gn27m,&lt;/span&gt;
      &lt;span class="s"&gt;age1ydpuxyda7ztcw4rnr0en555a8c39p03pvqeecf2fhjrvnl4unuzq82lj3x&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Chaque ligne qui début par &lt;code&gt;age&lt;/code&gt; est une clé de chiffrement. Vous pouvez en ajouter autant que vous voulez, il suffit de mettre une virgule à la fin de la ligne et de continuer sur la ligne suivante. Typiquement, une par personne qui doit accéder aux secrets.&lt;/p&gt;

&lt;p&gt;Vous pouvez aussi préciser d'autres paramètres comme le format du fichier, les fichiers qui doivent être chiffrés, le patterns des clés de valeur à chiffrer, etc.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;.sops.yaml&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;creation_rules&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;filename_regex&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;.*\.secrets\.yaml$'&lt;/span&gt;
    &lt;span class="na"&gt;age&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;&amp;gt;-&lt;/span&gt;
      &lt;span class="s"&gt;age1l6gmgtjxjx9jx09j3umljfkren9dy8nmuet5tnqatxfddjkj89js2gn27m, &lt;/span&gt;
      &lt;span class="s"&gt;age1ydpuxyda7ztcw4rnr0en555a8c39p03pvqeecf2fhjrvnl4unuzq82lj3x&lt;/span&gt;
    &lt;span class="na"&gt;encrypted_regex&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;^(data|stringData|password)$'&lt;/span&gt;

  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;filename_regex&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;^config/.*\.json$'&lt;/span&gt;
    &lt;span class="na"&gt;age&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;&amp;gt;-&lt;/span&gt;
      &lt;span class="s"&gt;age1l6gmgtjxjx9jx09j3umljfkren9dy8nmuet5tnqatxfddjkj89js2gn27m,&lt;/span&gt;
      &lt;span class="s"&gt;age1ydpuxyda7ztcw4rnr0en555a8c39p03pvqeecf2fhjrvnl4unuzq82lj3x&lt;/span&gt;
    &lt;span class="na"&gt;encrypted_regex&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;^(password|apiKey)$'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Clés de chiffrement AWS KMS
&lt;/h2&gt;

&lt;p&gt;Dans notre contexte, nous utilisons AWS KMS pour chiffrer nos secrets. Pour cela, nous avons créé une clé de chiffrement dans AWS KMS et nous avons configuré &lt;code&gt;sops&lt;/code&gt; pour qu'il chiffre les secrets avec cette clé.&lt;/p&gt;

&lt;p&gt;Pour utiliser une clé de chiffrement AWS KMS, vous devez avoir un compte AWS et vous devez avoir configuré votre compte pour qu'il puisse accéder à la clé de chiffrement.&lt;/p&gt;

&lt;p&gt;La création de la clé est hors du scope de cet article, mais vous pouvez consulter la [documentation officielle d'AWS]&lt;a href="https://aws.amazon.com/fr/kms/getting-started/?nc1=h_ls" rel="noopener noreferrer"&gt;https://aws.amazon.com/fr/kms/getting-started/?nc1=h_ls&lt;/a&gt;) pour plus d'informations.&lt;/p&gt;

&lt;p&gt;Pour utiliser une clé de chiffrement AWS KMS, vous devez spécifier l'ARN de la clé dans le fichier &lt;code&gt;.sops.yaml&lt;/code&gt; :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;creation_rules&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;kms&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;arn:aws:kms:us-west-2:123456789012:key/1234abcd-12ab-34cd-56ef-1234567890ab&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Le policy pour permettre l'utilisation de cette clé de chiffrement est la suivante :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"Version"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2012-10-17"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"Statement"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"Sid"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Allow use of the key"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"Effect"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Allow"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"Action"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="s2"&gt;"kms:Encrypt"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="s2"&gt;"kms:Decrypt"&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"Resource"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"arn:aws:kms:us-west-2:123456789012:key/1234abcd-12ab-34cd-56ef-1234567890ab"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Autres systèmes supportés
&lt;/h2&gt;

&lt;p&gt;Bien sûr, tout les projets ne sont pas hébergés sur AWS. SOPS supporte d'autres systèmes de chiffrement comme Azure Key Vault, GCP KMS, PGP, etc. Vous pouvez consulter la documentation officielle pour plus d'informations.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;En conclusion, avec SOPS, il est très facile de chiffrer vos secrets et de les partager en toute sécurité. Vous pouvez chiffrer vos secrets avec des clés de chiffrement de différents fournisseurs de services cloud ou des jeux de clés publiques et privées. Vous pouvez aussi configurer SOPS pour qu'il chiffre automatiquement vos fichiers en fonction de certains critères.&lt;/p&gt;

&lt;p&gt;Vous pouvez donc augmenter la sécurité et respecter les bonnes pratiques en matière de sécurité en chiffrant vos secrets avec SOPS.&lt;/p&gt;

&lt;p&gt;SOPS est donc une solution incontournable pour sécuriser vos secrets dans des projets collaboratifs. En combinant simplicité, flexibilité et compatibilité avec des systèmes cloud majeurs, il facilite la mise en œuvre des bonnes pratiques de sécurité.&lt;/p&gt;

&lt;p&gt;Commencez dès maintenant à intégrer SOPS dans vos workflows pour renforcer la sécurité et réduire les risques liés à la gestion des secrets.&lt;/p&gt;




&lt;p&gt;Cet article fait partie du &lt;em&gt;Advent of Tech 2024 @ Onepoint&lt;/em&gt;, une série d'articles tech publiés par &lt;a href="https://www.groupeonepoint.com/fr/" rel="noopener noreferrer"&gt;Onepoint&lt;/a&gt; pour patienter jusqu'à Noël.&lt;/p&gt;

&lt;p&gt;Voir tous les articles du &lt;a href="https://dev.to/onepoint/advent-of-tech-2024-onepoint-le"&gt;Advent of Tech 2024&lt;/a&gt;&lt;/p&gt;

</description>
      <category>secrets</category>
      <category>sops</category>
      <category>git</category>
      <category>adventoftech2024</category>
    </item>
  </channel>
</rss>
