AWS serverless ecosystem consists of a lot of tools and services. Although there are couple of guides on the implementation details of individual services, there is not enough material highlighting the principles involved in choosing an AWS service. A wrong choice can be a costly mistake when our serverless system hits scale. This article is more of a survey of serverless fundamentals in AWS. It will briefly touch upon composition paradigms and the services which can be used for any of these paradigms. Common use cases of AWS services and their comparison will also be discussed.
Before we proceed to architect a serverless system, we must understand what serverless systems offer and what are the common use cases for serverless systems.
Serverless is no silver bullet and it promises certain things which makes it useful for certain scenarios.
Considering the promises serverless do, there are some use cases for which serverless makes more sense.
Serverless architecture is best used to perform short-lived tasks and manage workloads that experience infrequent or unpredictable traffic. Some of the use cases are:
Now we understand the benefits and popular use cases for serverless, we will jump to the fundamentals of serverless systems.
Whenever we are designing serverless or microservices, we must define the events in our system, bounded context of our APIs and the composition paradigm we will be choosing for our system.
It is better to divide large business operations to small bounded contexts. This enables us to clearly define the responsibility of any given part of our system. We can define this process to three steps:
This infoq article has a good guide on bounded contexts.
A bounded context can be any part of our system clearly depicting the flow. One example of a bounded context in a serverless system can be seen in the following diagram.
There are two paradigms to compose serverless systems:
Each of these paradigms have different characteristics which enable us to make the choice for our use case.
Since we understand bounded contexts and composition paradigms, we will move on to implementation of these principles in AWS.
There are several serverless services in AWS. Some of them are listed down below in their respective category.
AWS step functions are used for serverless orchestration in AWS. Step functions are all about modelling business transactions through series of state transitions. Step functions enable us to do end to end monitoring and reporting via audit histories. The order flow is modeled and source controlled.
Above is one of the example of a step function flow. We can clearly see it as state machine. There are two types of step functions workflows:
Some of the common use cases for AWS step functions are given below
Implementation details and extended flow examples can be studied at AWS official examples page.
Choreography in AWS allows us to modify each step of the flow independently. It also enables us to scale the different parts of our system independently of each other. Since we have already discussed bounded contexts and events, events allows us to extend functionality in choreography comparatively easily.
There are two considerations which we must discuss before proceeding:
Let's discuss the example choreography architecture given below:
There is no centralized service controlling everything. Instead each part of the system relies on the incoming event, does its part and forwards it to a destination. The whole system is driven by events. For this example:
As we saw that the question of choosing SNS & EventBridge at their respective places is still not answered. At this stage, there should be more questions like:
By a quick read about these services, we find out that some services appears to do very similar things like SQS, SNS and EventBridge. In order to have the correct mental model for these services, we must understand how these services integrate with the compute part of our serverless system i.e. Lambda.
There are three ways in which Lambda integrates with the other AWS services.
Before we proceed, lets discuss the synchronous and asynchronous invocation of lambda functions.
In synchronous invocation, we wait for the function to process the event and return a response.
In asynchronous invocation, Lambda queues the event for processing and returns a response immediately.
AWS has very detailed documentation for both kind of invocations. Let's move on to the lambda integration models.
Lambda is a service which contains many resources such as our lambda function, event queue, event resource mapping etc. In this kind of integration, event resource mapping is responsible for polling the target service and fetching data when available.
Below are the services which do poll based integration with AWS Lambda:
Below is an example of this kind of integration from AWS Docs.
In this kind of integration, services themselves are responsible for pushing the event to Lambda Service.
AWS API Gateway, AWS Cognito & AWS CloudFront do this kind of integration with AWS Lambda. The example diagram in choreography section can be seen as an example of API Gateway's integration with Lambda.
For the API Gateway scenario, there is a catch here. Since our Lambda function is invoked synchronously by lambda service, it returns a response. There is a way to configure Lambda so that it integrates with API Gateway in an asynchronous way. Official docs has a very good guide for it.
In this kind of invocation, services invokes the lambda and immediately gets success response after handing over the event. Lambda then processes the event in the background.
S3, SNS, EventBridge & CloudWatch do this kind of integration with lambda. Below is an example where SNS integrates with Lambda in an asynchronous way.
Most of the times, we are dealing with poll based integration and event based integration. Below is a short visual summary of all three types of integrations.
Now we understand different composition paradigms, how they are implemented in AWS and how Lambda integrates with the serverless services in AWS. Let's discuss briefly the design principle and use cases for some common services.
SQS and SNS are used to decouple our applications in cloud. But both of these services have some very distinct characteristics making them suitable for different purposes.
SNS & EventBridge are both used to distribute events. EventBridge is under the hood same as AWS CloudWatch Events API but it provides more features like integrating with external services. SNS is more useable for fanning out events to different services while EventBridge's intended use is for Application Integration.
Sometimes people face difficulty in the limit of 5 target on a matching rule when they try to use EventBridge in place of SNS. What we can do is that to have an SNS topic as a destination of matching rule and route the event to SNS for fanning out. AWS EventBridge is primarily meant for routing event in our system. The convention is to have a separate rule against each service to which we want to route an event. This is good for separation of concerns.
We discussed bounded contexts and composition paradigms, how to implement them in AWS and mental models for some of the services central to event driven systems. After having the knowledge of all these things, we should be able to make an educated choice for our system on the basis of our budget, our use case, our team size and the project timelines. There is no right or wrong for most of the people and systems. But these design decisions and principles become important when we are dealing with serverless at scale.
This whole article is meant to serve as a mental model for designing serverless in AWS. For the implementation details of individual services, AWS Docs are the best place to go.
If you found this post useful, please subscribe. This will enable you to be notified whenever I write something new. If you don't like subscribing to newsletters, please subscribe to RSS + Web feeds.