Accueil/Compétences/AWS EventBridge
Logo AWS EventBridge

AWS EventBridge

Service de bus d'événements sans serveur permettant de créer des architectures pilotées par les événements et d'interconnecter vos applications avec des données provenant de diverses sources.

Pour les non-initiés

Qu'est-ce que AWS EventBridge ?

Imaginez un grand centre de messagerie central qui reçoit des notifications de différents services, les trie selon des règles précises, puis les envoie aux bonnes destinations. C'est exactement ce que fait AWS EventBridge.

En termes simples, EventBridge est comme un facteur intelligent pour le monde numérique. Il reçoit des "événements" (messages qui signalent qu'une action s'est produite) de diverses sources, puis les achemine vers les services qui doivent réagir à ces événements.

À quoi sert EventBridge ?

Connexion d'applications

Il permet de connecter différentes applications ou services pour qu'ils puissent communiquer entre eux sans avoir à créer des intégrations complexes.

Automatisation

Il déclenche automatiquement des actions en réponse à des événements spécifiques, comme l'envoi d'une confirmation quand un client passe une commande.

Un exemple concret : lorsqu'un nouvel utilisateur s'inscrit sur votre site web (événement), EventBridge peut déclencher l'envoi d'un email de bienvenue, créer un compte dans votre base de données, et informer votre équipe commerciale - le tout automatiquement et sans que ces différents systèmes aient besoin d'être directement connectés entre eux.

C'est comme si, au lieu d'avoir des personnes qui se transmettent des informations en chaîne, vous aviez un tableau d'affichage central où tous peuvent voir les annonces importantes et agir en conséquence.

Pour les développeurs

Fonctionnement technique

AWS EventBridge est un service de bus d'événements sans serveur qui facilite la construction d'architectures pilotées par les événements (event-driven). Il permet d'ingérer, filtrer, transformer et acheminer des événements entre différents composants d'applications.

Concepts fondamentaux

Événements

Un événement est un enregistrement JSON qui représente un changement d'état ou une notification. Les événements contiennent des métadonnées et des informations détaillées sur ce qui s'est produit.

  • Structure standard : chaque événement contient des champs communs (version, id, source, type, etc.)
  • Taille maximale : 256 KB par événement
  • Sources : services AWS, applications SaaS intégrées, applications personnalisées
  • Format des champs importants :
    • source : origine de l'événement (ex: "aws.s3", "com.company.app")
    • detail-type : nature de l'événement (ex: "EC2 Instance State Change")
    • detail : objet JSON avec les informations spécifiques de l'événement

Bus d'événements

Un bus d'événements est un routeur qui reçoit des événements et les dirige vers les cibles associées en fonction des règles définies.

  • Bus par défaut : chaque compte AWS a un bus d'événements par défaut
  • Bus personnalisés : vous pouvez créer jusqu'à 100 bus personnalisés par compte
  • Bus partenaires : reçoivent des événements de services SaaS partenaires
  • Partage entre comptes : un bus peut être partagé avec d'autres comptes AWS
  • Archives : les événements peuvent être archivés pour relecture ultérieure

Règles

Les règles définissent quels événements sont capturés par le bus et vers quelles cibles ils sont envoyés. Elles se composent de deux parties principales.

  • Pattern d'événement : filtre qui détermine quels événements correspondent à la règle
  • Cibles : services ou ressources qui seront invoqués lorsqu'un événement correspond
  • Types de règles :
    • Règles basées sur les événements : déclenchées par des événements spécifiques
    • Règles planifiées : déclenchées selon un horaire défini (cron ou rate)
  • Transformation d'entrée : possibilité de reformater l'événement avant de l'envoyer à la cible

Patterns d'événements

Les patterns d'événements sont des structures JSON qui décrivent les événements à capturer. Ils peuvent correspondre à des valeurs exactes ou utiliser des filtres plus avancés.

  • Correspondance exacte : correspond si la valeur est exactement celle spécifiée
  • Filtres numériques : comparaisons numériques (>, <, =, etc.)
  • Préfixes/suffixes : correspondance sur le début ou la fin d'une chaîne
  • Anything-but : correspond à tout sauf les valeurs spécifiées
  • Exists : vérifie si un champ existe ou non
  • Correspondance avec wildcard : utilisation de * pour les correspondances partielles

Cibles

Les cibles sont les destinations où EventBridge envoie les événements correspondant aux règles. De nombreux services AWS peuvent être configurés comme cibles.

  • Services de calcul : Icône AWS LambdaAWS Lambda, Icône Step FunctionsStep Functions, ECS Task, etc.
  • Services de messagerie : Icône SQSSQS, Icône SNSSNS, Kinesis, etc.
  • Autres bus d'événements : redirection vers d'autres bus
  • API Gateway : invocation d'Icône APIsAPIs
  • Options de traitement :
    • File d'attente de lettres mortes (DLQ) pour gérer les échecs
    • Politiques de nouvelle tentative configurables
    • Transformation d'entrée pour reformater les événements

Implémentation technique

Voyons maintenant comment mettre en œuvre EventBridge dans différents scénarios courants.

1. Création d'une règle pour traiter les commandes

Comment configurer une règle EventBridge pour capturer et traiter des événements de commande :

Création d'une règle EventBridge
// Création d'une règle EventBridge avec SDK AWS v3 const { EventBridgeClient, PutRuleCommand, PutTargetsCommand } = require("@aws-sdk/client-eventbridge"); const client = new EventBridgeClient({ region: "eu-west-1" }); async function createOrderProcessingRule(ruleName, lambdaFunctionArn) { try { // 1. Création de la règle avec un pattern d'événement spécifique const ruleCommand = new PutRuleCommand({ Name: ruleName, Description: "Capture les événements de création de commande", EventPattern: JSON.stringify({ "source": ["com.myecommerce.orders"], "detail-type": ["OrderCreated"], "detail": { "status": ["PENDING"], "amount": [{ "numeric": [">", 100.0] }] } }), State: "ENABLED" }); const ruleResponse = await client.send(ruleCommand); console.log("Règle créée avec succès:", ruleResponse); // 2. Définir la cible Lambda pour la règle const targetCommand = new PutTargetsCommand({ Rule: ruleName, Targets: [ { Id: "ProcessOrderTarget", Arn: lambdaFunctionArn, // Transformation d'entrée optionnelle pour adapter le format de l'événement InputTransformer: { InputPathsMap: { "orderId": "$.detail.orderId", "amount": "$.detail.amount", "customerId": "$.detail.customerId" }, InputTemplate: `{ "order": { "id": <orderId>, "totalAmount": <amount>, "customer": <customerId> }, "processType": "PRIORITY", "timestamp": "<aws.events.event-time>" }` } } ] }); const targetResponse = await client.send(targetCommand); console.log("Cible ajoutée avec succès:", targetResponse); return { ruleResponse, targetResponse }; } catch (error) { console.error("Erreur lors de la création de la règle EventBridge:", error); throw error; } }

2. Publication d'un événement personnalisé

Comment publier un événement dans le bus d'événements :

Publication d'un événement
// Publication d'un événement dans EventBridge avec SDK AWS v3 const { EventBridgeClient, PutEventsCommand } = require("@aws-sdk/client-eventbridge"); const client = new EventBridgeClient({ region: "eu-west-1" }); async function publishOrderCreatedEvent(orderId, customerId, amount, items) { try { const command = new PutEventsCommand({ Entries: [ { // Bus d'événements cible (par défaut: default) EventBusName: "default", // Source unique pour faciliter le filtrage Source: "com.myecommerce.orders", // Type de l'événement DetailType: "OrderCreated", // Données détaillées de l'événement (doit être une chaîne JSON) Detail: JSON.stringify({ orderId: orderId, customerId: customerId, orderDate: new Date().toISOString(), status: "PENDING", amount: amount, items: items, metadata: { channel: "web", ipAddress: "198.51.100.123" } }), // Ressource liée à l'événement (facultatif) Resources: [ `arn:aws:ec2:eu-west-1:123456789012:instance/i-1234567890abcdef0` ], // Heure de l'événement (facultatif, par défaut: heure actuelle) Time: new Date() } ] }); const response = await client.send(command); console.log("Événement publié avec succès:", response); // Vérifier si des entrées ont échoué if (response.FailedEntryCount > 0) { console.error("Certaines entrées ont échoué:", response.Entries); } return response; } catch (error) { console.error("Erreur lors de la publication de l'événement:", error); throw error; } } // Exemple d'utilisation de la fonction const orderId = "ORD-" + Math.floor(Math.random() * 1000000); const customerId = "CUST-12345"; const amount = 249.99; const items = [ { productId: "PROD-001", name: "Écouteurs sans fil", quantity: 1, unitPrice: 199.99 }, { productId: "PROD-002", name: "Étui de protection", quantity: 1, unitPrice: 50.00 } ]; publishOrderCreatedEvent(orderId, customerId, amount, items);

3. Configuration d'événements planifiés

Comment créer une règle pour déclencher des actions à intervalles réguliers :

Création d'un événement planifié
// Création d'un événement programmé (anciennement CloudWatch Events) avec SDK AWS v3 const { EventBridgeClient, PutRuleCommand, PutTargetsCommand } = require("@aws-sdk/client-eventbridge"); const client = new EventBridgeClient({ region: "eu-west-1" }); async function createScheduledReportGenerator(ruleName, lambdaFunctionArn) { try { // 1. Création de la règle avec une expression cron // Cette règle s'exécutera tous les lundis à 9h du matin (UTC) const ruleCommand = new PutRuleCommand({ Name: ruleName, Description: "Génère un rapport hebdomadaire tous les lundis à 9h", // Formats supportés : cron, rate, ou at ScheduleExpression: "cron(0 9 ? * MON *)", State: "ENABLED" }); const ruleResponse = await client.send(ruleCommand); console.log("Règle programmée créée avec succès:", ruleResponse); // 2. Définir la cible Lambda pour la règle programmée const targetCommand = new PutTargetsCommand({ Rule: ruleName, Targets: [ { Id: "WeeklyReportTarget", Arn: lambdaFunctionArn, // Entrée constante pour la Lambda Input: JSON.stringify({ reportType: "WEEKLY_SALES", format: "PDF", recipients: [ "sales-team@example.com", "management@example.com" ], includeGraphics: true }) } ] }); const targetResponse = await client.send(targetCommand); console.log("Cible ajoutée à la règle programmée:", targetResponse); return { ruleResponse, targetResponse }; } catch (error) { console.error("Erreur lors de la création de la règle programmée:", error); throw error; } } // Formats courants pour ScheduleExpression : // 1. Cron: "cron(0 12 * * ? *)" - Tous les jours à midi UTC // 2. Rate: "rate(1 hour)" - Toutes les heures // 3. Rate: "rate(5 minutes)" - Toutes les 5 minutes // 4. Rate: "rate(1 day)" - Tous les jours

4. Création et utilisation d'un bus d'événements personnalisé

Comment configurer un bus d'événements dédié pour un domaine spécifique :

Configuration d'un bus d'événements personnalisé
// Création d'un bus d'événements personnalisé avec SDK AWS v3 const { EventBridgeClient, CreateEventBusCommand, PutRuleCommand, PutTargetsCommand } = require("@aws-sdk/client-eventbridge"); const client = new EventBridgeClient({ region: "eu-west-1" }); async function createCustomEventBusWithRules(eventBusName, ruleName, snsTopicArn) { try { // 1. Création d'un bus d'événements personnalisé const busCommand = new CreateEventBusCommand({ Name: eventBusName, Tags: [ { Key: "Environment", Value: "Production" }, { Key: "Department", Value: "Engineering" } ] }); const busResponse = await client.send(busCommand); console.log("Bus d'événements personnalisé créé avec succès:", busResponse); // 2. Création d'une règle sur ce bus personnalisé const ruleCommand = new PutRuleCommand({ Name: ruleName, Description: "Capture les événements de sécurité critiques", EventPattern: JSON.stringify({ "source": ["com.mycompany.security"], "detail-type": ["SecurityAlert", "ComplianceViolation"], "detail": { "severity": ["CRITICAL", "HIGH"] } }), // Spécifier le bus d'événements personnalisé EventBusName: eventBusName, State: "ENABLED" }); const ruleResponse = await client.send(ruleCommand); console.log("Règle créée sur le bus personnalisé:", ruleResponse); // 3. Définir une cible SNS pour la règle (notification par email) const targetCommand = new PutTargetsCommand({ Rule: ruleName, EventBusName: eventBusName, // Important: spécifier le bus personnalisé Targets: [ { Id: "SecurityAlertNotificationTarget", Arn: snsTopicArn, // Transformation d'entrée pour formater le message de notification InputTransformer: { InputPathsMap: { "alertType": "$.detail-type", "severity": "$.detail.severity", "description": "$.detail.description", "resourceId": "$.detail.resourceId", "timestamp": "$.time" }, InputTemplate: `{ "Subject": "Security Alert: <severity> <alertType>", "Message": "A <severity> security alert was detected:\n\nResource: <resourceId>\nTime: <timestamp>\nDescription: <description>\n\nPlease investigate immediately." }` } } ] }); const targetResponse = await client.send(targetCommand); console.log("Cible ajoutée à la règle sur le bus personnalisé:", targetResponse); // Retourner les ARNs et les identifiants pour référence return { eventBusArn: `arn:aws:events:${client.config.region}:${busResponse.AccountId}:event-bus/${eventBusName}`, ruleArn: ruleResponse.RuleArn, responses: { busResponse, ruleResponse, targetResponse } }; } catch (error) { console.error("Erreur lors de la configuration du bus d'événements personnalisé:", error); throw error; } }

5. Architecture événementielle complète avec AWS CDK

Comment définir une infrastructure complète pilotée par les événements avec AWS CDK :

Architecture EventBridge avec AWS CDK
// Configuration complète d'EventBridge avec AWS CDK (TypeScript) import * as cdk from 'aws-cdk-lib'; import * as events from 'aws-cdk-lib/aws-events'; import * as targets from 'aws-cdk-lib/aws-events-targets'; import * as lambda from 'aws-cdk-lib/aws-lambda'; import * as sns from 'aws-cdk-lib/aws-sns'; import * as sqs from 'aws-cdk-lib/aws-sqs'; import * as subscriptions from 'aws-cdk-lib/aws-sns-subscriptions'; import { Construct } from 'constructs'; export class EventDrivenInfrastructureStack extends cdk.Stack { constructor(scope: Construct, id: string, props?: cdk.StackProps) { super(scope, id, props); // Création d'un bus d'événements personnalisé const applicationEventBus = new events.EventBus(this, 'ApplicationEventBus', { eventBusName: 'application-events' }); // Configuration d'une politique de rétention d'événements new events.CfnEventBusPolicy(this, 'EventBusPolicy', { statementId: 'AllowAccountEvents', eventBusName: applicationEventBus.eventBusName, statement: { Effect: 'Allow', Principal: { AWS: this.account }, Action: 'events:PutEvents', Resource: applicationEventBus.eventBusArn } }); // Création d'une archive pour les événements new events.CfnArchive(this, 'EventArchive', { sourceArn: applicationEventBus.eventBusArn, description: 'Archive for all application events', eventPattern: { // Archiver tous les événements account: [this.account] }, retentionDays: 30, // Conserver les événements pendant 30 jours archiveName: 'application-events-archive' }); // Création de Lambda pour traiter différents types d'événements const orderProcessorFunction = new lambda.Function(this, 'OrderProcessorFunction', { runtime: lambda.Runtime.NODEJS_16_X, handler: 'index.handler', code: lambda.Code.fromAsset('lambda/order-processor'), environment: { EVENT_BUS_NAME: applicationEventBus.eventBusName } }); const inventoryUpdateFunction = new lambda.Function(this, 'InventoryUpdateFunction', { runtime: lambda.Runtime.NODEJS_16_X, handler: 'index.handler', code: lambda.Code.fromAsset('lambda/inventory-update') }); const notificationFunction = new lambda.Function(this, 'NotificationFunction', { runtime: lambda.Runtime.NODEJS_16_X, handler: 'index.handler', code: lambda.Code.fromAsset('lambda/notification-service') }); // Création d'une file d'attente SQS pour le traitement asynchrone const orderProcessingQueue = new sqs.Queue(this, 'OrderProcessingQueue', { visibilityTimeout: cdk.Duration.seconds(300), retentionPeriod: cdk.Duration.days(14) }); // Création d'un topic SNS pour les notifications const notificationTopic = new sns.Topic(this, 'NotificationTopic', { displayName: 'Application Notifications' }); // Ajout d'un abonnement email au topic SNS notificationTopic.addSubscription(new subscriptions.EmailSubscription('admin@example.com')); // Règle 1: Nouvelle commande créée (source custom) const orderCreatedRule = new events.Rule(this, 'OrderCreatedRule', { eventBus: applicationEventBus, description: 'Capture order creation events', eventPattern: { source: ['com.mycompany.orders'], detailType: ['OrderCreated'], detail: { status: ['PENDING'] } } }); // Ajouter plusieurs cibles à cette règle orderCreatedRule.addTarget(new targets.LambdaFunction(orderProcessorFunction, { deadLetterQueue: orderProcessingQueue, // DLQ pour les échecs de traitement maxEventAge: cdk.Duration.hours(2), retryAttempts: 2 })); orderCreatedRule.addTarget(new targets.SqsQueue(orderProcessingQueue, { // Transformation d'entrée pour adapter le format des événements à la cible message: events.RuleTargetInput.fromObject({ orderId: events.EventField.fromPath('$.detail.orderId'), operation: 'PROCESS_NEW_ORDER', timestamp: events.EventField.fromPath('$.time') }) })); // Règle 2: Événement programmé pour nettoyage quotidien const scheduledCleanupRule = new events.Rule(this, 'ScheduledCleanupRule', { schedule: events.Schedule.cron({ minute: '0', hour: '3' }), // 3 AM tous les jours description: 'Daily cleanup task' }); scheduledCleanupRule.addTarget(new targets.LambdaFunction( new lambda.Function(this, 'CleanupFunction', { runtime: lambda.Runtime.NODEJS_16_X, handler: 'index.handler', code: lambda.Code.fromAsset('lambda/cleanup') }) )); // Règle 3: Mise à jour d'inventaire conditionnelle const inventoryUpdateRule = new events.Rule(this, 'InventoryUpdateRule', { eventBus: applicationEventBus, description: 'Detect low inventory situations', eventPattern: { source: ['com.mycompany.inventory'], detailType: ['InventoryUpdate'], detail: { quantity: [{ numeric: ['<', 10] }] // Seuil de stock bas } } }); inventoryUpdateRule.addTarget(new targets.LambdaFunction(inventoryUpdateFunction)); inventoryUpdateRule.addTarget(new targets.SnsTopic(notificationTopic, { message: events.RuleTargetInput.fromText( 'Low inventory alert: Product $' + events.EventField.fromPath('$.detail.productId') + ' is low with only $' + events.EventField.fromPath('$.detail.quantity') + ' units remaining.' ) })); // Règle 4: Traitement spécifique à une région if (this.region === 'eu-west-1') { const europeanComplianceRule = new events.Rule(this, 'EuropeanComplianceRule', { eventBus: applicationEventBus, description: 'Handle European-specific compliance events', eventPattern: { source: ['com.mycompany.compliance'], detailType: ['GDPRRequest', 'DataRetention'], region: ['eu-west-1', 'eu-central-1'] } }); europeanComplianceRule.addTarget(new targets.LambdaFunction( new lambda.Function(this, 'GDPRProcessingFunction', { runtime: lambda.Runtime.NODEJS_16_X, handler: 'index.handler', code: lambda.Code.fromAsset('lambda/gdpr-processor') }) )); } // Création d'un pattern de transformation d'événements const orderTransformer = events.EventField.fromObject({ orderId: events.EventField.fromPath('$.detail.orderId'), status: events.EventField.fromPath('$.detail.status'), transformedTime: events.EventField.time() }); // Autoriser la Lambda à publier sur le bus d'événements (pour chaîner les événements) applicationEventBus.grantPutEventsTo(orderProcessorFunction); // Sorties pour faciliter l'intégration avec d'autres systèmes new cdk.CfnOutput(this, 'ApplicationEventBusName', { value: applicationEventBus.eventBusName }); new cdk.CfnOutput(this, 'ApplicationEventBusArn', { value: applicationEventBus.eventBusArn }); new cdk.CfnOutput(this, 'OrderProcessingQueueUrl', { value: orderProcessingQueue.queueUrl }); new cdk.CfnOutput(this, 'NotificationTopicArn', { value: notificationTopic.topicArn }); } }

Intégrations clés

EventBridge s'intègre nativement avec de nombreux services AWS et partenaires externes :

  • Services AWS : plus de 90 services AWS envoient des événements à EventBridge
  • Intégrations SaaS : plus de 40 partenaires SaaS comme Zendesk, DataDog, Auth0, etc.
  • API Destinations : permet d'invoquer des API HTTP/HTTPS externes
  • Amazon EventBridge Pipes : connexion point-à-point entre sources et cibles avec transformation
  • Icône AWS LambdaAWS Lambda : exécution de code sans serveur en réponse à des événements
  • Amazon Icône SQSSQS/Icône SNSSNS : envoi d'événements vers des files d'attente ou des sujets de notification
  • Icône AWS Step FunctionsAWS Step Functions : démarrage de workflows complexes

Bonnes pratiques

  • Structure des événements : standardisez la structure de vos événements personnalisés
  • Bus d'événements multiples : utilisez des bus séparés pour différents domaines ou environnements
  • Dead Letter Queues : configurez des DLQ pour capturer les événements non traités
  • Versionnement : incluez des informations de version dans vos événements
  • Politique de permissions : utilisez le principe du moindre privilège pour l'accès aux bus
  • Monitoring : créez des alarmes CloudWatch pour surveiller les événements non traités
  • Pagination : pour les événements volumineux (>256KB), divisez-les ou utilisez des références
  • Archive : activez l'archivage pour rejouer les événements si nécessaire
Applications concrètes

Cas d'usage

Architecture de microservices découplée

EventBridge permet de créer des microservices qui communiquent de manière asynchrone sans dépendances directes. Chaque service peut publier des événements lorsque son état change, et d'autres services peuvent réagir à ces événements sans connaître l'émetteur. Cette approche améliore la résilience, la scalabilité et facilite l'évolution indépendante des services.

Intégration d'applications SaaS

EventBridge facilite l'intégration avec des services SaaS tiers comme Zendesk, Datadog ou Auth0. Par exemple, vous pouvez automatiquement créer un ticket dans Zendesk lorsqu'une erreur critique est détectée dans votre application, ou désactiver les accès utilisateurs dans vos systèmes internes lorsqu'un compte est supprimé dans Auth0.

Automatisation des tâches planifiées

Les règles planifiées d'EventBridge remplacent avantageusement les tâches cron traditionnelles pour l'automatisation périodique. Vous pouvez programmer des sauvegardes quotidiennes, des rapports hebdomadaires, des nettoyages de données mensuels, ou des vérifications de conformité trimestrielles, le tout avec une haute disponibilité et sans serveur à gérer.

Surveillance et alertes

EventBridge peut être utilisé pour créer des systèmes de surveillance sophistiqués qui réagissent à des événements spécifiques. Par exemple, détection de comportements suspects dans les journaux de sécurité, alertes en cas de pics de trafic anormaux, ou notifications lorsque des métriques dépassent certains seuils, avec différentes voies d'escalade selon la gravité.

Exemples d'architectures avancées

Système de commande e-commerce multirégional

Une architecture qui utilise des bus d'événements dans plusieurs régions AWS pour traiter les commandes au plus proche des clients, tout en maintenant une vue globale cohérente. Les événements de commande sont capturés localement, traités, puis répliqués vers un bus central pour la consolidation et le reporting.

Composants clés : EventBridge multi-région, DynamoDB Global Tables, Lambda, Step Functions pour orchestration, SNS pour notifications.

Pipeline d'analyse de données en temps réel

Un système qui capture les événements d'activité utilisateur, les enrichit via diverses transformations, puis les achemine vers différentes destinations d'analyse. EventBridge orchestre le flux de données et déclenche différents traitements selon le type d'événement et les attributs utilisateur.

Composants clés : EventBridge, Kinesis Data Streams pour les volumes élevés, Lambda pour transformation, Firehose pour livraison, S3 pour stockage, Athena pour requêtes.

Système de gestion de contenu multi-tenant

Une architecture SaaS qui utilise des bus d'événements personnalisés pour isoler les événements de chaque client, tout en permettant un traitement unifié. Cette approche maintient l'isolation des données tout en réutilisant la logique métier commune.

Composants clés : Bus d'événements par client, Lambda pour traitement, DynamoDB avec partitionnement par tenant, mécanismes de routage conditionnels.