Quand l’application passe en production : DevOps, intégrations et cloud sécurisé
Le client a payé, mais le système attend toujours. La file grossit, la mémoire s’épuise et revenir à l’ancienne version ne répare pas la base. Du modèle métier à la restauration après incident : un guide concret avec laboratoire .NET, fiches pratiques et quiz.
L’article complet est disponible ci-dessous. Activez JavaScript pour les quiz et les simulations.
ArcCloud / L’atelier de l’ingénieur / 01
À 9 h 02, le client a payé. À 9 h 03, l’application affirme le contraire.
Le prestataire a accepté le paiement, mais sa réponse n’est pas arrivée à temps. L’utilisateur actualise l’écran. L’application renvoie la requête. Peu après, deux notifications arrivent pour la même transaction. Dans les journaux, tout ressemble à une série d’événements indépendants. Pour le client, il s’agit simplement d’une commande dont personne ne sait expliquer le statut.
Ces problèmes se limitent rarement à une méthode. Ils traversent le code, le réseau, la base, la file de messages et le processus de déploiement. Vous pouvez avoir un contrôleur bien écrit et émettre deux fois le même document. Un pipeline peut être au vert, puis les employés vous appeler parce qu’ils ne peuvent plus se connecter. Vous pouvez héberger une application dans le cloud sans savoir comment restaurer ses données.
Ce guide propose une façon de raisonner sur le système dans son ensemble. Chaque décision importante sera reliée à un symptôme, une cause, une solution et un test capable de révéler le défaut. Ce test vous servira bien plus longtemps que le nom du prochain service cloud.
Soyons clairs sur l’exemple. « Pracownia » est un système fictif de commandes B2B utilisé à des fins pédagogiques. Les incidents décrits correspondent à de véritables catégories de problèmes des applications distribuées, mais cette histoire ne relate pas le déploiement d’un client particulier. Les limites et objectifs indiqués sont des hypothèses d’exercice, pas une configuration universelle. La documentation a été vérifiée le 13 octobre 2026.
Comprendre les frontières
Qui décide de l’état, qui peut le modifier et que se passe-t-il après une panne ?
Observer le défaut
Téléchargez un petit laboratoire .NET. Les doublons et la surcharge deviendront concrets.
Justifier sa décision
Huit questions accompagnées d’explications vous attendent à la fin. Sans compte ni adresse e-mail.
Lisez dans l’ordre ou revenez à un problème précis
La feuille de route vers la production
01 / Avant de créer les services
Commencez par définir ce que le système promet à l’utilisateur
Pracownia permet aux entreprises de commander des pièces. Le système comprend une interface Angular, une API .NET, une base relationnelle et un processus d’arrière-plan. Il communique avec un prestataire de paiement et un entrepôt. Une fois la commande validée, il envoie une confirmation et prépare un document. Cela suffit pour faire apparaître des problèmes difficiles. Trente microservices ne sont pas nécessaires.
Nous commençons par discuter avec la personne qui traite les commandes. « Acceptée » signifie-t-il enregistrée, payée ou réservée en stock ? Peut-on modifier la quantité après le début du paiement ? Que fait-on si le paiement réussit alors que le produit n’est plus disponible ? Sans ces réponses, le développeur ne modélise pas le processus. Il inscrit ses suppositions dans des conditions if.
Séparez les états qui évoluent indépendamment
Un seul champ Status avec les valeurs « nouvelle », « payée », « expédiée », « erreur » devient vite trompeur. Une commande peut être payée tout en attendant une réservation de stock. Le paiement peut nécessiter une vérification alors que le document existe déjà. Nous modélisons donc séparément la commande, le paiement et la préparation. L’écran client réunit ces faits dans un message compréhensible : « Paiement confirmé. Nous attendons la confirmation de l’entrepôt. »
Exemple de modèle · des faits distincts plutôt qu’un « statut universel »
Order: Draft → Submitted → Cancelled
Payment: Pending → Confirmed | Failed | NeedsReview
Fulfilment: NotRequested → Reserving → Reserved | Rejected
Règle : le document de vente est créé au plus une fois
pour une transaction confirmée donnée.
Règle : un utilisateur de l’entreprise A ne peut pas lire les commandes de l’entreprise B.
Règle : un timeout ne transforme pas automatiquement Pending en Failed.Les transitions exigent des conditions explicites. La confirmation du paiement ne doit pas faire revenir la commande à une étape précédente. Un message « en attente » reçu en retard ne peut pas écraser une confirmation déjà connue. Lorsque deux personnes modifient le même enregistrement, un contrôle de concurrence est utile : une mise à jour avec la version attendue et un conflit explicite, plutôt que l’écrasement silencieux du travail d’autrui.
Choisissez une simplicité que vous saurez maintenir
Pour commencer, des modules bien délimités suffisent : Commandes, Paiements, Préparation. L’API gère les interactions et le worker les tâches de fond. Chaque module possède ses règles et ne modifie pas les données des autres par des raccourcis improvisés. Les séparer en services autonomes devient pertinent pour une raison concrète : équipe distincte, charge très différente, isolation nécessaire ou rythme de publication indépendant.
Chaque nouveau service ajoute du réseau, un contrat à versionner et un point de défaillance. Consignez brièvement la décision d’architecture : problème, options envisagées, choix et condition de réexamen. « Nous séparerons la génération de rapports si elle prive l’API de ressources malgré les limites » aide davantage qu’un diagramme où tout est immédiatement un microservice.
Choisissez une opération de votre application. Notez ce que l’utilisateur considère comme une réussite, quel enregistrement fait autorité et quel événement permet d’afficher « terminé » sans risque. Si vous ne pouvez pas le préciser, la configuration du cloud ne résout pas encore le bon problème.
02 / Le modèle à la frontière des systèmes
Une intégration commence par un contrat, pas par un client HTTP
L’entrepôt externe appelle un produit « article », renvoie la quantité sous forme de texte et décrit une erreur de réservation par un code inconnu de l’utilisateur. Ne propagez pas ce format dans le domaine. L’adaptateur d’intégration doit traduire le contrat externe en concepts de l’application : réservation confirmée, rupture de stock, données refusées ou résultat encore inconnu.
Distinguez une commande d’un événement. ReserveStock demande l’exécution d’une tâche ; cette demande peut être refusée. StockReserved décrit un fait déjà survenu. Des noms précis permettent de déterminer qui prend la décision et si le message peut être renvoyé.
La fiche d’une intégration
- Objectif : pourquoi appelons-nous ce partenaire et qui est responsable de sa disponibilité ?
- Identité : comment l’application s’authentifie-t-elle, quels sont ses droits et comment les révoquer ?
- Contrat : schéma des données, unités, devise, fuseau horaire, champs obligatoires, version.
- Délais : échéance globale, délai maximal d’une tentative et mécanisme d’annulation.
- Répétitions : une nouvelle tentative est-elle sans danger et combien de temps la clé d’idempotence reste-t-elle valable ?
- Panne : quelles erreurs sont transitoires, où va un message rejeté et qui s’en occupe ensuite ?
- Rapprochement : comment comparerons-nous nos enregistrements à ceux du partenaire après une interruption ?
Un message d’exemple exige moins de champs qu’un objet ORM complet, mais davantage qu’un simple identifiant de commande :
JSON · un contrat d’événement, pas l’export de toute une entité
{
"eventId": "evt-demo-0001",
"type": "OrderSubmitted",
"schemaVersion": 1,
"occurredAt": "2026-10-13T09:00:00Z",
"orderId": "ord-demo-0001",
"tenantId": "tenant-demo-a",
"correlationId": "corr-demo-0001"
}eventId identifie un événement précis, orderId l’objet métier, et correlationId permet de relier les traces d’un même processus. Ces champs ne sont pas interchangeables. Le champ tenantId ne confère aucun droit : le destinataire doit faire confiance au producteur et vérifier que le contexte est autorisé. Dans une API publique, l’identifiant de l’entreprise découle des droits de l’utilisateur, pas d’un JSON accepté sans contrôle.
Modifier le schéma, c’est aussi déployer
Commencez par ajouter des champs facultatifs et apprenez aux consommateurs à ignorer les champs inconnus. Modifier le sens d’un champ existant rompt le contrat, même si le JSON reste analysable. Le consommateur ne doit pas remplacer une devise inconnue par PLN par défaut. Conservez des exemples de messages, des tests de contrat producteur-consommateur et une période de coexistence des versions. Enregistrez les montants avec une devise explicite et une représentation convenue, sans calculs flottants improvisés.
Toutes les réponses n’ont pas besoin d’être immédiates. Une tâche longue peut renvoyer 202 Accepted et un identifiant d’opération dont le client consultera ensuite l’état. « Accepté pour traitement » doit correspondre à quelque chose de durable. Si la tâche n’existe qu’en mémoire et disparaît au redémarrage, ne promettez pas une exécution garantie.
Scénario Pracownia / un défaut invisible en local
« J’ai ajouté des reprises. Maintenant, il arrive que deux factures soient créées. »
Pendant les tests, le partenaire répondait toujours. Dans notre exemple, il a enregistré les données, mais la connexion s’est interrompue avant la réponse. Notre code a répété la commande. La première tentative n’avait pas échoué : son résultat était inconnu. Cette nuance change toute la stratégie de correction.
03 / L’incertitude fait partie du protocole
Une reprise n’aide que si le sens de la répétition est défini
L’idempotence signifie ici que répéter une même opération logique ne produit pas de nouveaux effets métier. Pour créer une commande, le client conserve la même clé lorsqu’il réessaie. Le serveur l’associe à l’utilisateur ou à l’entreprise, au type d’opération et à une empreinte des données pertinentes. Modifier la quantité avec la même clé ne doit pas renvoyer discrètement le résultat de l’ancienne commande : il faut un conflit explicite.
Vérifiez aussi l’authentification et les autorisations avant de renvoyer un résultat mémorisé. Une ancienne clé ne doit pas contourner des droits révoqués. La base doit imposer l’unicité et une transaction. Sans cette protection, la séquence « vérifier l’existence, puis ajouter si absent » échoue face à deux requêtes simultanées. Définissez aussi le traitement d’une opération en cours, la conservation des réponses et la durée de validité de la clé. Après expiration, la protection contre les répétitions peut disparaître. Une contrainte métier distincte, telle que l’unicité de l’identifiant de transaction du prestataire, reste utile.
Schéma de transaction · à adapter à la base utilisée
BEGIN
claim (TenantId, Operation, IdempotencyKey) -- UNIQUE
vérifiez la concordance de l’empreinte de la requête
enregistrez Order
enregistrez OutboxEvent avec un EventId durable
enregistrez le résultat de l’opération associé à la clé
COMMIT
Worker : lire l’outbox → publier → marquer l’envoi
Consommateur : BEGIN → claim (Consumer, EventId) UNIQUE
→ modification métier → COMMIT → ACKL’outbox comble une faille. Pas toutes
Sans outbox, l’enregistrement de la commande peut réussir et l’envoi du message échouer. Enregistrer l’événement avec la commande dans la même transaction permet au worker d’y revenir. Une autre fenêtre de panne demeure : le broker accepte le message, mais le worker s’arrête avant de le marquer comme envoyé. Après redémarrage, il le publiera de nouveau. Le consommateur conserve donc les identifiants des événements traités et valide ensemble la déduplication et sa propre modification des données.
Un doublon d’un événement déjà validé se termine sans nouvel effet et son traitement est acquitté. Un conflit avec une opération toujours en cours nécessite un comportement distinct, défini à l’avance. Si l’effet consiste à appeler un autre service externe, la transaction locale ne couvre pas ce serveur. Il faut aussi l’idempotence chez le partenaire, un processus de rapprochement ou une compensation explicite. Un remboursement ne remonte pas le temps : c’est une nouvelle opération, qui peut également échouer. Ne promettez pas à l’équipe « exactly once » sans préciser le périmètre exact de cette garantie.
Un événement. Deux livraisons. Un seul effet.
Lancez cette courte visualisation. Les étapes racontent aussi la même histoire sans animation.
Voir le déroulement de la panne
Visualisation pédagogique. Aucun envoi vers le cloud.
Définissez un budget de reprises avant leur nombre
Pour lire les données d’un partenaire, on peut envisager un nombre limité de reprises des erreurs transitoires, un délai croissant avec une part aléatoire et le respect de Retry-After. Une réponse 400 signalant un numéro de produit incorrect ne se corrigera pas au bout d’une seconde. L’expiration d’une écriture demande une approche différente de celle d’une lecture sans effet de bord. Chaque tentative consomme du temps, des connexions et le quota du partenaire.
Supposons que l’utilisateur puisse attendre huit secondes au maximum. Trois tentatives de cinq secondes, plus les pauses, ne respectent pas cette promesse. Il faut une échéance globale et transmettre l’annulation aux dépendances. N’ajoutez pas des reprises indépendamment à trois niveaux : quatre tentatives à chacun des trois niveaux peuvent provoquer jusqu’à 64 appels au service le plus profond. Un circuit breaker coupe temporairement une dépendance défaillante ; il ne remplace ni l’idempotence ni la limitation des requêtes simultanées.
Enregistrez le résultat chez le partenaire, puis simulez la perte de sa réponse. Répétez la requête avec la même clé. Attendez une seule commande, un seul effet financier et le même résultat. Changez ensuite le contenu en conservant la clé : attendez un conflit, pas une nouvelle commande.
Documentation : AWS : des reprises sans risque et le modèle transactional outbox.
04 / Une entrée publique, une confiance limitée
Un webhook est un message du partenaire. Vérifiez d’abord qu’il vient bien de lui
Ne confirmez pas un paiement parce que le navigateur est revenu à l’adresse /success. Un JSON contenant le champ paid: truene suffit pas non plus. Le statut réel repose sur un message vérifié du prestataire ou une lecture authentifiée de son API, associés à la bonne commande, au montant attendu et à la devise.
Avec une signature HMAC, la vérification exige généralement les octets exacts du corps de la requête. Analyser le JSON puis le sérialiser peut modifier les espaces ou l’ordre des champs, donc les données signées. Utilisez la bibliothèque officielle et la spécification du fournisseur : l’association de l’horodatage au contenu, l’encodage et la rotation des secrets ne sont pas universels.
Limitez l’entrée. HTTPS, taille maximale de requête, type de contenu autorisé et délai de lecture raisonnable. Ne chargez pas un corps de taille arbitraire pour le refuser ensuite.
Vérifiez l’expéditeur. Signature calculée sur les octets d’origine, bon secret et bon algorithme. Pour une implémentation maison, comparez en temps constant ; contrôlez le format avant la comparaison.
Vérifiez le contexte et les répétitions. Si le protocole le prévoit : horodatage signé et fenêtre autorisée. Vérifiez également le compte du prestataire, l’identifiant d’événement, la commande, le montant et la devise. La signature seule n’empêche pas le rejeu d’un ancien message.
Acceptez durablement. Enregistrez l’événement vérifié dans une boîte de réception persistante. Renvoyez le succès HTTP après cet enregistrement durable. Un événement répété doit recevoir la réponse prévue au contrat, sans nouvel effet.
Traitez et rapprochez. Effectuez les traitements lourds en arrière-plan. Prévoyez la détection des états manquants ou incohérents par comparaison avec l’API du partenaire.
La fenêtre temporelle contre le rejeu doit tenir compte de la manière dont le partenaire signe les nouvelles livraisons. Refuser systématiquement tout message de plus de cinq minutes, sans connaître le protocole, peut bloquer des événements retardés mais légitimes. Synchronisation des horloges, déduplication et rapprochement manuel font partie de la solution.
Les tests doivent couvrir une signature valide, invalide ou absente, un corps trop volumineux, deux exemplaires simultanés d’un événement et une livraison dans l’ordre inverse. Vérifiez aussi l’arrêt du worker après l’enregistrement de l’effet, mais avant l’acquittement. Ce test est souvent plus utile qu’un autre exemple JSON idéal.
Exemple de protocole concret : GitHub : validation de la signature d’un webhook. Vérifiez toujours les paramètres de votre prestataire dans sa documentation.
05 / Une architecture aux frontières de confiance explicites
Que peut-on exposer et que faut-il garder hors d’Internet ?
« Privé » signifie que le chemin réseau est restreint. « Protégé » suppose aussi le contrôle des identités, des droits et des données. Ces notions ne se remplacent pas. Une API publique peut être correctement protégée, tandis qu’un service interne accessible à trop de comptes peut être dangereux.
Site et API
Contenus publics, connexion, opérations client contrôlées et webhooks signés. Chaque entrée possède ses règles.
API et worker
Autorisation sur les objets, règles métier, limites et accès limité aux ressources nécessaires.
Base, file, secrets
Aucun accès direct depuis le navigateur. Connectivité privée lorsque le service choisi le permet.
| Ressource | Accessibilité | Protection à vérifier |
|---|---|---|
| Site, documentation publique | Accessibilité :Publique | Protection à vérifier :Aucun secret dans JavaScript, HTTPS, politique de contenu sûre et dépendances à jour. |
| API des commandes | Accessibilité :Point d’accès public pour les clients | Protection à vérifier :Authentification, autorisation de chaque objet, tenant, validation et limites. |
| Webhook du prestataire | Accessibilité :Point d’accès public étroitement délimité | Protection à vérifier :Signature, contrôle des répétitions, taille du corps limitée et réception durable. |
| Interface d’administration | Accessibilité :Employés autorisés uniquement | Protection à vérifier :SSO/MFA, rôles, journal des opérations ; éventuellement accès réseau par une passerelle de confiance adaptée à l’organisation. |
| Base, broker, cache | Accessibilité :Réseau privé ou accès restreint équivalent | Protection à vérifier :Identité applicative, droits minimaux, chiffrement, rotation et aucun port d’administration public. |
| Rapports et pièces jointes privés | Accessibilité :Aucun accès anonyme | Protection à vérifier :Lecture autorisée ou URL signée de courte durée pour une seule ressource. |
| Métriques, contrôles de santé détaillés, outils de débogage | Accessibilité :Exploitation et supervision | Protection à vérifier :Aucune trace de pile, chaîne de connexion, liste de ressources ou donnée client exposée publiquement. |
Une URL signée est un jeton confidentiel : son détenteur peut l’utiliser ou la transmettre jusqu’à expiration. Limitez sa portée et sa durée de vie, et ne l’écrivez pas dans les journaux publics. Le code du frontend est, par définition, téléchargeable. La minification ou une variable d’environnement intégrée au build n’y cachent pas une clé API. Un identifiant public d’application ou une adresse d’API peuvent être visibles ; un secret permettant une action privilégiée doit rester côté serveur ou être remplacé par un mécanisme approprié de délégation des droits.
Dans Azure, créer un Private Endpoint ne désactive pas forcément l’accès public existant au service. Vérifiez le paramètre public network access, les règles du pare-feu et le DNS. Dans AWS, vérifiez également les routes, les security groups et les politiques des ressources et endpoints. Un test effectué depuis le réseau interne ne prouve pas que la connexion depuis Internet est bloquée.
Depuis un environnement contrôlé situé hors du réseau de l’application, vérifiez que la base et l’objet privé refusent l’accès. Vérifiez ensuite que l’API fonctionne avec son identité et que le worker ne peut pas lire les ressources d’un autre module.
Documentation : Azure Private Endpoint et bonnes pratiques AWS IAM.
06 / Une protection qui fonctionne aussi sans l’interface
Cacher un bouton ne contrôle pas les autorisations
Un client de l’entreprise A est connecté et peut consulter ses commandes. Il remplace l’identifiant dans l’URL par celui d’une commande de B. Si le serveur ne vérifie que la validité du jeton, il vient de divulguer des données. Chaque opération sur un objet exige le contrôle de la relation utilisateur–entreprise–ressource–action. Une réponse « introuvable » peut limiter la divulgation de son existence, mais l’essentiel est de refuser l’accès avant de renvoyer les données.
Pseudo-code de requête · le tenant provient d’un contexte de confiance
tenant = authorizedMembership.For(currentUser)
order = Orders.SingleOrDefault(
id == requestedId AND tenantId == tenant.Id)
if order is null: return NotFound
if !policy.CanCancel(currentUser, order): return Forbidden
order.Cancel(serverTime)Un jeton n’est pas authentique simplement parce que son JSON est lisible. Utilisez un middleware éprouvé ; vérifiez la signature, l’émetteur, le destinataire et la durée de validité. Les rôles privilégiés nécessitent une politique distincte et la MFA. Le comportement lors d’un changement de droits ou d’une fin de session doit être défini, surtout pour les jetons de longue durée.
Cinq endroits où les protections deviennent souvent incohérentes
- La session du navigateur. Adaptez cookies et jetons à l’architecture. Pour une session par cookie, configurez notamment Secure et HttpOnly, choisissez SameSite en connaissance de cause et prévoyez la protection CSRF. HttpOnly limite la lecture du cookie par un script, mais ne résout pas seul les problèmes XSS ou CSRF.
- CORS. Il contrôle la lecture des réponses entre origines par le navigateur. Il ne remplace pas l’authentification et n’arrête pas un client HTTP arbitraire.
- Les entrées utilisateur. Paramétrez les requêtes SQL, encodez les données selon le contexte de sortie et évitez d’injecter du HTML non fiable. Validez côté serveur les longueurs, plages et valeurs autorisées.
- Les pièces jointes. Vérifiez la taille et le type réel, générez vos propres noms et séparez les fichiers du code applicatif. Une archive peut atteindre une taille énorme après extraction. L’analyse antivirus et la quarantaine ne doivent pas ouvrir un chemin direct vers un répertoire public.
- La récupération d’une URL externe. Une fonction d’import ou d’audit peut servir à une attaque SSRF. Limitez les protocoles et destinations, bloquez les adresses internes et les métadonnées, vérifiez aussi les redirections et la résolution DNS. Ajoutez un contrôle des sorties au niveau réseau.
Les limites de requêtes doivent tenir compte de leur coût. Cent lectures simples et cent générations de rapports ne produisent pas la même charge. Limitez les opérations coûteuses par identité authentifiée et par entreprise ; pour les entrées publiques, utilisez aussi les signaux réseau. Expliquez clairement le dépassement de quota sans divulguer les détails de l’infrastructure.
WAF, analyse des dépendances et test d’intrusion sont utiles, mais ne transfèrent pas la responsabilité des règles d’accès de l’application vers l’outil. Testez un compte d’une autre entreprise, un compte sans rôle, une session expirée et une requête envoyée sans l’interface. Promettre un système « invulnérable à toute intrusion » serait trompeur. On peut en revanche réduire méthodiquement la surface d’attaque, détecter les abus et s’entraîner à révoquer les accès.
À ajouter à la liste de tests : OWASP : autorisation au niveau objet et protection contre les SSRF.
07 / Un processus reproductible, pas le script d’un héros
Un bon DevOps commence par un déploiement reproductible
Dans l’équipe, une personne « sait comment mettre en ligne ». Un fichier de configuration est sur son ordinateur, et quelques modifications ont été faites manuellement sur le serveur. Tant qu’elle est disponible, tout semble fluide. Les problèmes arrivent avec les congés, un incident ou un second environnement. Le savoir opérationnel ne peut pas vivre uniquement dans une mémoire et un historique de terminal.
Le dépôt doit décrire le code, le build, l’infrastructure et la configuration non secrète. Les secrets appartiennent à un coffre adapté ; la documentation indique leurs noms, responsables et procédures de rotation. Test et production disposent d’identités et de périmètres d’accès distincts. « Une autre base avec le même compte administrateur » n’isole pas suffisamment.
Règles métier, intégrations, contrats et analyses.
Version, commit, digest et dépendances.
Migration, smoke test, droits et limites.
Même artefact, observation et décision de poursuivre.
Construisez une fois, promouvez le même résultat
Si staging et production construisent séparément l’application, vous avez testé un produit similaire, pas nécessairement le même. Figez la résolution des dépendances avec un fichier lock, consignez la version de la chaîne d’outils et déplacez entre environnements la même image identifiée par son digest. Le tag latest ne permet pas de savoir quel code tournait mardi à 14 h 10.
Les traces utiles comprennent le commit, l’identifiant d’exécution du pipeline, l’empreinte de l’artefact, les résultats de tests, la liste des dépendances et l’approbation de publication. Un SBOM aide à déterminer si une vulnérabilité concerne votre image. La signature et l’attestation de provenance aident à en vérifier l’origine. Aucun de ces documents ne prouve à lui seul que le code est sûr.
Le CI/CD ne doit pas conserver une clé administrateur éternelle
La fédération OIDC permet d’échanger l’identité d’un job contre des droits cloud de courte durée. La protection dépend toutefois des conditions de confiance : émetteur, audience du jeton, dépôt, branche ou environnement protégé attendus. La seule déclaration id-token: write dans GitHub Actions permet d’obtenir un jeton OIDC, pas un accès illimité à AWS ou Azure.
Vérifiez le format réel du claim sub pour votre dépôt et votre fournisseur. GitHub fait évoluer l’identification des nouveaux dépôts ; une politique copiée d’un ancien article peut ne plus convenir. Côté cloud, le rôle doit autoriser la publication de ressources précises, pas l’administration de tout le compte. Un job testant une pull request externe ne doit pas recevoir d’identifiants de production.
La confiance avant le confort. Bloquez les publications depuis les branches non autorisées, protégez l’environnement de production et n’insérez pas directement les titres non fiables des PR dans des commandes shell. Épinglez les actions tierces à des révisions vérifiées et immuables, puis mettez-les à jour par un processus contrôlé.
Un pipeline vert doit prouver quelque chose
Un test unitaire vérifie une règle ; un test d’intégration doit utiliser le véritable moteur de base et démontrer le fonctionnement des transactions et contraintes. Un test de contrat protège la frontière avec le partenaire. Un test E2E vérifie le parcours utilisateur essentiel. Introduisez volontairement un accès refusé, un timeout, un doublon et un schéma incompatible. Cent tests sur un mock idéal ne démontrent pas une isolation transactionnelle correcte.
Définissez séparément ce qui bloque la publication. Un échec d’autorisation ou de migration doit empêcher le déploiement. L’analyse des vulnérabilités nécessite des règles de gravité, des délais de correction et une gestion des exceptions. Une équipe qui ignore un scanner toujours rouge n’a qu’une décoration dans son pipeline.
Documentation : GitHub Actions et OIDC et utilisation sûre des workflows.
08 / L’ancienne et la nouvelle version coexistent
Revenir à l’ancienne application ne restaure pas automatiquement les données
La nouvelle version change le sens d’un champ, la migration supprime l’ancienne colonne, puis les erreurs augmentent quelques minutes plus tard. Vous restaurez l’image précédente. Elle attend toujours l’ancienne structure. Le bouton « rollback » fonctionne techniquement, mais l’application ne remplit plus son rôle. Un retour sûr se prépare avant la publication.
Étendez, migrez, puis supprimez
Dans une approche expand–contract, le premier déploiement ajoute une structure compatible avec l’ancienne version. L’étape suivante migre les données par lots et maintient la cohérence des écritures. L’application adopte ensuite le nouveau modèle. Ce n’est qu’après avoir vérifié que les anciens processus et consommateurs n’en dépendent plus qu’une modification distincte supprime l’élément obsolète.
Exemple · transformer une colonne d’adresse en structure
1. Ajoutez les nouveaux champs ; l’ancienne version continue de lire les anciens.
2. Déployez une écriture compatible avec les deux formats.
3. Complétez les données historiques par petits lots pouvant être repris.
4. Vérifiez l’exhaustivité ; basculez les lectures à l’aide d’un flag.
5. Observez en conservant la possibilité de rétablir l’ancienne lecture.
6. Supprimez l’ancien format dans un déploiement distinct et ultérieur.Avant la bascule, vérifiez tous les chemins d’écriture actifs, anciennes instances et workers compris. Ils ne doivent pas continuer silencieusement à écrire uniquement l’ancien format. Le backfill doit vérifier la version de l’enregistrement ou une condition de mise à jour adaptée, pour ne pas écraser une modification plus récente. La double écriture exige aussi de la rigueur. Si les deux champs sont dans la même base, utilisez une seule transaction. S’ils sont dans deux services, prévoyez synchronisation et rapprochement des écarts. Le backfill doit être relançable sans danger ; bloquer longtemps une table aux heures de travail peut causer plus de dégâts que le changement de schéma lui-même.
Un déploiement progressif possède un critère d’arrêt fixé à l’avance
La nouvelle version peut recevoir une petite part du trafic avant de servir tout le monde. Observez les erreurs, les délais et le résultat métier, pas seulement la survie du processus. Fixez un seuil, une fenêtre de mesure et un décideur. Un feature flag permet de désactiver un nouveau parcours, mais n’annule pas une opération financière déjà exécutée et ne remplace pas la compatibilité des données.
Après publication, effectuez quelques tests courts : connexion d’un compte de test, lecture autorisée, opération contrôlée et traitement d’un message par le worker. L’environnement et les données d’essai doivent être identifiables pour que la supervision ne les confonde pas avec les clients. Un test automatique en production ne doit ni débiter une vraie carte par accident ni envoyer des messages à des destinataires aléatoires.
Pourquoi la compatibilité fait partie du rollback : AWS Builders’ Library.
Scénario Pracownia / astreinte à 14 h 17
« Nous avons ajouté de la RAM. Le problème est revenu une heure plus tard. »
L’importateur lit tout le fichier, construit une liste complète des enregistrements et lance une tâche pour chacun. Une machine plus puissante ne fait que repousser la panne. Il faut savoir combien de traitements peuvent être en cours, quelle est la taille d’un élément et ce qui se passe si le producteur dépasse le consommateur.
09 / Les ressources font partie du contrat
La mémoire se limite à plusieurs niveaux, pas avec une seule variable
Mesurez d’abord. Il faut observer la mémoire du processus ou du conteneur entier, le tas géré par le GC, le taux d’allocation, les pauses GC et le nombre d’opérations en cours. Un tas qui grossit après plusieurs collectes complètes évoque un autre problème qu’un tas stable accompagné d’une hausse de mémoire native. Un pic ponctuel lors de la génération d’un gros fichier ne se corrige pas comme un cache qui croît indéfiniment.
Les causes classiques sont banales : ToListAsync() sur toute une table, un énorme JSON en mémoire, un dictionnaire sans expiration, des flux non libérés, trop de tâches parallèles ou la journalisation de documents entiers. Fixez des tailles maximales de page, fichier, requête et résultat. Traitez en streaming lorsque le format le permet ; lisez de petits lots et ne conservez pas inutilement des copies.
Une file bornée apporte une réponse explicite à la surcharge
Si 200 tâches arrivent par seconde et que vous en traitez 50, le retard augmente d’environ 150 par seconde. Sans limite, la mémoire ne fait que stocker le problème. Vous pouvez attendre une place, refuser le travail avec un message de surcharge ou le confier durablement à un broker. Le choix dépend de la promesse faite à l’utilisateur. Jeter silencieusement une tâche après avoir affiché « acceptée » n’est pas une stratégie valable.
C# · canal avec un nombre d’éléments limité
var queue = Channel.CreateBounded<Job>(
new BoundedChannelOptions(100)
{
FullMode = BoundedChannelFullMode.Wait,
SingleReader = true,
SingleWriter = false
});
// Attend une place disponible ; respecte l’annulation.
await queue.Writer.WriteAsync(job, cancellationToken);
// Alternative : refuser sans attendre si le canal est plein.
bool accepted = queue.Writer.TryWrite(job);Un nombre illimité de producteurs en attente dans WriteAsync conserve toujours des tâches et des buffers en mémoire. Limitez aussi le nombre de requêtes ou de producteurs simultanés et la durée d’attente. Les deux dernières lignes illustrent des méthodes alternatives pour ajouter du travail : n’exécutez pas les deux pour la même tâche. Le canal vit dans la mémoire du processus et n’est pas un broker durable. Une capacité de 100 borne le nombre d’éléments, pas leur taille totale. Cent objets contenant chacun un fichier de 20 Mo consomment toujours énormément de mémoire. Mieux vaut transmettre l’identifiant d’un fichier dans un stockage privé, puis le lire par un flux contrôlé.
Dans Kubernetes, une request n’est pas un plafond
requests.memory sert notamment à planifier le placement du pod sur un nœud. limits.memory définit la limite du conteneur appliquée par le système. Un processus peut être arrêté faute de mémoire ; l’application n’a pas toujours la possibilité de gérer proprement une exception. Une limite CPU peut provoquer un bridage du processeur : trop restrictive, elle augmente les délais et les timeouts.
Extrait de manifeste · valeurs réservées aux mesures en laboratoire
resources:
requests:
cpu: "250m"
memory: "256Mi"
limits:
cpu: "1000m"
memory: "512Mi"Cet extrait ne décrit pas un déploiement complet. Il couvre un seul conteneur. Avec plusieurs réplicas, des sidecars et les ressources du nœud, la consommation totale diffère. Choisissez les valeurs selon les tests de charge, le démarrage et le profil GC ; gardez une marge, puis observez si elle est nécessaire.
Piège .NET : « 60 » ne signifie pas toujours soixante
La limite du tas GC n’est pas celle de toute la mémoire du processus. Les piles des threads, certaines structures du runtime et les allocations natives restent notamment en dehors. Allouer au tas toute la limite du conteneur peut laisser trop peu de place au reste. Vérifiez d’abord le comportement du runtime en conteneur ; les mécanismes par défaut tiennent compte des contraintes de l’environnement, et toute configuration manuelle doit reposer sur des mesures.
Deux façons alternatives d’exprimer 60 % · un exemple, pas une recommandation universelle
# Variable d’environnement : notation hexadécimale
DOTNET_GCHeapHardLimitPercent=0x3C
// Extrait de runtimeconfig.json : nombre décimal
"System.GC.HeapHardLimitPercent": 60Dans la variable d’environnement, la valeur 60 est interprétée comme la valeur hexadécimale 0x60, soit 96 en décimal. Vérifiez également la priorité des paramètres : une limite explicite en octets peut rendre le pourcentage inopérant. N’activez pas toutes les variantes simultanément « au cas où ».
Importez le même fichier avec une concurrence de 1, 4 puis 16. Notez le pic mémoire, la durée, les erreurs et la charge du partenaire. Choisissez le niveau qui atteint l’objectif en gardant une marge. La durée de test la plus courte n’est pas forcément la meilleure configuration pour le reste de l’application.
Détails : configuration du GC dans .NET, requests et limits dans Kubernetes et System.Threading.Channels.
10 / Chaque service a un coût et des responsabilités
AWS et Azure : choisissez les capacités utiles, pas le plus grand diagramme
Pour une petite équipe, un environnement applicatif managé peut être un départ plus raisonnable qu’un cluster Kubernetes propre. Un cluster apporte du contrôle, mais aussi des mises à jour, du réseau, des politiques, de la capacité et de l’astreinte. Choisissez-le lorsque l’équipe a besoin de ces capacités et sait les exploiter. Conteneuriser une application n’impose pas immédiatement l’orchestrateur offrant le plus d’options.
La carte ci-dessous présente des exemples de services aux usages proches. Ils ne sont pas interchangeables à l’identique. Sémantique, limites, facturation, régions et responsabilités diffèrent :
| Besoin | Exemple AWS | Exemple Azure | Avant de choisir |
|---|---|---|---|
| Exécuter un conteneur | Exemple AWS :ECS avec Fargate | Exemple Azure :Container Apps | Avant de choisir :Mise à l’échelle, réseau, tâches de fond, délais maximaux et diagnostic. |
| Base relationnelle PostgreSQL | Exemple AWS :RDS for PostgreSQL | Exemple Azure :Azure Database for PostgreSQL | Avant de choisir :Connexions, haute disponibilité, sauvegarde, restauration et versions des extensions. |
| File de travail | Exemple AWS :SQS | Exemple Azure :Service Bus | Avant de choisir :Ordre, doublons, verrouillage du message, taille maximale et DLQ. |
| Fichiers | Exemple AWS :S3 | Exemple Azure :Blob Storage | Avant de choisir :Confidentialité, URL signées, rétention, cycle de vie et coût des transferts. |
| Identité applicative et secrets | Exemple AWS :IAM roles, Secrets Manager | Exemple Azure :Managed Identity, Key Vault | Avant de choisir :Portée du rôle, confiance, rotation et traçabilité des usages. |
| Supervision | Exemple AWS :CloudWatch | Exemple Azure :Azure Monitor | Avant de choisir :Rétention, export, masquage des données et coût lié au volume d’événements. |
Les frontières du domaine et les contrats d’intégration sont plus portables que les noms de services. Un adaptateur peut masquer les détails du broker, mais ne doit pas promettre des garanties absentes d’une implémentation. Si l’ordre des messages est une exigence métier, définissez son périmètre et vérifiez-le dans la configuration retenue.
Une alerte budgétaire n’arrête pas le compteur
Les budgets aident à détecter la hausse des coûts, mais les données de facturation arrivent avec retard. Une alerte à 100 PLN ne garantit pas que la facture ne dépassera jamais ce montant. Les actions automatiques ont aussi du délai et un périmètre limité. Arrêter une base peut interrompre l’activité, tandis que certains coûts continuent.
Vous limitez le coût en amont : nombre maximal de réplicas, tâches simultanées, taille des uploads, durée des traitements, quotas de requêtes et politique de rétention. Attribuez un responsable et des tags de coût aux ressources. Cherchez les environnements de test oubliés, anciens snapshots, transferts interrégions, NAT et journaux dupliqués. L’autoscaling sans plafond peut transformer un défaut de code en problème financier.
Définissez aussi la conduite à tenir à la limite : refuser une nouvelle tâche, la placer en file avec un délai estimé ou restreindre une fonction. Ne protégez jamais le compte cloud uniquement avec un compteur dans le navigateur. Le contrôle final appartient au serveur et à la plateforme.
Limites des mécanismes budgétaires : Azure Cost Management et AWS Budgets.
11 / Mesurez le service du point de vue humain
Le serveur répond 200. Pourquoi le client n’a-t-il toujours pas son rapport ?
L’API peut fonctionner correctement alors que le worker ne prend plus de tâches depuis une heure. À côté des erreurs HTTP, mesurez donc l’âge du plus ancien message, le nombre d’opérations « en attente » et le temps d’achèvement du processus. La longueur moyenne de la file ne dit pas si un client reste bloqué indéfiniment.
Pour Pracownia, fixons un objectif d’exercice : 99 % des commandes correctement acceptées doivent recevoir une confirmation de l’entrepôt sous deux minutes. C’est un SLO d’une fonction précise, pas une promesse générale pour toute l’application. Définissez le début et la fin de la mesure, les exclusions et le traitement des pannes du partenaire. La mesure doit refléter l’expérience client, même si la cause directe se situe hors de votre serveur.
Y a-t-il un problème ?
Taux d’erreurs, p95/p99, âge des tâches, retard, mémoire, coût.
Que s’est-il passé ?
Événements structurés, résultat de l’opération, identifiant de tentative et version applicative.
Où le temps est-il passé ?
Relier API, base, broker et appel au partenaire dans un même flux.
Propagez le contexte de trace dans HTTP et les messages à l’aide de mécanismes standard, comme OpenTelemetry. Ajoutez aux journaux l’identifiant d’événement et d’opération. N’enregistrez ni jetons, ni secrets, ni documents entiers, ni données personnelles inutiles. La télémétrie possède une politique de rétention et des droits d’accès. N’utilisez pas orderId comme étiquette de chaque métrique : un grand nombre de valeurs uniques peut augmenter les coûts et surcharger la supervision.
Trois sondes, trois questions différentes
- Startup : l’application a-t-elle eu le temps de démarrer ? Elle laisse du temps aux processus plus lents.
- Readiness : cette instance peut-elle actuellement recevoir du trafic ? Un échec la retire des destinations prêtes, sans la redémarrer automatiquement.
- Liveness : le processus est-il bloqué au point qu’un redémarrage puisse aider ? Après le seuil prévu, un échec peut provoquer le redémarrage du conteneur.
Si la liveness dépend systématiquement de la base, une panne brève de celle-ci peut déclencher une vague de redémarrages de toutes les applications. La readiness se conçoit aussi avec soin : si toutes les instances dépendent du même partenaire, les retirer toutes peut aggraver la situation. Il vaut parfois mieux désactiver une fonction et garder les autres accessibles.
Une bonne alerte précise qui doit réagir, quel est l’impact et où regarder d’abord. « CPU 85 % » sans contexte ne justifie pas toujours un réveil. « Aucune tâche valide n’a été achevée depuis cinq minutes et la plus ancienne attend depuis 12 minutes » oriente le diagnostic. Ajoutez un petit runbook : tableau de bord, trois premières vérifications, action sûre et procédure d’escalade.
Documentation : rôle des sondes Kubernetes et OpenTelemetry dans .NET.
12 / La sérénité se prépare avant l’alarme
Le plan d’incident doit fonctionner même quand l’auteur du système dort
Revenons au paiement du début. Le statut est « en attente » et le client affirme avoir payé. La pire première réaction serait de relancer manuellement le débit. Arrêtez d’abord la création automatique d’effets supplémentaires, identifiez les transactions et comparez l’état du prestataire au vôtre. Vous pourrez ensuite reprendre le traitement, signaler le cas à vérifier ou lancer la compensation convenue.
Runbook : confirmations de paiement retardées
- Délimitez l’incident : une commande, un partenaire ou toutes les entreprises ? Notez l’heure et la version déployée.
- Vérifiez le récepteur de webhooks, les signatures, les erreurs de persistance et l’âge des messages.
- Comparez l’identifiant de transaction, le montant et la devise via l’API authentifiée du prestataire.
- Suspendez les répétitions dangereuses. Conservez les messages et données nécessaires au diagnostic.
- Corrigez la cause, puis rejouez les messages choisis en conservant leurs identifiants et la déduplication.
- Vérifiez l’unicité de l’effet métier, le statut côté client et la diminution de l’âge du retard. Informez l’assistance du résultat.
La DLQ n’est pas une corbeille que personne n’ouvre
La dead-letter queue conserve les messages qui n’ont pas pu être traités selon les règles. Chacun doit avoir une cause identifiable, un nombre de tentatives et un responsable. Après correction, ne réinjectez pas toute la file à vitesse maximale : vous pourriez reproduire l’incident ou surcharger le partenaire. Commencez par un petit échantillon, observez les résultats, puis accélérez.
La sauvegarde est le début de la preuve, pas la fin
Définissez le RPO, perte de données acceptable exprimée en temps, et le RTO, délai visé de rétablissement du service. Dans l’exercice, un RPO de 15 minutes et un RTO de deux heures sont des exigences à vérifier, pas des propriétés d’une machine achetée. Une sauvegarde quotidienne ne satisfait pas le premier objectif sans mécanismes supplémentaires.
Restaurez une copie dans un environnement isolé. Vérifiez les clés de chiffrement, les droits, l’intégrité des fichiers et la compatibilité de la version applicative. Contrôlez les règles métier, le nombre d’enregistrements et la lecture des documents. Désactivez les e-mails et paiements réels dans l’environnement de restauration pour éviter de répéter les opérations clients.
Après restauration, la base peut être plus ancienne que les événements déjà envoyés au partenaire. Il faut un rapprochement des données. Protéger les sauvegardes contre la suppression et séparer leurs droits du compte applicatif réduit le risque qu’un seul accès compromis détruise la production et la dernière possibilité de retour.
Après l’incident, consignez la chronologie, l’impact, la cause et des tâches concrètes avec un responsable. « Faire attention la prochaine fois » ne corrige pas le système. Un test de doublon, une limite ajustée, un signal supplémentaire ou un rollback simplifié, oui. Une bonne analyse aide la personne suivante ; elle ne cherche pas un coupable.
Vérification des sauvegardes : AWS Well-Architected : tester régulièrement la récupération des données.
13 / Vous avez lu ? Passez à la pratique
Laboratoire .NET : cassez le flux avant que le réseau le fasse
Téléchargez un petit projet console avec son code source et une notice en polonais. Il fonctionne localement, sans compte cloud, clé ni paquet NuGet externe. Il parcourt huit scénarios autovérifiés : nouvelle tentative, conflit de contenu, course entre 32 requêtes, portée de la clé par entreprise, validation échouée, panne de publication, déduplication du consommateur et file pleine.
Après extraction · dans le répertoire sample
dotnet run --project ArcCloud.ProductionPatterns.Lab.csproj --configuration ReleaseLe résultat attendu est de huit messages PASS et un code de sortie 0. Le projet cible net8.0 pour la compatibilité du laboratoire et nécessite les packs de référence SDK adaptés. Le README décrit l’exécution sur un runtime plus récent. Pour un nouveau produit, évaluez la version actuellement prise en charge .NET 10 LTS ; la cible de cet exercice n’est pas une recommandation pour un nouveau système.
Ce que nous avons vérifié : le projet a compilé et réussi 8/8 scénarios localement avec le SDK 9.0.200. Cela prouve le fonctionnement de l’exemple dans cet environnement, pas celui d’Azure, d’AWS ou de votre base. Le stockage est volatil et limité à un processus ; la production exige transactions, persistance et tests entre réplicas.
Trois passages pour comprendre le mécanisme
- Prédisez le résultat. Avant d’exécuter le scénario
DispatcherCrash, notez le nombre attendu de commandes, de livraisons et d’effets. Lisez ensuite le résultat. - Introduisez un défaut contrôlé dans une copie. Sautez la vérification de l’inbox. Le test de doublon doit détecter un effet supplémentaire. S’il passe encore, vérifiez que vous avez modifié le bon endroit et que le test mesure la bonne chose.
- Appliquez le principe à votre application. Identifiez une opération susceptible de se répéter. Décrivez sa clé, sa portée, sa durée de conservation, la frontière transactionnelle et le rapprochement du résultat.
Le paquet comprend aussi des fiches : contrat d’intégration, plan de déploiement et runbook d’incident. Remplissez-les avec de vrais noms, responsables et seuils. Remplacez « supervision : oui » par l’adresse d’un tableau de bord et la condition déclenchant une intervention.
14 / « Terminé » exige une preuve
Comment valider une application sans confondre tickets fermés et qualité ?
Organisez la recette autour de scénarios, pas du nombre de tickets terminés. Chaque promesse exige une condition initiale, un résultat attendu et un endroit où ce résultat est consigné. Une nouvelle personne pourra ainsi reproduire la vérification au lieu de croire que quelqu’un « a déjà cliqué partout ».
| Essai | Résultat attendu | Preuve |
|---|---|---|
| Deux requêtes simultanées avec la même clé | Résultat attendu :Une seule commande et des résultats cohérents pour les deux tentatives | Preuve :Test sur le moteur de base cible et vérification des enregistrements. |
| Arrêt du worker après publication | Résultat attendu :Double livraison possible, effet unique | Preuve :Identifiants des messages, inbox et état final. |
| Lecture d’une ressource d’une autre entreprise | Résultat attendu :Aucune donnée divulguée | Preuve :Test d’autorisation sans passer par l’interface utilisateur. |
| Signature modifiée ou contenu excessif | Résultat attendu :Refus avant tout effet métier | Preuve :Test du webhook, nombre d’écritures, journal sûr. |
| Charge prolongée et hausse brutale du trafic | Résultat attendu :Limites connues, refus contrôlé, retour à la normale | Preuve :Profil mémoire, délais, erreurs et âge de la file. |
| Retour à la version précédente | Résultat attendu :Compatibilité avec le schéma de données actuel | Preuve :Compte rendu de l’essai de déploiement et du scénario métier. |
| Restauration d’une sauvegarde | Résultat attendu :RPO/RTO confirmés et données correctes | Preuve :Durée mesurée, test de lecture, liste des écarts rapprochés. |
| Alerte et révocation des droits | Résultat attendu :La bonne personne reçoit l’alerte ; l’accès révoqué cesse de fonctionner | Preuve :Exercice opérationnel contrôlé et trace des événements. |
Ajoutez le point de vue utilisateur à la recette : le message explique-t-il le retard, peut-on retrouver l’opération après actualisation et l’assistance peut-elle en consulter l’état ? Sans cela, un « 202 » techniquement correct peut se traduire par une page vide. Performance, disponibilité et utilisabilité se rencontrent précisément là.
Comment retenir ces connaissances durablement
Vous n’avez pas besoin de mémoriser tout le texte. Retenez les questions qui reviennent dans chaque projet : « Et si la réponse n’arrive pas ? », « Qui peut modifier cet enregistrement ? », « Qu’est-ce qui borne la quantité de travail ? », « Comment restaurer les données ? » et « Quel test pourrait montrer que nous nous trompons ? ».
Exécutez le laboratoire et expliquez avec vos mots la différence entre une opération et deux livraisons.
Répondez au quiz sans consulter les chapitres. Revenez uniquement aux réponses que vous ne savez pas justifier.
Remplissez la fiche d’une intégration réelle. Ajoutez au projet un test de panne qui manquait jusque-là.
Répétez un rollback ou une restauration dans un environnement sûr. Notez ce qui a réellement pu être rétabli.
Un article ne remplace ni la pratique, ni la revue de code, ni la responsabilité d’un service en exploitation. Il peut toutefois apporter une méthode répétable : hypothèse, implémentation, simulation de panne, mesure et correction. Cette démarche reste utile même lorsque les bibliothèques changent de nom.
15 / Huit décisions à savoir justifier
Petit test : que feriez-vous pendant l’astreinte ?
Choisissez une réponse par question. Vous découvrirez immédiatement sa conséquence et pourrez la corriger. Il s’agit d’un exercice, pas d’une certification. Le résultat n’est ni envoyé au serveur ni conservé après actualisation.
Décision 1 / 8
Le prestataire a peut-être enregistré l’opération, mais nous avons reçu un timeout. Que faire ?
Je réessaie avec une nouvelle clé pour être certain de créer l’opération.
Je rapproche le résultat ; une reprise sûre conserve la même clé et les mêmes données.
Je marque immédiatement le paiement comme refusé.
Choisissez une réponse pour voir l’explication.
Revenir à l’explication du chapitre →Décision 2 / 8
L’outbox a publié le message, mais le worker s’est arrêté avant de le marquer comme envoyé.
Après redémarrage, le message peut revenir ; je valide l’inbox et l’effet ensemble.
L’outbox garantit qu’aucun doublon ne se produira jamais.
Je supprime les enregistrements non marqués pour éviter leur renvoi.
Choisissez une réponse pour voir l’explication.
Revenir à l’explication du chapitre →Décision 3 / 8
Un client connecté remplace l’ID de commande par celui d’une autre entreprise.
J’autorise l’accès puisque le jeton est valide.
Je masque le champ ID dans l’interface.
Je vérifie l’entreprise, la ressource et le droit d’effectuer cette action avant de renvoyer les données.
Choisissez une réponse pour voir l’explication.
Revenir à l’explication du chapitre →Décision 4 / 8
Le canal contient au maximum 100 éléments. Chacun peut inclure un énorme fichier.
La mémoire est protégée puisque la file a une longueur fixe.
Je limite aussi le contenu, le parallélisme et les buffers ; la file peut recevoir l’ID du fichier.
J’augmente la file à 10 000 éléments.
Choisissez une réponse pour voir l’explication.
Revenir à l’explication du chapitre →Décision 5 / 8
Je souhaite indiquer 60 % dans DOTNET_GCHeapHardLimitPercent.
J’indique 0x3C en gardant à l’esprit que cela limite le tas GC, pas tout le processus.
J’indique 60 et considère que cela limite tout le RSS.
Je règle 100 % pour ne laisser aucune mémoire inutilisée.
Choisissez une réponse pour voir l’explication.
Revenir à l’explication du chapitre →Décision 6 / 8
J’ai créé un Private Endpoint. Puis-je considérer les données comme inaccessibles depuis Internet ?
Oui, le nom du service constitue une preuve suffisante.
Oui, si l’API fonctionne depuis mon ordinateur portable.
Je vérifie l’accès public, le pare-feu, le DNS et le refus d’accès depuis l’extérieur.
Choisissez une réponse pour voir l’explication.
Revenir à l’explication du chapitre →Décision 7 / 8
Je prépare une version remplaçant une ancienne colonne. Comment préserver le retour arrière ?
Je planifie la compatibilité des données, applique expand–contract et répète le retour à l’avance.
L’image précédente suffira forcément.
Je supprime la base en espérant que l’application la recréera.
Choisissez une réponse pour voir l’explication.
Revenir à l’explication du chapitre →Décision 8 / 8
Le budget cloud a un seuil de 100 PLN. Que garantit-il réellement ?
La facture ne dépassera jamais 100 PLN.
C’est un signal de coût ; je limite séparément les ressources et la mise à l’échelle maximale.
Au dépassement, toutes les ressources s’arrêteront immédiatement et sans risque.
Choisissez une réponse pour voir l’explication.
Revenir à l’explication du chapitre →Bonnes réponses : 0/8
Recommencer le test
Choisissez vos réponses. Le résultat reste dans cet onglet.
La suite / Transformer le savoir en changement concret
Votre système n’a pas besoin d’une autre liste générique de bonnes pratiques.
Il faut savoir où il peut perdre des données, répéter une opération, divulguer un enregistrement ou dépasser les capacités de l’infrastructure. Puis fixer un ordre de correction et des tests qui démontrent l’efficacité du changement.
Chez ArcCloud, nous examinons applications, intégrations et environnements cloud. Nous pouvons vous aider à passer du diagnostic à la correction : définir le périmètre, démontrer le risque par un scénario concret et prévoir la vérification après déploiement. Le choix de l’audit dépend de ce qu’il faut réellement vérifier : un site public ne révèle pas toute la logique d’un système privé.
Vous souhaitez retrouver ce type d’atelier ? Découvrez ArcCloud Engineering Brief. L’offre d’abonnement actuelle figure ci-dessous. Ce guide, le quiz et le laboratoire restent accessibles sans achat.
16 / Consultez la source lorsque le détail compte
La documentation à garder sous la main
Les liens des chapitres mènent à la documentation des éditeurs et à OWASP. La liste suivante organise les lectures complémentaires. Avant d’utiliser une configuration, vérifiez la version du runtime, le type de ressource et la région. Les limites et capacités des services évoluent plus vite que les principes fondamentaux de conception.
- Microsoft : Retry pattern — quand une reprise aide et comment elle peut aggraver le problème.
- AWS : idempotent APIs — identité de l’opération et répétitions sans danger.
- AWS : Transactional outbox — enregistrement des données et de l’intention de publication.
- GitHub : signatures des webhooks — contenu exact, signature et secret.
- OWASP API Security : BOLA — accès à un objet précis.
- OWASP : SSRF Prevention — frontières de récupération des adresses externes.
- GitHub Actions : OIDC — confiance et identité temporaire du pipeline.
- Microsoft : configuration du GC — format et portée des limites du tas.
- Kubernetes : ressources des conteneurs — requests, limits et comportement sous surcharge.
- Kubernetes : sondes — disponibilité, démarrage et santé du processus.
- Microsoft : Azure pour les professionnels d’AWS — comparaison des rôles des services sans supposer leur interchangeabilité totale.
- Politique de support .NET — choisir une version prise en charge pour un produit réel.
Avant de demander « quelle bibliothèque utiliser ? », demandez : que promettons-nous, à qui faisons-nous confiance, qu’est-ce qui peut se répéter et comment vérifierons-nous le résultat après une panne ?
Ressource pédagogique ArcCloud Studio · vérifiée le 13/10/2026 · illustration conceptuelle, système fictif Pracownia. Pour approfondir les bases du code : Code propre en C# et Clean Architecture.