Ravindra BagaleCourses & study guides मराठी Track your progress

Project: Build Upload Receipt Emails with S3, Lambda, SES and DynamoDB (Source Code)

After you upload a document to Drive-style storage, you get a mail receipt. Here: S3 upload → Lambda → SES email (or SNS fallback) + DynamoDB receipt row. Watch the SES sandbox.

What you'll learn in this chapter

  • S3 trigger receipt flow
  • SES send with sandbox rules
  • SNS fallback switch
  • Cleanup

1. Everyday example

Why do we need this?

Students upload assignments. Teacher wants an email: file name + size + time — proof it landed.

What is it?

ObjectCreated → Lambda reads event (no need to download body) → ses.send_email or sns.publish → PutItem receipt.

SES sandbox

New accounts can mail only verified From and To identities. Verify both in SES (ap-south-1). If blocked, set USE_SNS=1 and a confirmed email topic.

Download: upload-receipt-email.zip

2. Lab

How to do it (step by step)

A. Bucket + table + mail

  1. Bucket yourname-uploads, BPA on.
  2. Table yourname-receipts, PK receiptId.
  3. SES: verify From and To emails (or prepare SNS topic fallback).

B. Lambda + trigger

  1. Role: s3:GetObject (optional), ses:SendEmail, sns:Publish, PutItem, logs.
  2. handler.py env TABLE_NAME, FROM_EMAIL, TO_EMAIL. Or USE_SNS=1 + TOPIC_ARN.
  3. S3 event on create → Lambda. Upload a small file. Check mail + DynamoDB.

Cleanup

  1. Remove event, Lambda, bucket (empty first), table, role. Leave or delete SES identities.
  2. Delete SNS topic if used.

3. Interview

Q. Why SES over putting raw SMTP on EC2?

Managed deliverability, no server.

Q. Sandbox purpose?

Stops accidental spam from new accounts.

Q. SNS fallback?

Same notification habit when SES is blocked in class.

Q. Idempotency?

Same key re-upload may re-mail — version keys or dedupe tokens.

Q. Cleanup?

Event, Lambda, bucket, table.

Try at home

  1. Include object etag in the email body.
  2. Add CloudWatch alarm on Lambda errors.

In short

  1. S3 → Lambda → SES/SNS + DynamoDB.
  2. Respect SES sandbox.
  3. Receipts are audit rows.
  4. Clean up.

Practice Tasks

About this scenario

London Legal LLP is a law business in London. Oliver Hughes looks after its IT and cloud work. They count money in GBP and run their AWS resources in the eu-west-2 Region. In the tasks below you do real jobs for them using what this lesson teaches. All names, account IDs, IP addresses and numbers are made up for practice.

0 / 12

Easy List functions

Why: See which functions exist in this Region.

What to do: List the Lambda functions in eu-west-2.

How:
  1. Read the task and decide which AWS service it is about.
  2. Write aws, then the service name, then the operation (the action word).
  3. Add each needed flag (--name) followed by its value from the task.
  4. Flags can be in any order. Click Check answer.

Medium Invoke a function

Why: Invoke runs the function now and saves its answer in a file.

What to do: Invoke londonlegal-orders-fn and save the response to out.json.

How:
  1. Read the task and decide which AWS service it is about.
  2. Write aws, then the service name, then the operation (the action word).
  3. Add each needed flag (--name) followed by its value from the task.
  4. Flags can be in any order. Click Check answer.

Medium Trust policy for a Lambda role

Why: The trust policy says WHO may take the role.

What to do: Write a trust policy that lets lambda.amazonaws.com assume the role.

How:
  1. Start with { "Version": "2012-10-17", "Statement": [ ... ] }.
  2. In each statement write Effect, Action and Resource.
  3. Give only what the task needs (least privilege).
  4. Use double quotes and commas correctly. Click Check answer.

Medium Put an item

Why: DynamoDB JSON shows the type of each value: S for string, N for number.

What to do: Put an item into londonlegal-orders with orderId "o-101" (string) and amount 2500 (number).

How:
  1. Read the task and decide which AWS service it is about.
  2. Write aws, then the service name, then the operation (the action word).
  3. Add each needed flag (--name) followed by its value from the task.
  4. Flags can be in any order. Click Check answer.

Medium Change timeout and memory

Why: More memory also gives more CPU; timeout stops runaway runs.

What to do: Set londonlegal-orders-fn to timeout 30 seconds and memory 512 MB.

How:
  1. Read the task and decide which AWS service it is about.
  2. Write aws, then the service name, then the operation (the action word).
  3. Add each needed flag (--name) followed by its value from the task.
  4. Flags can be in any order. Click Check answer.

Medium Let a function write logs

Why: Without these actions, Lambda logs never appear in CloudWatch.

What to do: Allow logs:CreateLogGroup, logs:CreateLogStream, logs:PutLogEvents on arn:aws:logs:*:*:* only.

How:
  1. Start with { "Version": "2012-10-17", "Statement": [ ... ] }.
  2. In each statement write Effect, Action and Resource.
  3. Give only what the task needs (least privilege).
  4. Use double quotes and commas correctly. Click Check answer.

Hard Create a Lambda function

Why: Lambda needs the code zip, a runtime, a handler name and an execution role.

What to do: Create function londonlegal-orders-fn: runtime python3.12, handler app.handler, role arn:aws:iam::114543297314:role/lambda-basic, code in function.zip.

How:
  1. Read the task and decide which AWS service it is about.
  2. Write aws, then the service name, then the operation (the action word).
  3. Add each needed flag (--name) followed by its value from the task.
  4. Flags can be in any order. Click Check answer.

Hard Set environment variables

Why: Keep settings like table names out of the code.

What to do: Set the environment variable TABLE=londonlegal-orders on londonlegal-orders-fn.

How:
  1. Read the task and decide which AWS service it is about.
  2. Write aws, then the service name, then the operation (the action word).
  3. Add each needed flag (--name) followed by its value from the task.
  4. Flags can be in any order. Click Check answer.

Hard Invoke with a JSON payload

Why: In CLI v2, raw JSON needs --cli-binary-format raw-in-base64-out.

What to do: Invoke londonlegal-orders-fn with payload {"orderId":"o-101"} (raw JSON) and save the reply in out.json.

How:
  1. Read the task and decide which AWS service it is about.
  2. Write aws, then the service name, then the operation (the action word).
  3. Add each needed flag (--name) followed by its value from the task.
  4. Flags can be in any order. Click Check answer.

Hard Lambda GB-seconds

Why: Lambda bills memory × time.

What to do: 1,000,000 invocations, 512 MB memory, 200 ms each. How many GB-seconds?

How:
  1. Write down the numbers the task gives you.
  2. Work it out step by step on paper.
  3. Type only the final answer in the box.
  4. Click Check answer.

Hard Connect an SQS queue to Lambda

Why: An event source mapping makes Lambda poll the queue and process messages in batches.

What to do: Create an event source mapping from queue arn:aws:sqs:eu-west-2:114543297314:londonlegal-orders to londonlegal-orders-fn with batch size 10.

How:
  1. Read the task and decide which AWS service it is about.
  2. Write aws, then the service name, then the operation (the action word).
  3. Add each needed flag (--name) followed by its value from the task.
  4. Flags can be in any order. Click Check answer.

Hard Let S3 call your function

Why: A resource-based permission is needed before S3 can invoke the function.

What to do: Add permission statement s3invoke to londonlegal-orders-fn so s3.amazonaws.com can call lambda:InvokeFunction from bucket arn:aws:s3:::londonlegal-uploads.

How:
  1. Read the task and decide which AWS service it is about.
  2. Write aws, then the service name, then the operation (the action word).
  3. Add each needed flag (--name) followed by its value from the task.
  4. Flags can be in any order. Click Check answer.

Revision, comparison and interview cards

Revise this lesson in a few minutes. Save the cards on your phone or download them as PNG files. The QR code on each card opens this lesson.

Revision card: Upload receipt email. After you upload a document to Drive-style storage, you expect a mail saying it landed. Same idea on S3. S3 ObjectCreated → Lambda → SES SendEmail (or SNS email fallback) → DynamoDB receipt row (objectKey, when, to). Bucket + event → Lambda with ses:SendEmail or sns:Publish + PutItem. Verify SES identity or use SNS topic in sandbox. Upload docs/lab.pdf → email “Received docs/lab.pdf” and DynamoDB item with the key.
Revision card: Upload receipt email · Download PNG · Open card page
Revision card: SES vs SNS fallback. SES sandbox only mails verified identities. Students often cannot leave sandbox in one lab session. Amazon SES is built for email. If sandbox blocks you, publish to an SNS email topic instead so the flow still teaches. Try verify email in SES. If stuck, set USE_SNS=1 and TOPIC_ARN. IAM allows the path you use. Same upload triggers a receipt either from SES or SNS depending on the env flag — DynamoDB still logs one row.
Revision card: SES vs SNS fallback · Download PNG · Open card page
Revision card: Idempotent receipts. S3 can retry the same ObjectCreated event. Double email confuses users. Idempotent = doing the same work twice is safe. Key the DynamoDB receipt by object versionId or etag; skip if already sent. PutItem with condition attribute_not_exists(receiptId) or GetItem first; only then SendEmail. Two deliveries of the same event → one email, one DynamoDB row.
Revision card: Idempotent receipts · Download PNG · Open card page
Comparison: Amazon SES vs Amazon SNS email. Amazon SES: Purpose-built email sending and templates. Amazon SNS email: Simple pub/sub notify including email subscribers.
Comparison: Amazon SES vs Amazon SNS email · Download PNG · Open card page
Interview card: Why SES instead of SMTP on EC2?. Managed email sending, reputation tooling, and IAM auth — no mail server to patch. Sandbox limits early mistakes; production raises sending limits deliberately. ses:SendEmail from Lambda with a verified identity in ap-south-1.
Interview card: Why SES instead of SMTP on EC2? · Download PNG · Open card page
Interview card: How do you avoid double receipt emails?. S3 may deliver the same event more than once; handlers must be idempotent. Key receipts by object etag/versionId; skip SendEmail if the row exists. PutItem ConditionExpression attribute_not_exists(receiptId) before SES.
Interview card: How do you avoid double receipt emails? · Download PNG · Open card page

More cards: Ravi Sir's Cards.