Following the path of Architecture as Code
Modern Cloud Applications built with Enterprise-Integration-Patterns
Enterprise Integration Pattern | AWS Service Implementation |
---|---|
A Message Bus performs as a Middleware between applications that enable them to work together using messaging. | Amazon EventBridge’s event bus serves as the foundation of our integration. It provides a central channel for routing events between producers and consumers. |
A Message Filter eliminates undesired messages from a channel based on a set of criteria. | EventBridge Rules allow us to selectively route events based on specific criteria, ensuring that only relevant events reach downstream processing components. |
Content-Enricher accesses external data sources to augment a message with missing information. | An AWS Lambda function acts as a Content-Enricher. It processes events, fetches additional details, and appends this data to the original event. |
A Recipient List inspects incoming messages, determines the list of recipients, and forwards messages to all channels associated with the recipients in the list. | EventBridge Rules establish a Recipient List to route events to a defined set of targets, directing them to appropriate downstream services. |
- Amazon Transcribe emits events about Transcription job state changes onto the default EventBridge event bus, acting as a Message Bus pattern implementation.
- An EventBridge Rule filters relevant events from Amazon Transcribe and routes them to an AWS Lambda function, representing a sequence of a Message Filter and a Recipient List pattern.
- The AWS Lambda function serves as the Content-Enricher pattern. It receives the initial event from Amazon Transcribe, fetches additional details about the Transcription job, and appends these details to the event.
- The enriched event is sent to a custom EventBridge bus via a Lambda Destinations channel.

Flow
interface promotes a declarative approach to codify integrations. Consumers specify the desired interactions between components using a fluent syntax (withFilter()
, withEnricher()
, etc.). The flow for our example will then look like the following snippet. It seamlessly ties together the messaging concepts from our solution design using an expressive interface. I wanted to provide a clean interface for my integration logic while hiding service-specific implementation details and promoting a pattern-focused approach.Flow
must adhere to service-specific implementation details. The EventBridge-specific implementation encapsulates the complexity of configuring EventBridge rules including filters and targets, and integrating the Content-Enricher Lambda function. This allows a user to focus on the design of a flow itself rather than cracking service-specific implementation details.MessageBus
construct is another pattern implementation, abstracting event bus creation and configuration. It further provides the flow(id: string)
method, which acts as a factory method for defining a new integration flow specific to Amazon EventBridge.MessageBus
construct.Flow
implementation as you see in the following snippets as part of our Flow
implementation. A Flow
that contains a content-enricher implemented as an AWS Lambda function, creates an EventInvokeConfig
Lambda Destination implementation. If the flow does not contain a content-enricher, it adds the event target to the underlying rule implementation.withEventTarget
restricts us from using anything else than an Amazon EventBridge event bus as a target. Multiple other valid targets like AWS Step Functions, Amazon SQS, or Amazon SNS can be modeled at a later stage supporting more integration use cases.- Ubiquitous Language: EIPs provide a common vocabulary to describe integrations, bridging communication gaps, and promoting collaboration.
- Finding good abstraction is hard: Only thought-through L3 constructs raise the level of abstraction when defining cloud architectures. They embody patterns, encapsulate AWS-specific details, and promote a declarative, configuration-focused approach. Finding the right level of abstraction when defining infrastructure with code is not an easy task. Adopting AaC requires fluency in programming, infrastructure as well as integration concepts. That is a learning curve of its own.
- AWS CDK for the win: The expressiveness of the AWS CDK and the fact that you can model your infrastructure as real code opens the world for Architecture as Code. You can switch perspectives by communicating intentions instead of service selections.