> ## Documentation Index
> Fetch the complete documentation index at: https://notes.kodekloud.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Introduction to Modules

> Explains Terraform modules including structure, usage, sources, versioning and benefits for building reusable, consistent, maintainable infrastructure

Welcome to the Introduction to Terraform Modules.

This lesson explains how Terraform modules let you package related infrastructure-as-code into reusable, logical components. Organizing configurations into modules reduces repetition, enforces consistency across environments, and makes it easier to share well‑tested patterns across teams.

We’ll cover core concepts including module structure, usage, sources, and versioning so you can build, consume, and maintain reusable Terraform modules. Let’s dive into why modules are essential for scalable, maintainable infrastructure.

## What is a module?

A module is a container for related Terraform resources that are commonly used together — for example, the resources that make up a subnet, a VPC, or an application stack. Modules are the recommended way to package and reuse configurations.

When you run Terraform, the configuration in the working directory is the root (or parent) module. Any other module called from the root module is a child (reusable) module. Using modules helps encapsulate complexity and standardize patterns.

<Callout icon="lightbulb" color="#1CB2FE">
  The root module is the directory where you run Terraform commands. Child modules live in other directories, remote registries, or version control and are referenced via `module` blocks.
</Callout>

## Benefits of using modules

Using modules delivers several operational and organizational advantages:

* Improved organization: Break large configurations into smaller, easier-to-reason units.
* Easier collaboration: Publish vetted modules to a registry or shared repo so teams consume standardized building blocks.
* Consistent patterns: Centralize naming, tagging, sizing, and security controls in modules to enforce best practices.

<Frame>
  <img src="https://mintcdn.com/kodekloud-c4ac6d9a/HUZ-SFw2Tg4GUikN/images/HashiCorp-Certified-Terraform-Associate-004/Terraform-Modules/Introduction-to-Modules/modules-as-containers-benefits-diagram.jpg?fit=max&auto=format&n=HUZ-SFw2Tg4GUikN&q=85&s=1c03314e576d5f229a42af05382e607c" alt="The image explains modules as containers for related resources, highlighting their benefits: improved organization, easier collaboration, and consistent patterns." width="1920" height="1080" data-path="images/HashiCorp-Certified-Terraform-Associate-004/Terraform-Modules/Introduction-to-Modules/modules-as-containers-benefits-diagram.jpg" />
</Frame>

When platform or security teams review and approve modules, your organization can ensure deployments follow standards without each consumer needing to implement the same checks.

## Modules as building blocks

Instead of placing many resource blocks (TLS certificate, load balancer, message queue, Kubernetes cluster, database, etc.) into a single configuration, define each piece once as a module and reuse it across multiple root modules.

For example:

* A Marketing Application might reference the TLS and Load Balancer modules.
* A GenAI service might reference those plus GPU-backed cluster and specialized queue modules.

Root modules declare only the modules they need and configure them via inputs. This makes code DRY (Don’t Repeat Yourself), easier to test, and simpler to maintain.

<Frame>
  <img src="https://mintcdn.com/kodekloud-c4ac6d9a/HUZ-SFw2Tg4GUikN/images/HashiCorp-Certified-Terraform-Associate-004/Terraform-Modules/Introduction-to-Modules/terraform-building-blocks-modules-diagram.jpg?fit=max&auto=format&n=HUZ-SFw2Tg4GUikN&q=85&s=c415745158b3beec8c88ba293b516b58" alt="The image illustrates Terraform building blocks, showing the connection between modules such as TLS Certificate and Load Balancer and applications like Marketing Application and GenAI Service." width="1920" height="1080" data-path="images/HashiCorp-Certified-Terraform-Associate-004/Terraform-Modules/Introduction-to-Modules/terraform-building-blocks-modules-diagram.jpg" />
</Frame>

## What does a module look like?

A module is simply a directory containing standard Terraform files. The most common layout is:

* `main.tf` — resources and core configuration
* `variables.tf` — input variables the module accepts
* `outputs.tf` — outputs the module exposes to callers
* (optional) `versions.tf` — provider and Terraform version constraints
* (optional) `examples/` — example usage to help consumers

Example filesystem layout:

```text theme={null}
modules/
  tls/
    main.tf
    variables.tf
    outputs.tf
  load_balancer/
    main.tf
    variables.tf
    outputs.tf
```

Common module file types and purpose

| File           | Purpose                                 | Example                                                                     |
| -------------- | --------------------------------------- | --------------------------------------------------------------------------- |
| `main.tf`      | Define resources and composition        | `resource "aws_acm_certificate" "example" { ... }`                          |
| `variables.tf` | Declare input variables and defaults    | `hcl variable "domain_name" { type = string } `                             |
| `outputs.tf`   | Expose values to calling module         | `hcl output "certificate_arn" { value = aws_acm_certificate.example.arn } ` |
| `versions.tf`  | Lock Terraform and provider versions    | `hcl terraform { required_version = ">= 1.0.0" } `                          |
| `examples/`    | Example root module demonstrating usage | `examples/complete/main.tf`                                                 |

Example: calling a local child module from a root module

```hcl theme={null}
module "tls" {
  source = "./modules/tls"

  domain_name = "example.com"
  cert_tags   = {
    environment = "prod"
  }
}
```

Minimal `variables.tf` inside the module:

```hcl theme={null}
variable "domain_name" {
  type        = string
  description = "Domain name for the TLS certificate"
}

variable "cert_tags" {
  type        = map(string)
  description = "Tags to apply to the certificate"
  default     = {}
}
```

Minimal `outputs.tf` inside the module:

```hcl theme={null}
output "certificate_arn" {
  description = "The ARN of the TLS certificate"
  value       = aws_acm_certificate.example.arn
}
```

## Module sources and versioning

Modules can be sourced from several places: local paths, Git repositories, Terraform Registry, or other VCS. Always prefer versioned sources for reproducible builds when pulling remote modules.

Examples of module sources

| Source type    | Example                                                                                             |
| -------------- | --------------------------------------------------------------------------------------------------- |
| Local path     | `source = "./modules/network"`                                                                      |
| Git (with ref) | `source = "git::https://github.com/example-org/terraform-modules.git//modules/postgres?ref=v1.2.0"` |
| Registry       | `source = "app.terraform.io/example-org/mysql/aws"`                                                 |
| Archive URL    | `source = "https://example.com/terraform-modules.tar.gz"`                                           |

When referencing remote modules, pin to a specific tag, branch, or commit using `?ref=` to avoid accidental changes.

## Declaring and using module blocks

To reuse a module, declare a `module` block in your root module and set the `source` and any required inputs. The root module receives outputs from the child module as attributes.

Example with multiple modules:

```hcl theme={null}
module "network" {
  source = "./modules/network"
  vpc_cidr = "10.0.0.0/16"
}

module "db" {
  source = "git::https://github.com/example-org/terraform-modules.git//modules/postgres?ref=v1.2.0"
  db_name      = "appdb"
  instance_tier = "db.t3.medium"
}
```

Best practices for module authorship

* Keep modules focused and single-purpose.
* Use clear, descriptive variable names and document defaults.
* Provide outputs that callers need without exposing internal resource IDs unnecessarily.
* Include examples and tests (e.g., Terratest or Kitchen-Terraform) where feasible.
* Apply provider and Terraform version constraints in `versions.tf`.
* Use semantic versioning and tag releases for remote modules.

## Summary

Modules are the primary mechanism in Terraform for packaging, sharing, and enforcing infrastructure patterns. Use them to:

* Reduce duplication
* Improve maintainability
* Standardize security and operational controls

By organizing infrastructure as reusable modules and versioning them responsibly, teams gain scalability and governance while keeping root modules concise and readable.

## Links and References

* [Terraform Documentation: Modules](https://www.terraform.io/language/modules)
* [Terraform Registry](https://registry.terraform.io/)
* [Terraform CLI: Module Sources](https://www.terraform.io/language/modules/sources)
* [Semantic Versioning](https://semver.org/)

<CardGroup>
  <Card title="Watch Video" icon="video" cta="Learn more" href="https://learn.kodekloud.com/user/courses/hashicorp-certified-terraform-associate-004/module/7a9b9328-bd7d-4cb0-99f2-2ac166f272a7/lesson/d7e308d3-d224-426f-a4a8-019b2f68b4b5" />
</CardGroup>
