case study · AWS platform · 2026
Microservices platform infrastructure
Terraform infrastructure and a working local environment for a .NET microservices platform. Eight services and two workers share a synchronous API path and an asynchronous S3 and SQS path.
problem
Run a complete product platform within a strict cost limit
The platform needed an admin frontend, eight APIs, two background workers, PostgreSQL, Redis, OpenSearch and queue-based processing. The infrastructure also had to remain small enough for a personal AWS account and reproducible enough to remove when it was not being tested.
The application runs locally as the same set of services used by the AWS design. LocalStack provides S3 and SQS, while real PostgreSQL, Redis and OpenSearch containers avoid replacing cloud dependencies with simpler substitutes.
architecture
Separate request traffic from background processing
Requests follow CloudFront → ALB → ECS → data services. File imports and search updates use S3 and SQS so bursts of background work do not block API requests. Each queue has a dead-letter queue for messages that cannot be processed successfully.
decisions and tradeoffs
Key design decisions
- ECS on EC2 instead of Fargate
- Ten workloads share one small instance. This lowers compute cost but gives the platform less isolation and capacity than separate Fargate tasks.
- No NAT gateway
- ECS runs in a security-group-restricted public subnet, while databases remain private. S3 and DynamoDB gateway endpoints cover those service paths. The design saves the fixed NAT cost but requires tighter control of the compute subnet.
- SQS workers instead of synchronous jobs
- PDF imports and search updates can retry independently and cannot hold open an API request. The tradeoff is eventual consistency and additional failure handling.
- One CloudFront origin for frontend and API paths
- CloudFront serves S3 content and forwards API paths to the ALB under one hostname, removing the need for browser CORS configuration.
what broke
Local services used the wrong SQS region
LocalStack created queues in its default region while the application requested them from
ap-south-1. The queue names were correct, but every worker reported that its queue
did not exist. Creating the local queues in the same configured region fixed the mismatch.
A second container failure came from the worker image. The Prometheus ASP.NET package required the ASP.NET shared framework, but the workers used the smaller .NET runtime image. They exited at startup until their Dockerfiles switched to the ASP.NET runtime base.
numbers
Current scope
- 8application services
- 2background workers
- 16containers in the complete local environment
- 121Terraform resources in the clean cloud plan
The local application is complete and the infrastructure modules were applied and removed once. The current 121-resource cloud deployment plan is complete; a full application deployment to AWS remains pending.