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.

Licensed under CC BY-NC-SA 4.0
Last updated on Sep 19, 2025 16:48 +0100
comments powered by Disqus
Built with Hugo
Theme Stack designed by Jimmy