AWS for DevOps — Serverless Practice Exercises
9.6 — Serverless Practice Exercises
Exercise 1 — Lambda Configuration
A Lambda function processes images uploaded to S3. It resizes images and takes about 45 seconds per image. The function has these settings:
- Memory: 128 MB
- Timeout: 3 seconds
- No dead letter queue
What problems will this cause? Fix the configuration.
Show Answer
Problems:
- Timeout too short — Image processing takes ~45 seconds but timeout is 3 seconds. The function will be killed every time.
- Memory too low — Image processing is CPU-intensive. Since Lambda CPU scales with memory, 128 MB gives minimal CPU. The function will be slow.
- No DLQ — S3 events are asynchronous. If the function fails, AWS retries twice then discards the event. Without a DLQ, failed images are lost.
Fixed configuration:
$ aws lambda update-function-configuration \
--function-name resize-image \
--timeout 120 \
--memory-size 1024 \
--dead-letter-config TargetArn=arn:aws:sqs:ap-south-1:123456789012:failed-resizes-dlq
- Timeout: 120 seconds (45s average + buffer for large images)
- Memory: 1024 MB (8× more CPU for image processing)
- DLQ configured (failed events go to SQS for investigation)
Exercise 2 — API Design
A team wants to build a REST API with these endpoints:
| Endpoint | Method | Description |
|---|---|---|
/users |
GET | List all users |
/users |
POST | Create a user |
/users/{id} |
GET | Get one user |
They expect ~100 requests/minute during business hours and near-zero at night. Should they use REST API or HTTP API? Design the SAM template.
Show Answer
HTTP API — lower cost, lower latency, sufficient features for this use case.
AWSTemplateFormatVersion: "2010-09-09"
Transform: AWS::Serverless-2016-10-31
Globals:
Function:
Runtime: python3.12
Timeout: 10
MemorySize: 256
Resources:
ListUsersFunction:
Type: AWS::Serverless::Function
Properties:
Handler: app.list_users
CodeUri: src/users/
Policies:
- DynamoDBReadPolicy:
TableName: !Ref UsersTable
Events:
Api:
Type: HttpApi
Properties:
Path: /users
Method: get
CreateUserFunction:
Type: AWS::Serverless::Function
Properties:
Handler: app.create_user
CodeUri: src/users/
Policies:
- DynamoDBCrudPolicy:
TableName: !Ref UsersTable
Events:
Api:
Type: HttpApi
Properties:
Path: /users
Method: post
GetUserFunction:
Type: AWS::Serverless::Function
Properties:
Handler: app.get_user
CodeUri: src/users/
Policies:
- DynamoDBReadPolicy:
TableName: !Ref UsersTable
Events:
Api:
Type: HttpApi
Properties:
Path: /users/{id}
Method: get
UsersTable:
Type: AWS::Serverless::SimpleTable
Properties:
PrimaryKey:
Name: UserId
Type: String
Exercise 3 — Event Flow Debugging
A file is uploaded to S3, which triggers a Lambda. The Lambda should write a record to DynamoDB. But the DynamoDB table remains empty. CloudWatch Logs show:
[ERROR] ClientError: An error occurred (AccessDeniedException) when calling the PutItem operation
The Lambda’s execution role has s3:GetObject permission. What is missing?
Show Answer
Missing: DynamoDB permissions on the Lambda execution role.
The execution role has s3:GetObject (to read the uploaded file) but no DynamoDB permissions. The function needs dynamodb:PutItem to write to the table.
Fix:
{
"Effect": "Allow",
"Action": [
"dynamodb:PutItem"
],
"Resource": "arn:aws:dynamodb:ap-south-1:123456789012:table/MyTable"
}
Or with SAM:
Policies:
- S3ReadPolicy:
BucketName: !Ref UploadBucket
- DynamoDBCrudPolicy:
TableName: !Ref MyTable
Exercise 4 — SQS + Lambda Sizing
An SQS queue receives ~1,000 messages per minute. Each message takes ~2 seconds to process. The Lambda has:
- Timeout: 30 seconds
- Batch size: 10
- Reserved concurrency: 5
Will this configuration keep up? Calculate the throughput.
Show Answer
Calculation:
- Each invocation processes 10 messages in ~20 seconds (10 × 2s, assuming sequential)
- Each of 5 concurrent Lambdas can do: 60s ÷ 20s = 3 invocations/min
- Total: 5 × 3 × 10 = 150 messages/minute
Problem: The queue receives 1,000 messages/minute but only 150 are processed. The queue will grow indefinitely.
Fixes (choose one or combine):
- Increase concurrency: Set reserved concurrency to 50 (50 × 30 = 1,500 msg/min)
- Increase batch size: Set to 100 if messages are small (fewer invocations needed)
- Process messages in parallel within Lambda: Use async/threading to process the batch concurrently instead of sequentially
- Remove reserved concurrency limit: Let Lambda auto-scale to match demand
Exercise 5 — Design an Event-Driven Pipeline
Design a serverless pipeline for this workflow:
- A CSV file is uploaded to S3
- Parse the CSV and validate each row
- Valid rows → write to DynamoDB
- Invalid rows → send to an SQS dead letter queue
- After processing, send a summary email via SNS
Draw the architecture and list the AWS resources needed.
Show Answer
Architecture:
S3 (upload bucket)
│
▼ (S3 event: ObjectCreated, suffix=.csv)
Lambda: parse-csv
│
├── Valid rows ──▶ DynamoDB: Records table
│
├── Invalid rows ──▶ SQS: invalid-rows-dlq
│
└── Summary ──▶ SNS: processing-complete
│
▼
Email subscription
AWS Resources:
- S3 Bucket —
csv-uploadswith event notification on*.csv - Lambda Function —
parse-csv- Triggered by S3 event
- Reads CSV from S3, validates rows
- Writes valid rows to DynamoDB
- Sends invalid rows to SQS
- Publishes summary to SNS
- DLQ configured for Lambda failures
- DynamoDB Table —
Records(PK=RecordId) - SQS Queue —
invalid-rows-dlq(for bad data investigation) - SNS Topic —
processing-completewith email subscription - IAM Role — S3 read, DynamoDB write, SQS send, SNS publish
- Lambda DLQ — SQS queue for Lambda execution failures (separate from data DLQ)
Key design decisions:
- Lambda DLQ handles function failures (code errors)
- SQS invalid-rows queue handles data failures (bad CSV rows)
- SNS sends a single summary email — not one per row
Next Chapter → Monitoring & Observability