0
0
Terraformcloud~15 mins

Module structure and conventions in Terraform - Deep Dive

Choose your learning style9 modes available
Overview - Module structure and conventions
What is it?
A Terraform module is a folder with files that define infrastructure resources and configurations. It groups related resources so you can reuse and organize your infrastructure code easily. Modules have a standard structure with specific files for inputs, outputs, and main configuration. This helps teams build consistent and manageable infrastructure setups.
Why it matters
Without modules, infrastructure code becomes messy and repetitive, making it hard to maintain or update. Modules solve this by letting you write code once and reuse it many times, saving time and reducing mistakes. They also help teams share best practices and keep infrastructure reliable and consistent.
Where it fits
Before learning modules, you should understand basic Terraform concepts like resources, variables, and outputs. After modules, you can explore advanced topics like module composition, versioning, and publishing modules to registries.
Mental Model
Core Idea
A Terraform module is like a reusable blueprint that packages infrastructure code into a neat, shareable box with clear inputs and outputs.
Think of it like...
Think of a module like a recipe card in a cookbook. The recipe lists ingredients (inputs), steps to cook (configuration), and the final dish you get (outputs). You can use the same recipe many times to make consistent meals.
┌─────────────────────────────┐
│       Terraform Module       │
├─────────────┬───────────────┤
│ Inputs      │ Variables     │
├─────────────┼───────────────┤
│ Configuration │ Resources   │
├─────────────┼───────────────┤
│ Outputs     │ Outputs       │
└─────────────┴───────────────┘
Build-Up - 7 Steps
1
FoundationWhat is a Terraform Module
🤔
Concept: Introduce the basic idea of a module as a container for infrastructure code.
A Terraform module is a folder with Terraform files that define resources and configurations. It can be as simple as a single file or a set of files working together. Modules help organize code and make it reusable.
Result
You understand that modules group infrastructure code into reusable units.
Knowing that modules are just folders with code helps remove the mystery and shows how easy it is to start using them.
2
FoundationStandard Module File Structure
🤔
Concept: Learn the common files and their roles inside a module folder.
A typical module folder contains: - main.tf: defines resources - variables.tf: declares inputs - outputs.tf: declares outputs - README.md: explains usage This structure is a convention that helps others understand and use your module.
Result
You can recognize and create a module folder with the right files.
Following a standard structure makes modules easier to read, share, and maintain.
3
IntermediateUsing Variables for Module Inputs
🤔Before reading on: do you think module inputs can be hardcoded inside the module or must always be variables? Commit to your answer.
Concept: Modules use variables to accept input values from the user or calling code.
Variables.tf defines inputs with types and optional defaults. When you call a module, you provide values for these variables. This makes modules flexible and reusable in different situations.
Result
You can customize module behavior by passing different input values.
Understanding variables as module inputs unlocks the power of reusability and customization.
4
IntermediateDefining Outputs for Module Results
🤔Before reading on: do you think module outputs are optional or required? Commit to your answer.
Concept: Modules can expose outputs to share information back to the caller.
Outputs.tf declares outputs that return values like resource IDs or IP addresses. These outputs let other parts of your Terraform code use information created inside the module.
Result
You can access important data from modules to connect resources together.
Knowing how outputs work helps you build complex infrastructure by linking modules.
5
IntermediateCalling Modules in Root Configuration
🤔Before reading on: do you think modules are called by copying their code or by referencing their folder? Commit to your answer.
Concept: Modules are used by referencing their folder or source in your main Terraform files.
In your root configuration, you use the 'module' block with a 'source' pointing to the module folder or registry. You then pass variables and can read outputs. This keeps your main code clean and organized.
Result
You can include and reuse modules in your Terraform projects.
Understanding module calls separates infrastructure logic and promotes clean code organization.
6
AdvancedModule Versioning and Registry Usage
🤔Before reading on: do you think modules can be versioned and shared publicly? Commit to your answer.
Concept: Modules can be published to registries and versioned for reuse and sharing.
Terraform Registry lets you publish modules with version tags. You can reference specific versions in your code to ensure stability. This supports collaboration and reuse across teams and projects.
Result
You can use and share stable module versions safely.
Knowing about versioning and registries helps manage module lifecycle and avoid breaking changes.
7
ExpertAdvanced Module Composition and Nested Modules
🤔Before reading on: do you think modules can call other modules inside them? Commit to your answer.
Concept: Modules can include other modules to build complex infrastructure hierarchies.
A module can call submodules inside its folder structure. This lets you break down large infrastructure into smaller, manageable pieces. Careful input/output design is needed to keep interfaces clean.
Result
You can build scalable and maintainable infrastructure with nested modules.
Understanding nested modules reveals how large systems stay organized and flexible in production.
Under the Hood
Terraform modules are folders with configuration files that Terraform reads and processes as a unit. When you run Terraform, it loads module files, evaluates variables, creates resources, and tracks outputs. Modules isolate resource definitions and variables, allowing Terraform to manage dependencies and state cleanly. Internally, Terraform treats modules as separate namespaces to avoid conflicts.
Why designed this way?
Modules were designed to promote code reuse and organization in infrastructure as code. Early Terraform projects became hard to maintain without modularity. The folder-based approach was chosen for simplicity and compatibility with existing file systems. Using variables and outputs as interfaces keeps modules flexible and composable.
Root Configuration
    │
    ▼
┌─────────────────────┐
│   Module Folder     │
│ ┌───────────────┐  │
│ │ variables.tf  │  │
│ │ main.tf       │  │
│ │ outputs.tf    │  │
│ └───────────────┘  │
└─────────────────────┘
    │
    ▼
Terraform Engine
    │
    ▼
Resource Creation and State Management
Myth Busters - 4 Common Misconceptions
Quick: Do you think a module must have all three files: variables.tf, main.tf, and outputs.tf? Commit to yes or no.
Common Belief:A module must always have variables.tf, main.tf, and outputs.tf files to work properly.
Tap to reveal reality
Reality:Modules can have only main.tf and still work; variables and outputs files are optional depending on needs.
Why it matters:Believing all files are mandatory can lead to unnecessary complexity or confusion when creating simple modules.
Quick: Do you think module inputs can be changed inside the module after passing them? Commit to yes or no.
Common Belief:Module input variables can be modified inside the module code after being passed in.
Tap to reveal reality
Reality:Input variables are read-only inside modules; you cannot change their values once passed.
Why it matters:Trying to modify inputs inside modules causes errors and breaks the immutability principle, leading to bugs.
Quick: Do you think modules copy their code into the root configuration when called? Commit to yes or no.
Common Belief:Calling a module copies its code into the root configuration as if pasted there.
Tap to reveal reality
Reality:Terraform treats modules as separate namespaces and does not copy code; it references them logically.
Why it matters:Misunderstanding this can cause confusion about variable scope and resource naming conflicts.
Quick: Do you think nested modules are discouraged or unsupported? Commit to yes or no.
Common Belief:Using modules inside other modules (nested modules) is discouraged or unsupported.
Tap to reveal reality
Reality:Nested modules are fully supported and commonly used to organize complex infrastructure.
Why it matters:Avoiding nested modules limits scalability and maintainability of infrastructure code.
Expert Zone
1
Modules should have minimal and clear interfaces; exposing too many variables or outputs makes them hard to use and maintain.
2
Using locals inside modules can simplify complex expressions without exposing unnecessary variables.
3
Careful naming conventions inside modules prevent resource name collisions when modules are used multiple times.
When NOT to use
Avoid modules for very small or one-off resources where reuse is unlikely; simple inline resource definitions are clearer. Also, avoid deep nesting of modules beyond 2-3 levels to prevent complexity. Alternatives include using workspaces or separate Terraform projects.
Production Patterns
In production, teams use versioned modules stored in private registries or repositories. Modules are tested independently and composed to build environments like dev, staging, and prod. Common patterns include base modules for networking, compute, and security, combined via root modules.
Connections
Software Functions
Modules are like functions that take inputs and return outputs.
Understanding modules as functions helps grasp their purpose: reuse, abstraction, and clear interfaces.
Object-Oriented Programming (OOP)
Modules encapsulate resources like classes encapsulate data and methods.
Seeing modules as encapsulation units clarifies why they isolate variables and outputs to manage complexity.
Manufacturing Assembly Lines
Modules are like assembly stations that build parts before final assembly.
This connection shows how breaking infrastructure into modules improves efficiency and quality control.
Common Pitfalls
#1Hardcoding values inside modules instead of using variables.
Wrong approach:resource "aws_instance" "example" { ami = "ami-123456" instance_type = "t2.micro" }
Correct approach:variable "ami" { type = string } resource "aws_instance" "example" { ami = var.ami instance_type = "t2.micro" }
Root cause:Not understanding that variables make modules reusable and flexible.
#2Not defining outputs to expose important resource attributes.
Wrong approach:resource "aws_vpc" "main" { cidr_block = "10.0.0.0/16" } # No outputs defined
Correct approach:resource "aws_vpc" "main" { cidr_block = "10.0.0.0/16" } output "vpc_id" { value = aws_vpc.main.id }
Root cause:Missing outputs limits module usefulness and integration.
#3Calling modules with incorrect source paths or missing required variables.
Wrong approach:module "network" { source = "./wrong_path" cidr_block = "10.0.0.0/16" }
Correct approach:module "network" { source = "./modules/network" cidr_block = "10.0.0.0/16" }
Root cause:Not verifying module paths or variable requirements causes errors during Terraform runs.
Key Takeaways
Terraform modules package infrastructure code into reusable, organized units with clear inputs and outputs.
Following standard file conventions like main.tf, variables.tf, and outputs.tf makes modules easy to understand and share.
Variables allow modules to accept customizable inputs, while outputs expose useful information to other code.
Modules are called by referencing their source, keeping root configurations clean and promoting reuse.
Advanced use includes versioning, registries, and nested modules to build scalable and maintainable infrastructure.