IaC Monorepo Management — Scale Terraform Across Teams Without Chaos
Your Terraform monorepo started with 10 files and one team. Now it has 500 files, 5 teams, and every <code>terraform plan</code> takes 3 minutes. Changes in the networking module trigger plans for services that did not change. Two teams submit conflicting PRs that both pass plan but fail when applied sequentially. We restructure your IaC monorepo with proper state isolation, selective execution, ownership boundaries, and tooling that makes large-scale Terraform manageable.
Need this done for your project?
We implement, you ship. Async, documented, done in days.
The Monorepo Scaling Problem
Terraform monorepos hit scaling problems around 100-200 resources per state file and 3-5 contributing teams. Symptoms include: slow plan times (minutes instead of seconds), frequent state lock contention, difficulty understanding which files affect which resources, accidental changes to infrastructure owned by other teams, and CI pipelines that run full plans on every PR regardless of what changed.
The root cause is usually a flat directory structure where everything shares one state file. This means every terraform plan evaluates every resource, every apply holds the lock for all resources, and every team's changes interact with every other team's infrastructure. The solution is state isolation — splitting your monorepo into multiple root modules, each with its own state file, while sharing common modules.
The challenge is doing this without disrupting your team's workflow. Moving resources between state files requires careful terraform state mv operations. Changing directory structures breaks CI/CD pipelines and developer muscle memory. We do this migration incrementally, validating each step with zero-change plans.
Our Monorepo Architecture
We restructure the monorepo into a layered directory structure with clear ownership boundaries:
infrastructure/
modules/ # Shared modules, versioned via git tags
vpc/
ecs-service/
rds/
environments/
production/
networking/ # Team: Platform — VPC, subnets, NAT
data/ # Team: Platform — RDS, ElastiCache
services/
api/ # Team: Backend — ECS service for API
web/ # Team: Frontend — ECS service for web app
workers/ # Team: Backend — ECS service for workers
monitoring/ # Team: Platform — Prometheus, Grafana
staging/
... # Same structure, different values
Each leaf directory is a root module with its own state file. The networking directory manages VPC resources. The api directory manages the API service. They reference each other via Terraform remote state data sources or output files — not by sharing state.
CODEOWNERS (GitHub) or CODEOWNERS-equivalent maps directories to teams. Changes in networking/ require Platform team review. Changes in services/api/ require Backend team review. This prevents unauthorized changes and distributes review load.
CI/CD uses change detection to run plan only for affected directories. A PR that changes services/api/ only plans and applies the API service — not the entire infrastructure. We use tools like Terragrunt, Spacelift, or custom scripts to handle dependency ordering when cross-cutting changes are needed (e.g., a networking change that affects all services).
What You Get
A scalable IaC monorepo architecture:
- State isolation — separate state files per infrastructure layer and service
- Directory structure — clear, navigable layout with consistent naming conventions
- Ownership boundaries — CODEOWNERS mapping directories to teams
- Selective execution — CI only plans/applies directories affected by the PR
- Shared modules — versioned, documented modules consumed by all teams
- Dependency management — cross-module references via remote state or output files
- Migration — existing resources moved to new state files without recreation
- Documentation — architecture diagram, team ownership matrix, and contribution guide
Why Anubiz Engineering
Ready to get started?
Skip the research. Tell us what you need, and we'll scope it, implement it, and hand it back — fully documented and production-ready.