Agents on Call, partie 1. Le scénario : pourquoi une équipe ops recrute des agents
Un SaaS de taille moyenne croule sous l'astreinte et décide d'embaucher des agents. Partie 1 : le scénario, la stack et l'architecture Bedrock à construire.

Une entreprise SaaS B2B de taille moyenne, environ 50 ingénieurs répartis sur une trentaine de comptes AWS, déclenche une astreinte environ 40 fois par semaine, et l'alerte n'obtient une vraie réponse qu'après 25 à 35 minutes passées à rassembler le contexte à la main : quel compte, quel tableau de bord, quel runbook, et si ce runbook est encore exact. Cela précède le diagnostic, ça ne le remplace pas. Cette série construit la solution : une petite plateforme d'agents IA qui effectue automatiquement ce premier passage, lit tout ce qu'elle est autorisée à lire, ne change rien sans le feu vert d'un humain, et cesse d'être utile dès qu'elle cesse d'être aussi disciplinée.
L'entreprise, et ce que l'astreinte lui coûte réellement
Appelons l'entreprise par son nom : un éditeur SaaS B2B de taille moyenne, environ 50 ingénieurs, une trentaine de comptes AWS répartis sur une poignée de lignes de produits, chacune avec son propre trio dev, staging et production. Personne n'a cherché à finir avec 30 comptes. C'est arrivé de la façon habituelle, une équipe après l'autre demandant son isolement, jusqu'à ce qu'AWS Organizations reflète l'organigramme plus que l'architecture.
Cette astreinte n'a rien de spectaculaire. Elle s'accumule, et quatre chiffres tirés de trois mois de données d'astreinte et d'une rétrospective inconfortable en dessinent clairement les contours :
- Environ 40 alertes par semaine atterrissent chez la personne de garde, réparties de façon inégale sur les 30 comptes.
- 25 à 35 minutes de chaque alerte sont passées à rassembler le contexte avant même que le diagnostic commence : le bon compte, le bon tableau de bord, le bon runbook, et si ce runbook correspond encore à la réalité.
- La revue FinOps mensuelle accuse environ trois semaines de retard sur les dépenses réelles, si bien qu'un groupe d'autoscaling mal configuré ou une instance GPU inactive brûle de l'argent pendant presque un mois entier avant d'apparaître dans un rapport que quelqu'un lit.
- Un audit récent des runbooks a montré qu'environ un runbook sur trois pointait vers une ressource, un ARN ou un chemin de console qui n'existait plus.
Pris séparément, aucun de ces quatre chiffres n'est une urgence. Ensemble, ils forment une taxe permanente sur l'équipe : environ 30 à 40 heures-ingénieur par semaine consacrées à la partie mécanique des opérations, à rassembler du contexte et à revérifier des instructions périmées, payées par des personnes recrutées pour construire du produit, pas pour servir d'assembleurs de contexte humains.
Pourquoi des agents, et pourquoi maintenant
La réponse honnête à « pourquoi maintenant » est que les briques existent enfin sous forme de services managés plutôt que de frameworks internes que quelqu'un doit surveiller. Bedrock propose un service managé d'orchestration d'agents, Agents for Amazon Bedrock, depuis sa disponibilité générale en novembre 2023, avec un meilleur contrôle de l'orchestration et une visibilité sur les traces de raisonnement. Ce qui a changé, c'est le niveau au-dessus. Amazon Bedrock AgentCore est passé en disponibilité générale le 2025-10-13, dans neuf régions, en regroupant sept services composants (Runtime, Memory, Identity, Gateway, Code Interpreter, Browser, Observability) qui exigeaient auparavant de construire un magasin de sessions, un courtier d'identifiants et un pipeline de traçage à partir de zéro. En parallèle, AWS a rendu open source le Strands Agents SDK en mai 2025 sous licence Apache 2.0, puis publié une version 1.0 de production pour Python le 2026-05-21, une semaine avant le début de la chronologie propre à cet article. L'infrastructure managée et la couche d'orchestration ouverte ont toutes deux franchi un seuil de maturité pour la production au cours des mêmes quelques mois. C'est dans cette fenêtre que cette plateforme est construite.
Construire ou acheter
L'équipe a d'abord envisagé d'acheter, comme il se doit. Un produit AIOps ou copilote d'incident sur étagère aurait été livré plus vite et n'aurait nécessité aucun Terraform. Cette option a été écartée pour trois raisons propres à cette entreprise, pas aux agents en général.
- La frontière de mutation n'est pas négociable. Quiconque exécute un correctif doit endosser un rôle IAM au périmètre étroit dans le compte concerné, verrouillé par une étape d'approbation interne. Un produit SaaS oblige soit à lui accorder un accès cross-account large, soit à greffer après coup son propre flux d'approbation sur le vôtre. Posséder la plateforme veut dire que le verrou d'approbation est natif dès le premier jour, pas intégré plus tard.
- Trente comptes de savoir tribal vivent dans des fils Slack et dans la tête des ingénieurs, pas dans un format que le pipeline d'ingestion d'un fournisseur comprend. Une Bedrock Knowledge Base construite sur le corpus de runbooks existant, avec l'équipe qui contrôle directement le découpage et la qualité de la récupération, est plus praticable que d'exporter ce savoir vers un tiers en espérant que sa récupération soit assez bonne.
- L'entreprise opère déjà AWS à cette échelle. Le Terraform, la CI, la rotation d'astreinte, la structure des comptes, tout cela existe déjà aujourd'hui. Le coût marginal de construire sur des briques natives AWS est plus faible que celui d'une deuxième relation fournisseur, d'une deuxième ligne de facturation et d'une deuxième revue de sécurité.
Le contre-argument est réel : acheter est plus rapide, et la rapidité a de la valeur quand l'astreinte s'accumule chaque semaine. La réponse de l'équipe a été de cadrer étroitement la construction (quatre agents, un seul schéma d'approbation, de l'inférence on-demand pour commencer, voir le calcul de dimensionnement dans une partie ultérieure) plutôt que d'en faire le projet sans fin d'une équipe plateforme. Le code compagnon de toute la série vit sur github.com/flightlesstux/agents-on-call ; c'est ici que commence son docs/architecture.md.
Le choix de la stack : trois façons de faire tourner un agent sur Bedrock
Une fois la décision de construire prise, la question suivante a été sur quelle couche construire. Trois options réelles existaient, et l'arbitrage est loin d'être aussi simple qu'« utiliser la dernière nouveauté » :
| Dimension | Bedrock Agents (classique) | AgentCore + Strands | Construction maison sur l'API Converse |
|---|---|---|---|
| Ce que vous possédez | Groupes d'actions définis dans la console, l'orchestration appartient à AWS | Runtime, identité, mémoire et gateway managés, la boucle d'agent est votre Python | Tout : boucle, retries, mémoire, routage des outils, traçage |
| Maturité à cette date | GA depuis novembre 2023, le plus long historique | GA depuis le 13 octobre 2025, environ sept mois d'usage en production | Aussi mature que votre propre code, pas plus |
| Portabilité des modèles et fournisseurs | Modèles Bedrock uniquement | Bedrock, Anthropic en direct, Ollama, et fournisseurs proxyfiés via LiteLLM | Ce que vous branchez vous-même |
| Dépendance au framework | Élevée : la logique d'orchestration vit dans le format action-group de Bedrock | Faible : Strands est du Python Apache 2.0, le même SDK qu'Amazon utilise en interne pour Q Developer, AWS Glue et VPC Reachability Analyzer | Aucune, mais aucune aide non plus |
| Intégration des outils | Action groups définis par des schémas OpenAPI | AgentCore Gateway transforme des API, des fonctions Lambda et des services existants en outils compatibles MCP ; MCP lui-même est un standard ouvert depuis novembre 2024 | Appel d'outils codé à la main contre l'API Converse |
| Observabilité | Trace de raisonnement intégrée, contrôle limité sur son mode d'exportation | Traces OTEL vers CloudWatch generative AI observability, sur vos propres tableaux de bord | Ce que vous instrumentez vous-même |
| Couverture Terraform | Ressources action-group présentes de longue date | Ressources natives aws_bedrockagentcore_* depuis le 16 octobre 2025, avec de vrais blocs HCL imbriqués plutôt que des cartes d'attributs en forme de JSON | Aucune ressource spécifique au service nécessaire, juste IAM et compute |
| Cas d'usage idéal | Un petit nombre d'agents simples, orchestration personnalisée minimale souhaitée | Plusieurs agents nécessitant un contrôle sur la boucle, et un futur multi-fournisseur | Une orchestration si spécialisée qu'aucun framework ne l'exprime bien |
L'équipe a choisi AgentCore associé à Strands. Les briques managées qu'elle ne voulait pas posséder (isolation des sessions, courtage d'identifiants, gateway cross-account) sont venues avec une couche d'orchestration qu'elle pouvait lire et déboguer, plutôt qu'une couche à rétro-ingénierer depuis une console. AgentCore Runtime, en disponibilité générale, donne à chaque session d'agent une isolation complète et une fenêtre d'exécution de huit heures, avec un support du protocole Agent2Agent si les agents de cette plateforme doivent un jour parler à des agents extérieurs. Le CLI @aws/agentcore, publié le 22 avril 2026, a ajouté un flux create, dev, deploy, invoke, logs et traces qui supporte Strands directement (ainsi que LangGraph, LangChain, Google ADK, OpenAI Agents, ou du sur-mesure), ce qui a compté pour l'intégration de l'équipe : personne n'a eu à apprendre un tout nouvel outil de déploiement en plein milieu du projet.
Bedrock Agents classique est resté sincèrement attractif sur ses propres mérites : deux ans et demi d'historique en production, moins de code maison à posséder, et un modèle mental plus simple quand un action group suffit au cas d'usage. Il a perdu ici parce que quatre agents partageant un schéma superviseur à travers une frontière IAM multi-compte stricte avaient besoin de plus de contrôle sur la boucle que ce que les action groups exposent. La construction maison sur l'API Converse brute a été rejetée pour la raison inverse : écrire un magasin de sessions, un courtier d'identifiants et un pipeline de traçage à partir de zéro, pour quelque chose qu'AWS livre déjà sous forme d'AgentCore Runtime, Memory, Identity et Observability, aurait consommé les deux premiers mois du projet à réinventer de l'infrastructure au lieu d'écrire des agents.
Architecture cible : hub-and-spoke à travers l'organisation
La plateforme est multi-compte, en hub-and-spoke, et délibérément additive. Si elle tombe, l'organisation se dégrade exactement au statu quo : les humains sont alertés comme ils l'ont toujours été. Elle ne se trouve jamais sur le chemin critique des alertes.
graph TD MGMT["management account
org root, SCPs, no workloads"] SEC["security account
org CloudTrail, GuardDuty,
Security Hub delegated admin"] OPS["ops-tooling account
the agent platform"] W1["workload account 1"] W2["workload account 2"] WN["workload account N
~30 total"] MGMT -. SCPs .-> SEC MGMT -. SCPs .-> OPS MGMT -. SCPs .-> W1 MGMT -. SCPs .-> W2 MGMT -. SCPs .-> WN W1 -- alarm events --> OPS W2 -- alarm events --> OPS WN -- alarm events --> OPS OPS -- "assume ops-readonly, read-only tools" --> W1 OPS -- "assume ops-readonly, read-only tools" --> W2 OPS -- "assume ops-readonly, read-only tools" --> WN OPS -. "assume ops-mutate, approved executor only" .-> W1
Chaque compte de workload expose exactement deux rôles à ops-tooling : ops-readonly, endossable par chaque Lambda outil, construit à partir des politiques managées AWS en lecture seule avec des refus explicites empilés par-dessus ; et ops-mutate, endossable par une seule Lambda, celle qui s'exécute après qu'un humain a approuvé une action proposée, restreinte à une liste blanche de documents SSM Automation spécifiques. Aucun agent, aucune autre Lambda, aucun chemin de code hormis ce seul exécuteur post-approbation ne peut jamais endosser ops-mutate. C'est cette séparation, pas une instruction de prompt, qui fait de la lecture seule le comportement par défaut : c'est imposé par IAM, pas obtenu en demandant gentiment à un modèle.
À l'intérieur d'ops-tooling
Zoom sur le compte unique dans lequel vit le reste de cette série :
graph LR
subgraph entry["Entry"]
EB["EventBridge bus
cross-account alarms"]
SLACK["Slack app
API Gateway + verifier Lambda"]
SCHED["EventBridge Scheduler
daily cost sweep"]
end
subgraph agents["Agent layer"]
SUP["supervisor"]
TRI["incident-triage"]
RUN["runbook"]
COST["cost"]
MEM["AgentCore Memory"]
ID["AgentCore Identity"]
end
subgraph models["Model layer"]
BR["Bedrock, cross-region
inference profiles"]
GR["Bedrock Guardrails"]
KB["Knowledge Base
runbook corpus"]
end
subgraph tools["Tool layer"]
GW["AgentCore Gateway"]
T1["cloudwatch-read"]
T2["logs-read"]
T3["cost-read"]
T4["ssm-execute"]
end
subgraph gate["Approval gate"]
SF["Step Functions
waitForTaskToken"]
EXEC["post-approval executor"]
end
subgraph obs["Observability"]
OTEL["OTEL traces to CloudWatch
GenAI observability"]
LOG["invocation logs to S3"]
BUD["Budgets + Cost
Anomaly Detection"]
end
EB --> SUP
SLACK --> SUP
SCHED --> COST
SUP --> TRI
SUP --> RUN
SUP --> COST
TRI --> MEM
RUN --> MEM
COST --> MEM
SUP --> ID
TRI --> BR
RUN --> BR
COST --> BR
BR --> GR
TRI --> KB
RUN --> KB
SUP --> GW
GW --> T1
GW --> T2
GW --> T3
GW --> T4
T4 --> SF
SF -- "context + Slack approval" --> SLACK
SF -- approved --> EXEC
BR --> OTEL
GW --> LOG
COST --> BUD
Quatre agents Strands tournent sur AgentCore Runtime derrière un superviseur : triage d'incidents, exécution de runbooks et optimisation des coûts. AgentCore Memory conserve l'état de session et l'état long terme afin que le superviseur n'ait pas à réexpliquer le contexte à un spécialiste à chaque saut, et AgentCore Identity fait courtier pour les identifiants sortants afin qu'aucun code d'agent ne porte de secret longue durée. Chaque appel de modèle passe par des profils d'inférence cross-region pour la fiabilité et la marge en cas de pic, avec Bedrock Guardrails attaché à chaque invocation et une Knowledge Base sur le corpus de runbooks qui alimente les agents de triage et de runbook. La couche outils est entièrement AgentCore Gateway : des Lambdas à privilège minimal derrière MCP, trois d'entre elles en lecture seule et endossant ops-readonly dans un spoke, l'une d'elles, ssm-execute, le seul outil mutant, et elle ne peut pas atteindre un compte spoke directement. Elle ne peut que remettre une proposition à Step Functions, qui se met en pause sur waitForTaskToken, poste le contexte complet (diagnostic, rayon d'impact, document SSM exact et paramètres) sur Slack, et ne reprend que quand un humain approuve. Chaque saut d'EventBridge à Gateway porte un traçage OTEL vers CloudWatch generative AI observability, les logs d'invocation Bedrock atterrissent dans S3, et Budgets plus Cost Anomaly Detection surveillent les dépenses propres à la plateforme avec des tags d'allocation de coûts par agent.
La lecture seule est la directive première
Chaque agent de cette plateforme peut regarder tout ce qui est pertinent et ne rien changer, à moins qu'un humain n'ait déjà dit oui. C'est la seule phrase à laquelle le reste de cette série doit rester fidèle. Elle se traduit par trois décisions IAM distinctes et peu glorieuses plutôt qu'un mécanisme unique et astucieux : les Lambdas outils endossent un rôle en lecture seule construit à partir de politiques managées AWS avec des refus explicites empilés par-dessus ; le seul outil mutant ne peut rien endosser directement dans un compte spoke ; et l'unique chemin entre « l'agent a proposé un correctif » et « le correctif a tourné » passe par un état d'attente Step Functions que seul un clic humain sur Slack peut relancer.
La lecture seule n'est pas une instruction de prompt qui demande à un modèle d'être prudent. Un modèle à qui on le demande gentiment ne l'est pas toujours. Ici, la lecture seule est une frontière IAM qu'un prompt compromis, un appel d'outil halluciné ou un simple bug ne peuvent pas franchir, parce que les identifiants nécessaires pour la franchir n'existent nulle part où l'agent puisse les atteindre.
À quoi ressemble le résultat visé
Le dernier volet de cette série reviendra sur ces chiffres. Ce sont ceux que l'inventaire de l'astreinte plus haut a posés, rendus mesurables :
- Temps médian entre l'alerte et un résumé Slack enrichi (logs, tableaux de bord, cause probable) sous les 5 minutes, contre les 25 à 35 minutes actuelles de rassemblement manuel.
- Zéro action mutante ne s'exécute sans une approbation humaine enregistrée par Step Functions, vérifiée chaque semaine contre CloudTrail.
- Le retard FinOps mensuel passe d'environ trois semaines à un traitement le jour même, grâce au balayage quotidien des coûts qui fait remonter les anomalies avant la clôture du cycle de facturation suivant.
- L'obsolescence des runbooks (ARN cassés, chemins de console morts) passe d'environ un sur trois à moins d'un sur vingt, détectée en continu plutôt qu'au moment d'un audit annuel.
- Un game day trimestriel désactive entièrement ops-tooling et confirme que les alertes et l'exécution manuelle des runbooks fonctionnent exactement comme avant son existence, sans qu'aucune dépendance silencieuse ne se soit créée.
- Le diagnostic de triage d'incidents correspond à la cause racine effective assez souvent, mesuré contre un seuil numérique que le harnais d'évaluation défini dans une partie ultérieure établira, pour que l'astreinte cesse de le revérifier à la main avant d'agir dessus.
Modes de défaillance à surveiller dès le premier jour
Trois points à surveiller avant que quiconque touche à Terraform, parce que la mise en scène du scénario est le pire endroit pour les découvrir en production. Si un outil de lecture n'arrive pas à atteindre un compte spoke, que ce soit parce qu'une prise de rôle est refusée ou qu'un service est dégradé, l'agent doit le signaler et rendre la main à un humain, pas deviner : un diagnostic faux énoncé avec assurance est pire qu'aucun diagnostic. Si le verrou d'approbation lui-même se bloque, l'état d'attente et la machine à états qui l'entoure ont tous les deux besoin de délais d'expiration explicites, sinon une proposition coincée vieillit en silence au lieu d'échouer bruyamment. Et si ops-tooling tombe entièrement, la plateforme doit se dégrader exactement au processus d'aujourd'hui, ce qui ne tient que si rien en dehors d'ops-tooling ne se met à dépendre silencieusement de son existence.
À lire ensuite
- Partie 2, Les fondations : Terraform avant les tokens, où l'organisation des comptes ci-dessus devient du vrai HCL : socle IAM, accès aux modèles Bedrock, et l'arbitrage entre inférence on-demand, provisionnée et cross-region.
- AWS Multi-party Approval for Organizations sur ercan.cloud, le même schéma « verrouiller l'action risquée derrière un quorum d'humains », vu côté AWS Organizations brut plutôt que côté agent.
Les deux diagrammes ci-dessus, ainsi que l'organisation des comptes et de l'IAM qu'ils décrivent, vivent aussi en Markdown dans le dépôt compagnon à github.com/flightlesstux/agents-on-call, aux côtés du Terraform et du Python que cette série construit partie par partie. Pour le volet base de données et infrastructure de faire tourner ce genre de plateforme à grande échelle, les notes de terrain sont sur ercan.cloud, et le hub se trouve sur ercanermis.com.
Plus d'Ercan
Deux autres sites, même auteur, terrain différent.
Cloud, AWS, EKS, Terraform, plateforme.
Notes de terrain de systèmes de production. EKS, IAM, Terraform à l'échelle organisation, observabilité, optimisation des coûts.
Visiter ercan.cloud →Le hub. À propos, conseil, contact.
Hub personnel pour les deux pistes d'écriture. Qui je suis, comment fonctionne le conseil, comment me joindre.
Visiter ercanermis.com →