A complete platform, multi-AZ from the first day.
A full cloud foundation built for a stealth-mode AI startup on AWS: a segmented VPC with a public edge and private compute, an Application Load Balancer over an auto-scaling EC2 tier and a managed Kubernetes cluster, a Multi-AZ managed database with a managed secrets store, and serverless and CDN paths for the work that does not belong on application servers.
The decisions a startup cannot easily undo.
Most infrastructure choices at an early-stage company are reversible. A handful are not, and they are all made in the first fortnight: how the network is segmented, whether the database can survive losing a zone, and where secrets live. This build got those three right at the outset and left everything else adjustable — which is what lets a small team move quickly afterwards without accumulating the kind of debt that eventually requires a migration project.
One region, several zones, three tiers.
A single VPC divided into a public subnet and private subnets across availability zones. The public subnet holds only what must be reachable: the load balancer and the NAT gateways. Everything that runs code or holds data sits private, and reaches the internet outbound through NAT rather than by having an address on it.

Five decisions, and the reasoning behind each.
Multi-AZ from day one, not after the first outage
Availability zones are the cheapest resilience a startup will ever buy, and retrofitting them is the most expensive. Load balancing, auto-scaling, the database and the NAT path were all spread across zones at build time rather than added once something had already fallen over.
Two runtimes, because startups have two kinds of workload
An Auto Scaling Group of EC2 instances and a managed Kubernetes cluster sit side by side. Long-lived conventional services get the simpler runtime; the containerised workloads that need orchestration get one that provides it. Forcing everything into either would have cost the team either flexibility or time.
Nothing that holds data faces the internet
Only the load balancer and the NAT gateways live in the public subnet. Compute and the database are private, reached through the balancer or through NAT for egress — so the blast radius of a misconfiguration is bounded by the network rather than by a security group someone remembered to write.
Credentials are a managed service, not a file
Database and application secrets live in a managed secrets store rather than in environment files, images or a repository. For a small team moving quickly, this is the control that most reliably prevents the mistake everyone eventually makes.
Serverless and static handled where they belong
Event-driven work runs on Lambda, static assets sit in object storage behind a CDN. Neither belongs on the application servers, and keeping them off it is what lets the auto-scaling group be sized for the actual application.
One way in, and it is not to the servers.
DNS resolves through Route 53. Static content is served by CloudFront and never reaches the application tier. Dynamic traffic enters the VPC through a single Internet Gateway and terminates on an Application Load Balancer, which distributes across private compute in multiple availability zones. The load balancer is the only thing in the public subnet that receives requests.
Route 53
DNS at the front, with the failover and health-checking that implies.
CloudFront + S3
Static assets cached at the edge, off the application path entirely.
Application Load Balancer
Layer-7 distribution across zones, and the only public entry point for dynamic traffic.
Paired NAT gateways
One per zone for private egress, so outbound access does not depend on a single zone.
Private means private.
Compute and data sit in private subnets with no route from the internet. Inbound reaches them only via the load balancer; outbound leaves only via NAT. This is unglamorous and it is the single control that most reliably limits the damage of a misconfigured service — because it does not depend on anyone having configured that service correctly.
Two runtimes, deliberately.
Match the runtime to the workload, not to a preference.
An EC2 Auto Scaling Group carries the conventional long-lived services, spread across private subnets in multiple zones and scaling with load. A managed Kubernetes cluster with its own worker nodes carries the containerised workloads that genuinely need orchestration. Lambda handles the event-driven work. Consolidating onto any one of the three would have cost the team either operational simplicity or the ability to run what they actually needed to run.
- EC2 Auto Scaling Group across multiple availability zones
- Amazon EKS with managed worker nodes for orchestrated workloads
- AWS Lambda for event-driven functions
- All compute in private subnets, reached through the load balancer

Survive a zone, and stop storing passwords in files.
The relational database is a managed Amazon RDS for MySQL instance deployed Multi-AZ, so the loss of an availability zone is an automatic failover rather than an outage and a restore. Object storage carries static assets and data at rest. Credentials — database and application alike — live in AWS Secrets Manager rather than in environment files, container images or the repository.
RDS MySQL, Multi-AZ
Managed, replicated across zones, with failover as a property rather than a procedure.
Secrets Manager
Managed credential storage and rotation, out of images and out of the repository.
S3
Object storage for static assets and data at rest.
Private data tier
The database is in a private subnet and is not reachable from the internet at all.
Every component delivered.
| Route 53 | DNS, resolving to the edge of the platform. |
|---|---|
| CloudFront | Content delivery in front of static assets, keeping that traffic off the application tier entirely. |
| Internet Gateway | The single controlled ingress point into the VPC. |
| Application Load Balancer | Layer-7 distribution across the private compute tier, spread over availability zones. |
| NAT Gateways | Paired, one per zone, so private subnets get outbound access without a single-zone dependency. |
| EC2 Auto Scaling Group | Conventional long-lived services, scaling on demand across private subnets in multiple zones. |
| Amazon EKS | A managed Kubernetes cluster with worker nodes, for the containerised and orchestrated workloads. |
| AWS Lambda | Event-driven functions for the work that does not justify a running server. |
| Amazon RDS for MySQL | The relational database, deployed Multi-AZ so a zone failure is a failover rather than an outage. |
| AWS Secrets Manager | Managed storage and rotation for database and application credentials. |
| Amazon S3 | Object storage for static assets and data at rest. |
Delivered for a stealth-mode AI startup. The customer is not named and no detail beyond the architecture is published. This was a delivered engagement rather than a product — there is nothing here to sign up for.