Featured image of post πŸ—‚οΈ Organising Terraform Code – module structure

πŸ—‚οΈ Organising Terraform Code – module structure

In this post, I’ll document how I approached organizing Terraform code for managing Auth0 tenants independently of the broader platform infrastructure.

πŸ“ 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:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
πŸ“ org/
β”œβ”€β”€ auth0/
β”‚   β”œβ”€β”€ auth0-dev/
β”‚   β”‚   β”œβ”€β”€ main.tf
β”‚   β”‚   β”œβ”€β”€ variables.tf
β”‚   β”‚   └── terraform.tfstate
β”‚   └── auth0-prod/
β”‚       β”œβ”€β”€ main.tf
β”‚       β”œβ”€β”€ variables.tf
β”‚       └── terraform.tfstate

πŸ“¦ modules/
└── auth0/
    β”œβ”€β”€ auth0-dev/
    β”‚   β”œβ”€β”€ *.tf (config files)
    └── auth0-prod/
        β”œβ”€β”€ *.tf (config files)

βΈ»

🎯 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.

comments powered by Disqus
Built with Hugo
Theme Stack designed by Jimmy