AWS Builder Center

How I Built an Automated Cloud Resume API Using AWS Lambda and DynamoDB

A step-by-step student guide to building a serverless Cloud Resume API using AWS Lambda, DynamoDB, API Gateway, and Python. Learn how to showcase your cloud skills with real infrastructure.

When I first started applying for cloud engineering internships, every job posting asked for hands-on experience with AWS. Static PDF resumes are great for human recruiters, but building a Cloud Resume API turned out to be the best project to actually prove I knew how services fit together behind the console.
In this guide, I will walk you through how I built a simple, production-ready serverless API that serves resume data (like work experience, projects, and skills) in JSON format using AWS Lambda, Amazon DynamoDB, and Amazon API Gateway.
Whether you are prepping for the AWS Certified Cloud Practitioner exam or trying to stand out in campus placements, this project gives you something concrete to discuss in interviews.
Architecture Overview
Here is how the data flows when someone queries your API:
[ User / Web Browser ]
│
(HTTP GET)
▼
[ Amazon API Gateway ]
│
(Routes Request)
▼
[ AWS Lambda Function ]
│
(Query Item)
▼
[ Amazon DynamoDB ]
Amazon API Gateway: Receives incoming HTTP request from a browser or script.
AWS Lambda: Executes a small Python script that fetches data from the database.
Amazon DynamoDB: A NoSQL table storing your resume sections as items.
Prerequisites
To follow along, you only need three things:
An AWS Free Tier Account (all services used here fall well within free limits).
The AWS CLI installed on your local machine.
Basic understanding of Python and JSON.
Step 1: Create the DynamoDB Table
First, we will store our resume data in a single NoSQL table.
Open your terminal and run this command to create a table named CloudResume:
Bash
aws dynamodb create-table
--table-name CloudResume
--attribute-definitions AttributeName=Section,AttributeType=S
--key-schema AttributeName=Section,KeyType=HASH
--billing-mode PAY_PER_REQUEST
--region us-east-1
Now, let's insert a sample item for your education background:
Bash
aws dynamodb put-item
--table-name CloudResume
--item '{
"Section": {"S": "Education"},
"Degree": {"S": "B.Tech in Computer Science"},
"University": {"S": "Tech University"},
"GraduationYear": {"S": "2026"}
}'
--region us-east-1
Step 2: Write the Lambda Function
Next, we write a Python script that reads from DynamoDB whenever the API endpoint is hit.
Create a file named lambda_function.py:
Python
import json
import boto3
from botocore.exceptions import ClientError

Initialize DynamoDB client

dynamodb = boto3.resource('dynamodb', region_name='us-east-1')
table = dynamodb.Table('CloudResume')
def lambda_handler(event, context):
# Extract query parameter (e.g., ?section=Education)
query_params = event.get('queryStringParameters') or {}
section = query_params.get('section', 'Education')
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
try:
response = table.get_item(Key={'Section': section})
item = response.get('Item')

if not item:
return {
'statusCode': 404,
'headers': {'Content-Type': 'application/json', 'Access-Control-Allow-Origin': '*'},
'body': json.dumps({'error': f'Section "{section}" not found.'})
}

return {
'statusCode': 200,
'headers': {'Content-Type': 'application/json', 'Access-Control-Allow-Origin': '*'},
'body': json.dumps(item)
}

except ClientError as e:
print(f"Error fetching data: {e}")
return {
'statusCode': 500,
'body': json.dumps({'error': 'Failed to fetch resume data.'})
}
Step 3: Set Up IAM Permissions and Deploy Lambda
Lambda needs an execution role that permits it to read from DynamoDB.
Create a file named trust-policy.json:
JSON
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": { "Service": "lambda.amazonaws.com" },
"Action": "sts:AssumeRole"
}
]
}
Create the IAM Role and attach the DynamoDB Read-Only policy:
Bash
aws iam create-role
--role-name ResumeLambdaRole
--assume-role-policy-document file://trust-policy.json
aws iam attach-role-policy
--role-name ResumeLambdaRole
--policy-arn arn:aws:iam::aws:policy/AmazonDynamoDBReadOnlyAccess
aws iam attach-role-policy
--role-name ResumeLambdaRole
--policy-arn arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole
Package and create the Lambda function:
Bash
zip function.zip lambda_function.py
aws lambda create-function
--function-name FetchResumeAPI
--runtime python3.12
--handler lambda_function.lambda_handler
--role arn:aws:iam::YOUR_ACCOUNT_ID:role/ResumeLambdaRole
--zip-file fileb://function.zip
--region us-east-1
(Note: Replace YOUR_ACCOUNT_ID with your actual 12-digit AWS account ID).
Step 4: Expose the Function via API Gateway
To turn our function into a public web endpoint:
Open the Amazon API Gateway Console.
Click Create API and choose HTTP API (it is faster and cheaper for simple workloads).
Under Integrations, select Lambda and pick FetchResumeAPI.
Name your API ResumeAPI and set the path route to /resume with method GET.
Deploy the API and copy the generated Invoke URL (it will look like https://xyz123.execute-api.us-east-1.amazonaws.com/resume ).
Testing Your API
Open your browser or terminal and test the endpoint:
Bash
curl "https://YOUR_API_ID.execute-api.us-east-1.amazonaws.com/resume?section=Education"
Expected Response:
JSON
{
"Section": "Education",
"Degree": "B.Tech in Computer Science",
"University": "Tech University",
"GraduationYear": "2026"
}
What I Learned as a Student
Costs stay near zero: Because every service here uses pay-as-you-go pricing, idle infrastructure costs $0.00.
CORS matters: Always include 'Access-Control-Allow-Origin': '*' in your Lambda response headers if you plan to call this API from a frontend portfolio site.
Single-Table Design: DynamoDB works best when you keep queries simple using partition keys.
Next Steps for Your Portfolio
If you want to take this project even further:
Hook up a simple HTML/JavaScript website hosted on S3 or CloudFront that fetches data directly from this API.
Add a custom domain name using Route 53.
Automate deployment using AWS SAM or Terraform.
Any opinions in this article are those of the individual author and may not reflect the opinions of AWS.
Enjoyed reading this content? Let the author know!

Your likes, comments, shares, and saves help creators reach more builders.

Loading recommendations

Loading article