Skip to content

Serverless Architectures

The first problem is a mobile application with a specific set of requirements:

  • It must be exposed as a REST API with HTTPS.
  • The architecture must be serverless.
  • Users should be able to interact directly with their own folder in S3.
  • Users should authenticate through a managed serverless service.
  • Users write and read to-dos, but they mostly read them.
  • The database should scale and provide high read throughput.

Each requirement forces one decision, and the architecture assembles itself as you go.

The mobile client calls REST over HTTPS into Amazon API Gateway. API Gateway verifies authentication against Amazon Cognito, which is what the mobile client authenticated with in the first place. Once the request passes, API Gateway invokes AWS Lambda, and the Lambda function queries Amazon DynamoDB.

That satisfies the first, second and fourth requirements at once: HTTPS REST, nothing to provision, and a managed serverless identity service.

The third requirement — direct access to their own S3 folder — is not solved by the API at all; the deck wires the mobile client straight to the bucket instead.

Instead, Cognito hands the mobile client permissions, and the client stores and retrieves files in Amazon S3 directly. Cognito is what issues the credentials, and the policy attached to them is what scopes each user to their own prefix.

High read throughput on mostly-static data

Section titled “High read throughput on mostly-static data”

The fifth and sixth requirements say reads dominate and the data changes rarely. That is a caching problem, and on DynamoDB the answer is DAX: a caching layer in front of the table, so the Lambda function’s query or read is served from cache instead of consuming table capacity.

DAX caches the database reads, but the request still travels all the way to Lambda each time. The last refinement is caching of responses at the API Gateway level, so repeated identical REST requests are answered before Lambda is ever invoked.

The two caches sit at different layers and both are worth having: API Gateway caches the whole HTTP response, DAX caches the DynamoDB items behind it.

  • A REST API with nothing to provision: HTTPS in, then API Gateway, Lambda and DynamoDB.
  • Cognito minting temporary credentials under a restricted policy, so the app’s own users reach the S3 bucket themselves — and the same trick carries over to DynamoDB, Lambda and more.
  • DAX absorbing the reads that would otherwise hit DynamoDB.
  • Response caching on API Gateway for the REST calls.
  • Cognito again, this time as the authentication and authorization half of security.

The second problem is a website with these requirements:

  • It should scale globally.
  • Blogs are rarely written but often read.
  • Part of the site is purely static files, the rest is a dynamic REST API.
  • Caching must be implemented wherever possible.
  • Any new user who subscribes should receive a welcome email.
  • Any photo uploaded to the blog should have a thumbnail generated.

The static half is Amazon S3 as the origin behind an Amazon CloudFront global distribution. Clients interact with edge locations rather than the bucket, which is what makes the site fast everywhere.

Serving static content globally and securely

Section titled “Serving static content globally and securely”

Fronting the bucket with CloudFront is not enough if the bucket itself is still reachable. You add OAC (Origin Access Control) and a bucket policy that only authorizes requests from the CloudFront distribution. The bucket then has exactly one legitimate reader.

The dynamic half repeats the pattern from the first architecture: Amazon API Gateway takes REST over HTTPS, invokes AWS Lambda, and Lambda queries or reads DynamoDB through a DAX caching layer.

Notice what is missing: there is no Cognito here, because this API is public.

Global scale means the data must be close to the reader too, not just the static files. Replacing the single table with DynamoDB Global Tables puts a readable and writable copy of the data in each region the application runs in.

Sending the welcome email is done without touching the API code. Writes to the DynamoDB table are captured by a DynamoDB Stream, the stream invokes a Lambda function, and that function — carrying an IAM role that permits it — uses the SDK to send an email through Amazon Simple Email Service (SES).

Photos are uploaded to S3 through Transfer Acceleration. The upload triggers a Lambda function, which writes the generated thumbnail back to Amazon S3. S3 can also notify SQS or SNS about the same events — those two are the pieces the deck marks optional.

Pulling the pieces together, the deck’s own recap:

  • Static content distributed using CloudFront with S3.
  • The REST API was serverless and did not need Cognito, because it is public.
  • A Global DynamoDB table served the data globallyAurora Global Database could have been used instead.
  • DynamoDB Streams were enabled to trigger a Lambda function.
  • That Lambda function had an IAM role which could use SES.
  • SES sent the emails in a serverless way.
  • S3 can trigger SQS, SNS or Lambda to notify of events.

The third scenario is an organization that wants to switch to a micro services architecture:

  • Many services interact with each other directly using a REST API.
  • The architecture of each micro service may vary in form and shape.
  • The motivation is a leaner development lifecycle for each service.

Users make a DNS query to Amazon Route 53, which resolves service1.example.com, service2.example.com and service3.example.com to three entirely different back ends reached over HTTPS:

Service Shape
service1 Amazon API Gateway in front of AWS Lambda, with ElastiCache
service2 Elastic Load Balancing in front of Amazon EC2 in an Auto Scaling group, with Amazon RDS
service3 Elastic Load Balancing in front of ECS, with DynamoDB

That heterogeneity is the point: nothing forces the three services to share a compute model or a database.

You are free to design each micro service the way you want, and the communication patterns fall into two families:

  • Synchronous patterns: API Gateway, load balancers.
  • Asynchronous patterns: SQS, Kinesis, SNS, Lambda triggers such as S3 events.

The challenges the deck names:

  • Repeated overhead for creating each new micro service.
  • Issues with optimizing server density and utilization.
  • Complexity of running multiple versions of multiple micro services simultaneously.
  • Client-side code requirements that keep multiplying, because every separate service has to be integrated with individually.

Some of these are solved by serverless patterns:

  • API Gateway and Lambda scale automatically and you pay per usage, which removes the density and utilization problem entirely.
  • You can easily clone an API and reproduce environments, which cuts the per-service setup overhead.
  • A client SDK is generated through the Swagger integration for API Gateway, which reduces the client-side integration burden.

4. Offloading software update distribution

Section titled “4. Offloading software update distribution”

The last scenario is a cost problem rather than a greenfield design.

An application on EC2 ships software updates now and then. Each release brings a flood of requests and pushes the same content out across the network en masse, and that gets expensive fast. The catch: the application itself must stay as it is, while cost and CPU both have to come down.

Today the application runs in an Auto Scaling group spread across Availability Zones 1 to 3, with Amazon Elastic File System holding the update files that all the instances share.

Put Amazon CloudFront in front of the existing setup. Nothing else moves: the same ASG, the same EFS, the same application.

  • No changes to the architecture are needed.
  • It caches the software update files at the edge.
  • Software update files are not dynamic — they are static and never change, which makes them ideal cache candidates.
  • The EC2 instances are not serverless, but CloudFront is, and it scales for us.
  • The ASG will not scale as much, so you save tremendously on EC2.
  • You also save on availability pressure and network bandwidth cost.

For no rewrite at all, an application you already run ends up scaling further and costing less.

Item What to remember for the exam
MyTodoList REST layer Mobile client → API Gateway (HTTPS REST) → Lambda → DynamoDB, with Cognito verifying authentication
Direct S3 access for users Cognito issues temporary credentials with a restricted policy so the client talks to S3 directly; the pattern generalizes to DynamoDB, Lambda and others
Read-heavy DynamoDB Add DAX as the caching layer for reads
API-level caching API Gateway response caching sits in front of Lambda, complementing DAX behind it
Static content globally CloudFront distribution over an S3 origin, clients hitting edge locations
Securing the origin OAC (Origin Access Control) plus a bucket policy authorizing only the CloudFront distribution
Public serverless API API Gateway + Lambda + DynamoDB + DAX, no Cognito needed when the API is public
Global data DynamoDB Global Tables — or Aurora Global Database as the alternative
Welcome email flow DynamoDB Streams → Lambda (with an IAM role) → Amazon SES
Thumbnail flow S3 upload via Transfer Acceleration → Lambda → thumbnail back in S3; S3 can optionally also notify SQS or SNS
Micro services routing Route 53 resolves one hostname per service; each service can use a different stack (API Gateway + Lambda + ElastiCache, ELB + EC2 ASG + RDS, ELB + ECS + DynamoDB)
Micro services patterns Synchronous: API Gateway, load balancers. Asynchronous: SQS, Kinesis, SNS, Lambda triggers such as S3
Micro services challenges Per-service setup overhead, server density and utilization, many versions running at once, client-side integration sprawl
Serverless relief API Gateway and Lambda scale automatically and are pay-per-use, environments are easy to clone, and Swagger generates the client SDK
Update offloading Static update files served from an EC2 ASG over EFS become expensive; CloudFront caches them at the edge with no architecture change, shrinking the ASG and the bandwidth bill