A learning-by-shipping cloud backend: an AWS-native video-ingestion service defined entirely in Terraform, no manual console clicks.
Implemented
- Lambda (Go) function that generates time-limited S3 presigned URLs for authenticated users.
- API Gateway in front of the Lambda, with a JWT authorizer backed by a Cognito user pool.
- RDS Postgres instance for user state, with credentials issued via Secrets Manager (the Lambda assumes a role that allows reading the secret at cold start).
- S3 bucket for content storage. The data plane (the actual upload) goes directly from the client to S3 via the presigned URL — the control plane (auth + URL generation) never sees the payload.
- IAM roles scoped to least privilege per component: the Lambda role can sign presigned URLs and read its secret; the RDS Proxy role can connect to the DB; nothing has broad permissions.
The pattern
The thing I was learning was the separation between control plane and data plane — the property that the request that authorizes an upload is small and synchronous, while the upload itself is large and direct to storage. Get this wrong and your Lambda becomes a bottleneck on bandwidth instead of on auth latency. Get this right and a cheap Lambda can serve thousands of concurrent uploads because it never touches the bytes.
The architecture is lifted from production media platforms (YouTube, Twitch, S3-presigned-URL pattern in general). Building it once in Terraform is how you learn what “least privilege” actually requires in IAM JSON.