Write a cloud formation / terraform template that involves O(1) machines and deploy 2000 identical copies.
Option two:
Write a template that deploys O(N = 2000) interdependent services across roughly 3-10x as many machines, and deploy one copy.
From what I can tell, you are arguing for option 2. It is strictly worse than option one. In addition to being more complex, it has a few nines less reliability, and costs 3-10x more for the hardware. The dev and CI hardware budgets is going to be 10x more because you can't test it on one machine, and it has bugs that only manifest at scale.
Source: I do this for a living, and have been on both sides of this fence. Option 1 typically has 5-6 nines (measured in chance a given customer sees a 10 second outage), option 2 never gets past 3-4 nines (measured in at least N% of customers are not seeing an outage).
The modern vs old technology debate has nothing to do with this tradeoff. If you want, you can build option 2 with EJB + CORBA on an IBM mainframe, and option 1 with rust and json on an exokernel FAAS.
This was a multi-tenant centrally hosted application. There were 2000 sites served, each with kiosk PCs and some associated special-purpose hardware.
The actual application code ran in just four virtual machines in two data centres.
No templates, no Terraform, no microservices, etc…
Just vanilla ASP.NET on IIS with SQL Server as the back end.
The efficiency stemmed from having a single consolidated scheme for all tenants with a tenant ID as a prefix to every primary key.
Shared tables (reference data) simply didn’t have a prefix.
The vendor product that replaced this was not multi-tenant in this sense. They deployed a database-per-tenant, and lots of “application servers”. Not one per tenant, but something like one per ten, so two hundred large virtual machines running twenty instances of their app.
Management of the new system took serious automation, disk image building, etc…
The repetition of the reference data bloated the database from 50GB to terabytes!
Also, the fact that a consulting company was able to turn a part time gig for one person into a $100M+ project at the taxpayer's expense is very frustrating.
If I remember correctly, my version had something like 8 + 8 cores in an active/passive configuration where the passive node is free. There was also a single dev/test server also with 8 cores, but that's free too.
The replacement used a few hundred cores shared by the various instances and environments. If I remember correctly, they had something like 10-20 databases per virtual machine, and then about 5 virtual machines per physical host. (I can't remember the exact ratios.)
The "modern" cloud approach of having dedicated VMs for a single thing is actually terribly inefficient, and that approach would have bloated out the above to thousands of VMs instead of "merely" a few hundred.
The correct architecture for something like this -- these days -- might be to use Kubernetes. This provides the required high availability and instancing, while efficiently bin-packing and deduplicating the storage.
Still, you can't Helm-chart your way out of an inefficient application codebase.
Again, for comparison, my version could run on a laptop and had about half a dozen components, not thousands.
Were there 2000 independent systems / SQL server instances running or just one? 2K separate deployments to manage (with 1K users each), does sound a little scary. Of course, perhaps that is not what is going on at all.