Skip Service Lists—Build Projects That Matter on AWS
AWS proficiency isn’t measured by how many services you can recite. In practice, engineers solve business problems by integrating multiple AWS services, not by knowing superficial service trivia.
Pitfalls of Memorization-Driven Learning
AWS currently exposes over 200 individual services (as of 2024)—from EC2, S3, and VPC, to more specialized offerings like Neptune and AWS WAF. Certification programs, including the Associate and Professional tracks, frequently encourage memorization of definitions and edge-case limitations.
Result: engineers pass exams but stall when asked to architect and deploy, say, a highly available backend, or to recover from issues like IAM permission errors (e.g., AccessDeniedException
). Knowing a service’s documentation verbatim does not prepare you for, say, debugging CloudFormation drift or diagnosing latency between Lambda and DynamoDB in us-east-1.
Project-Based Learning: What Actually Works
Experienced engineers evolve by architecting, deploying, breaking, and iterating on actual workloads. Small, focused builds simulate real constraints—IAM least privilege, panic over costs, region failover, or incident response.
Competence comes from exposure to integration pain points. Trade-offs become real: S3 triggers via EventBridge or direct Lambda invocation? ALB vs API Gateway?
Below: some representative, minimal-but-concrete AWS project blueprints.
Project Candidates
- Serverless CMS: Lambda (Node.js 18.x), API Gateway (REST endpoint), DynamoDB, S3 static asset hosting, Cognito for authentication.
- Realtime Notifications: SNS topics → Lambda → Slack webhook integration, CloudWatch rule for scheduled trigger.
- Low-Cost Monitoring: CloudWatch Events, Lambda alerts for status checks, SNS SMS failsafe.
- Asset Processing Pipeline: S3 uploads → Step Functions orchestration → Lambda (thumbnail generation) → DynamoDB tracking.
Note: Focused scope = better learning. Generic “To-do” apps rarely expose meaningful AWS patterns.
Real-World Blueprint: AWS Serverless Contact Form (with Notes)
Common on client projects: secure, auditable contact forms. Here’s a production-leaning approach:
[Client] --HTTP POST--> [API Gateway] --Lambda--> [DynamoDB, SES]
|
[CloudWatch Logs]
Implementation Steps
- API Gateway (REST, v1):
- HTTP POST
/contact
endpoint.
- HTTP POST
- Lambda Function (Python 3.11):
- Validates input, integrates with boto3:
ses.send_email
, writes to DynamoDB. - Handles exceptions, logs to CloudWatch.
- Attached IAM policy: minimum SES, DynamoDB, and CloudWatch access only.
- Validates input, integrates with boto3:
- DynamoDB:
- Table schema:
submission_id
(partition key), timestamp, payload JSON. - On-demand capacity (avoid over-provisioning for low-load PoCs).
- Table schema:
- CloudWatch:
- Alarm on Lambda error rate >2% within 5 min.
- Log group retention: 14 days (adjust as needed).
- IaC (CloudFormation or AWS CDK v2):
- All resources declared, single deploy step:
cdk deploy
oraws cloudformation deploy
.
- All resources declared, single deploy step:
Extra:
- Want to test quickly? Use
curl
:curl -X POST https://<api-id>.execute-api.<region>.amazonaws.com/prod/contact \ -H "Content-Type: application/json" \ -d '{"email":"me@corp.tld","message":"hello"}'
- Gotcha: SES is region-locked, and email sending must be out of sandbox mode for production—otherwise, emails to non-verified addresses will silently fail.
Practical Workflow
- Plan architecture visually. Skip whiteboarding? Use draw.io. AWS diagrams clarify role boundaries and request flow.
- Develop incrementally. Example: deploy API Gateway and Lambda stub first (
return {"status": "ok"}
), confirm connectivity, then add DynamoDB. Don’t wire everything at once—service permissions often bite. - Automate. Even for prototypes, use IaC (CDK or Terraform). Drift between hand-configured and templated infra wastes time. Version-control templates.
- Security from the outset. Default IAM permissions are too broad:
{ "Effect":"Allow", "Action":[ "dynamodb:PutItem", "ses:SendEmail" ], "Resource":[ "arn:aws:dynamodb:us-east-1:123456789012:table/ContactSubmissions", "arn:aws:ses:us-east-1:123456789012:identity/example.com" ] }
- Observe and adapt. Log and monitor. Expect quota errors (
ThrottlingException
) or misconfigured endpoints.
Non-obvious tip: For local fast-tracking, consider sam local start-api
or localstack
to simulate Lambda/API Gateway.
Cost, Scale, and Pitfalls
After the basic version deploys, test with traffic. Enable X-Ray tracing for cold start and integration lag diagnosis. Regularly review AWS Cost Explorer—the difference between Provisioned
vs On-demand
DynamoDB can surprise. SNS SMS alerts can silently rack up costs at scale.
For production, always revisit:
- CloudFormation stack growth: Fix cyclic dependencies early.
- API Gateway timeouts: Default is 29 seconds—non-obvious when invoking slow downstream services.
- Data retention: Legal/privacy concerns for storing contact data—configure DynamoDB TTL.
Summary
Certification is not mastery. AWS knowledge compounds fastest when you iterate, break, and observe actual deployments. Real projects expose the nuances—service limits, IAM quirks, regional oddities, and cost spikes.
Next steps: Build, iterate, automate. Optionally, review CloudTrail logs after every deploy for unintended privilege use—leaked permissions hide in plain sight.
Questions, feedback, or war stories? Leave comments.