EventBridge es un servicio serverless que permite crear aplicaciones basadas en eventos funcionando como un bus. Se pueden enviar eventos a EventBridge desde distintas fuentes internas (otros servicios de AWS) como externas (proveedores de SaaS).
Para más detalles en las referencias dejo en los links de videos y artículos del funcionamiento, los límites y arquitectura. En este artículo vamos a centrarnos en estudiar una forma de utilizarlo como un "gateway" de eventos.
Pensemos el siguiente escenario, necesitamos un EndPoint donde poder dejar un mensaje y asegurarnos que se va a entregar al menos una vez en dos destinos distintos. Los destinos pueden ser el destino del mensaje original y un detector de fraude. Ahora imaginemos que por un nuevo requerimiento, ese mensaje también tiene que llegar a un servicio legacy o un cliente externo que solo tiene integración por API/REST.
Es aquí donde el ejercicio que propongo tiene sentido, es posible configurar EventBridge para que su origen sea un EndPoint / ApiGateway y uno de sus destinos también sea un EndPoint. En principio, esto es útil para conectar aplicaciones ya existentes que no fueron pensadas como aplicaciones dirigidas por eventos.
El diagrama arriba muestra la arquitectura descrita:
ApiGateway con el EndPoint donde dejaremos los mensajes
Evento(Definido en el bus) que conecta el ApiGateway con el EventBridge
EventBridge
Reglas aplicadas a los eventos
Lambda que se despierta por un evento / regla
SNS que se notifica con un evento / regla a otro servicio
La API / REST externo que queremos conectar
Centrémonos en dos puntos importantes: como conectar el ApiGateway (elemento 1 en el diagrama), con el EventBridge, para esto usaremos AWS Sam para definir la infraestructura, y como conectar el EventBridge con el EndPoint legacy (elemento 7 en la figura).
En este repositorio ( creado para esta demo: https://github.com/olcortesb/sam-eventbridge-api/ hay tres carpetas, dos de las cuales son los puntos sobre los que queremos enfocarnos la primera carpeta a estudiar api-to-eb
dentro de esta carpeta tenemos un archivo template.yaml
con la estructura.
Dentro de ese archivo tenemos varias etapas bien definidas, enfoquemos en el punto donde se conecta el ApiGateway definido con el EventBridge
# Resource creates an integration for an API
# https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-apigatewayv2-integration.html
HttpApiIntegrationEventBridge:
DependsOn:
- HttpApiIntegrationEventBridgeRole
Type: AWS::ApiGatewayV2::Integration
Properties:
ApiId:
Ref: HttpApi
IntegrationType: AWS_PROXY
IntegrationSubtype: EventBridge-PutEvents
CredentialsArn:
Fn::GetAtt: [HttpApiIntegrationEventBridgeRole, Arn]
RequestParameters:
# Replace `mycompany` with your needs
Source: mycompany
DetailType: mydetailtype
Detail: $request.body
EventBusName:
Fn::GetAtt: [ApplicationEventBus, Arn]
PayloadFormatVersion: "1.0"
TimeoutInMillis: 10000
Este bloque de definición tiene varias dependencias y requiere definiciones adicionales, pero es el punto central de este archivo de definiciones de infraestructura. Particularmente el type AWS::ApiGatewayV2::Integration
y en segunda instancia el IntegrationSubtype: EventBridge-PutEvents
Ahora revisemos la segunda parte, la carpeta, eb-to-api
en esta carpeta está la configuración de como enviar los eventos de un EventBridge a una API tomado del ejemplo de Marcia Villalba (https://github.com/mavi888/sam-eventbridge/blob/api-destinations/blueDragon/template.yml#L10)
Dentro de esta carpeta está el archivo de definición, template.yml
este archivo al igual que el anterior contiene las definiciones de la infraestructura, pero a diferencia del anterior, este no crea el bus de eventos, sino que lo reutiliza y agrega un destino que es la API / REST que queremos integrar, el punto central de este archivo es el siguiente código
BlueDragonConnection:
Type: AWS::Events::Connection
Properties:
AuthorizationType: API_KEY
Description: 'Connection with an API key'
AuthParameters:
ApiKeyAuthParameters:
ApiKeyName: ApiKeyName
ApiKeyValue: BlueDragonApiKeyValue
BlueDragonApiDestination:
Type: AWS::Events::ApiDestination
Properties:
Name: 'BlueDragonApiDestination'
ConnectionArn: !GetAtt BlueDragonConnection.Arn
InvocationEndpoint: !Ref BlueDragonURL
HttpMethod: POST
InvocationRateLimitPerSecond: 10
BlueDragonEventRule:
Type: AWS::Events::Rule
Properties:
EventBusName: youreventname-dev
Description: "EventRule"
EventPattern:
source:
- "mycompany"
State: "ENABLED"
Targets:
- Arn: !GetAtt BlueDragonApiDestination.Arn
RoleArn: !GetAtt EventBridgeTargetRole.Arn
Id: "BlueDragonApiDestination"
En ese orden el
BlueDragonConections
: Define una nueva conexiónBlueDragonDestinations
: El destino o EndoPointBlueDragonEventRule
: Conecta el destino con el bus creado anteriormente
De esta forma tenemos configurada de una Api a otra Api el delivery de un mensaje con las características que ofrece EventBridge, como siempre no es una solución infalible y no aplica para todos los casos. Pero en una circunstancia donde tenemos que anexar una aplicación existente, validar un concepto y probar una nueva integración, resulta muy útil que con solo dos archivos (.yaml
) definiendo la infraestructura sin lógica de negocio, realizar esta comunicación a través de un servicio como EventBridge.
Cualquier comentario, recomendación, sugerencia en este post o en el repositorio que dejo en las referencias
¡Saludos!
Referencias
Repositorio con el código comentado en este post: https://github.com/olcortesb/sam-eventbridge-api
EventBridge: https://docs.aws.amazon.com/eventbridge/latest/userguide/eb-tutorial-get-started.html
Introducción a arquitecturas orientadas a eventos y Amazon EventBridge : https://www.youtube.com/watch?v=TkU1RS5Fw1o Marcia Villalba
Repositorio código de donde extraje el template de:
eb-to-api
https://github.com/mavi888/sam-eventbridge/blob/api-destinations/blueDragon/template.yml#L10 créditos Marcia Villalba