Learn how to create, organize, and use modules to build reusable, maintainable Terraform configurations.

What Will You Learn? #

Modules are the main way to organize and reuse Terraform configurations. Good modules reduce duplication, increase consistency, and speed up development. This section covers all aspects of modules, from basic to advanced.

Articles in This Section #

ArticleMain Topic
What is a Module?The concept of modules, why they’re needed, and when to create them
Root vs Child ModuleThe difference between the main (root) module and called (child) modules
StructureOrganized module file and folder structure
Interface DesignDesigning clean, intuitive module inputs/outputs
RegistryUsing and publishing modules to the Terraform Registry
VersioningVersioning strategies for stable, backward-compatible modules

Module Architecture #

flowchart TD
    subgraph Root["Root Module (Main)"]
        MAIN["main.tf<br/>Calls child modules"]
        VARS["variables.tf<br/>Input parameters"]
        OUT["outputs.tf<br/>Return values"]
    end

    subgraph Child["Child Modules"]
        VPC_MOD["modules/vpc/<br/>VPC + Subnets"]
        EC2_MOD["modules/ec2/<br/>Instances"]
        RDS_MOD["modules/rds/<br/>Database"]
    end

    subgraph Registry["Terraform Registry"]
        PUB["Public Modules<br/>terraform-aws-modules/*"]
        PRIV["Private Modules<br/>Company Registry"]
    end

    MAIN --> VPC_MOD
    MAIN --> EC2_MOD
    MAIN --> RDS_MOD
    VPC_MOD -.-> PUB
    EC2_MOD -.-> PRIV

    style Root fill:#e3f2fd
    style Child fill:#e8f5e9
    style Registry fill:#fff3e0

Module Reusability #

flowchart LR
    subgraph Shared["Shared Module: vpc/"]
        VPC["VPC Module<br/>Reusable"]
    end

    subgraph Envs["Environments"]
        DEV["Dev<br/>CIDR: 10.0.1.0/24"]
        STG["Staging<br/>CIDR: 10.0.2.0/24"]
        PROD["Production<br/>CIDR: 10.0.3.0/24"]
    end

    VPC --> DEV
    VPC --> STG
    VPC --> PROD

    style Shared fill:#e3f2fd
    style Envs fill:#e8f5e9

Interface Design Best Practice #

# ✅ Clean interface: minimal required, sensible defaults
variable "vpc_cidr" {
  type        = string
  description = "CIDR block for VPC"
  # No default = required
}

variable "enable_nat_gateway" {
  type        = bool
  description = "Create NAT Gateway"
  default     = true  # Sensible default
}

output "vpc_id" {
  value       = aws_vpc.main.id
  description = "ID of the created VPC"
}

A good module is a long-term investment. Continue to Environment to learn how to use modules across different environments.

About | Author | Content Scope | Editorial Policy | Privacy Policy | Disclaimer | Contact