Maurice Murphy made the leap from full-stack development to cloud engineering by shipping a serverless URL shortener—his first production-grade project on Amazon Web Services. The application strips complexity to the essentials: a React frontend, a Python backend, a NoSQL database, and a global content delivery network. For Murphy, the goal wasn’t to create another clone of popular services, but to build confidence in architecting AWS systems while keeping costs minimal.
Why a serverless stack made sense
Murphy chose AWS Lambda to handle shortening and redirection because the service spins up only when needed, automatically scales, and charges per millisecond of compute time. At low traffic levels, the bill remains near zero. The Python function required only a few dozen lines of code, a language Murphy was still learning. “This project was my attempt at intentionally building infrastructure instead of letting it grow organically,” he said.
For the database, Murphy picked DynamoDB over a relational option because the access pattern is straightforward: fetch one short code and return one URL. A single key lookup fits NoSQL perfectly, and Murphy’s prior work with MongoDB gave him a head start. API Gateway was the bridge between the public internet and the Lambda function, since functions alone have no public address. Without API Gateway, the app would have no entry point.
The React frontend lived in an S3 bucket as static files—index.html, CSS, JS, and two SVGs—while all data operations stayed on the backend. CloudFront delivered the content over HTTPS and enforced origin access control, allowing Murphy to keep the S3 bucket private and secure. That setup reduced surface area and simplified permission management.
Infrastructure designed for efficiency, not bloat
Cost efficiency wasn’t an afterthought; it was the primary constraint. Murphy avoided services that weren’t strictly necessary, a mindset that guided every decision. “I’m targeting AWS roles and studying for the SAA-C03, so I need to understand when to use Lambda over EC2, DynamoDB over RDS, and S3 over anything else,” he explained. The project became a live lab for applying the principle of least privilege.
Murphy scoped the IAM role for Lambda to only two DynamoDB actions: GetItem and PutItem on a single table. If the Lambda function misbehaved, the blast radius remained limited to those two operations. “Even if something went wrong, the issue is contained,” he noted. The same principle applied to the IAM user he created for this project: Murphy ensured it had only the permissions required to provision resources, avoiding the common trap of over-permissioned accounts.
Debugging the invisible layers
The smoothest services hid the most subtle mistakes. Murphy’s first error surfaced before any code was written: his IAM user lacked the permission to create roles, which Lambda requires to run. The fix was simple—adding iam:CreateRole via an admin account—but it underscored the need to verify permissions early.
A region mismatch between Lambda (us-east-2) and DynamoDB (us-east-1) caused silent failures until Murphy aligned both to the same region. The Python boto3 SDK inherited the wrong region, too, until Murphy hardcoded region_name='us-east-1' in the resource call. “I should always set the region explicitly,” he admitted.
CORS proved the most frustrating hurdle. Murphy’s React app on localhost sent an OPTIONS preflight request before every POST, but API Gateway returned 404 because no OPTIONS route existed. The fix required four separate steps: adding OPTIONS routes in API Gateway, injecting CORS headers into every Lambda response, writing an explicit OPTIONS handler in Lambda, and finally recreating the API Gateway when deployment changes failed to propagate. “CORS requires headers in both API Gateway and Lambda, and the preflight route must exist,” Murphy said.
CloudFront delivered the final lesson. Murphy kept receiving 403 errors even after verifying the S3 bucket policy. The issue stemmed from using the S3 website endpoint instead of the REST endpoint, a detail that broke the origin access control flow. Once Murphy switched to the REST endpoint, CloudFront began serving content correctly.
What the project proves for career changers
Murphy’s serverless URL shortener is more than a portfolio piece; it’s a proof of concept for career switchers aiming to break into cloud engineering. The project demonstrates how to design end-to-end systems, manage IAM safely, debug cross-service interactions, and keep costs predictable.
For those preparing for the AWS Solutions Architect Associate exam, Murphy’s journey highlights the importance of region alignment, permission scoping, and service selection. The skills he honed—Lambda, DynamoDB, API Gateway, S3, and CloudFront—are foundational blocks for modern cloud applications.
As Murphy continues his transition toward full-time cloud roles, his next steps include deepening Python fluency and exploring advanced AWS services like Step Functions and EventBridge. The serverless URL shortener remains live, quietly redirecting links while serving as a living resume.
AI summary
Kariyerini değiştirmek isteyen geliştiriciler için AWS’de ilk üretim projesini hayata geçiren Maurice Murphy’nin deneyimleri ve teknik ipuçları. Sunucusuz mimari, DynamoDB, API Gateway ve CORS hatasıyla ilgili pratik bilgiler.