π Structure Overview
When working with infrastructure as code, choosing the right Terraform module structure can be crucial for maintainability, scalability, and operational safety. In this post, Iβll document how I approached organizing Terraform code for managing Auth0 tenants independently of the broader platform infrastructure. Hereβs the final structure I implemented under our Terraform monorepo:
|
|
βΈ»
π― The Problem
Previously, our auth0 Terraform configuration lived within the same platform folder as our other microservices. This posed a few issues:
- π Shared root modules meant shared state, leading to potential clashes between dev and prod environments.
- π« Any change or issue in auth0 could block platform deployments.
- π₯ Less isolation increased the blast radius for errors or upgrades.
βΈ»
β The Solution
To reduce risk and improve isolation, I extracted auth0 from the shared platform root module and moved it under its own folder within the org/ structure.
Instead of using a single root module with multiple tfvars for environments (as we do for platform), I opted to create two completely separate root modules: one for auth0-dev and one for auth0-prod.
Why?
- π Auth0 has a distinct lifecycle compared to platform services.
- π‘οΈ Decoupling improves safety β I can upgrade or test the dev tenant without touching production.
- π Separate state files make it easier to manage lifecycle events (e.g., state migrations or imports).
βΈ»
π‘ Key Takeaways
- π Terraform code should be easy to read, even if itβs not perfectly DRY. Stability > cleverness.
- π‘οΈ Organizing infrastructure into isolated root modules with clear boundaries can prevent cross-env interference.
- βοΈ This structure allows more granular CI/CD workflows β you can plan/apply per service or environment.
βΈ»
π References
βΈ»
π This setup has been working well for us so far. It gives clarity, safer deployment boundaries, and the flexibility to scale or refactor as needed.