- IaC Insights
- Posts
- Multi-instance Root Modules
Multi-instance Root Modules
What would a single-instance root module setup look like for a decent sized infra repo?
Hey folks,
I'm starting to put down my thoughts on why we recommend multi-instance root modules in more depth. As part of that, I'm thinking through the idea of what one of our decent sized client infra monorepos would look like if we ran it single-instance.
Spoiler: it doesn't look great... But let’s dive in.
Here is background info about this multi-instance infra monorepo that we built for a client:
79 Root Modules (e.g. aws-backup, aurora-postgres, github-repositories, vpc, etc.)
Across those root modules we have ~54K lines of TF code (LOC), split across 691 OpenTofu files.
We have 238 instances of these root modules. Each of these instances is a workspace for a given root module, and this is what makes this project "multi-instance".
Our average LOC per root module is ~684 (54,000 / 79).
Now, if we ran this project with single-instance root modules, here is the back of napkin math on what that would look like.
If we implemented the single-instance pattern very naively, and we've seen this mistake a lot of times, we'd have 238 root module directories. With our 684 LOC average we'd end up with roughly a whopping 163K LOC (238 * 684). That is three times the amount of code that we'd need to maintain.
If we implemented single-instance in the smart way, we'd still need the original 79 root modules (now child modules) and their corresponding ~54K LOC, BUT we'd add an additional 238 root module directories (one for for each instance) and some additional code to instantiate each. Say that is roughly 100 LOC per root module; we'd add an additional ~24K LOC.
In the latter case, things aren't that bad, right? At first glance, it seems fine. Just an extra bunch of directories and 24K LOC of code? What's 24K LOC between friends right?
No big deal. Except you can’t enforce that each instance is only a call to a child module.
Oh damn, somebody needs a resource quick? Oops, they added it to the root module directly and now dev is not like stage or prod. Eh, I'm sure the team will figure it out on the fly.
Safe to say, we don't like to use the single-instance root module pattern. Can it be done well? Sure, but it opens you up to the hard left hook of "bad practices are easy".
You might as well just shoot yourself in the foot at the start instead of waiting for that new team member to do it in 9 months when they need to solve a problem and you’re on vacation and can’t review the PR to stop them.
May your root modules always be multi-instance,
Matt @ Masterpoint
PS Want more on the topic? I wrote a post earlier this year about the difference between multi-instance and single-instance root modules. If you’ve found this newsletter helpful, please forward it to a friend. Or if you want to share on your company slack, here’s the archive of all my newsletters.