Terraform Modules
# CHAPTER 7
Terraform Modules
1. Introduction
In software engineering, when you write a useful function (like calculating tax), you don't copy and paste that math into every file; you wrap it in a function and "call" it. Terraform utilizes the exact same principle. As your infrastructure grows, maintaining one massivemain.tf file becomes impossible. To achieve true scalability and enforce organizational standards, we package our infrastructure into Modules. In this chapter, we will learn how to create custom modules, how to call them, and how to utilize the massive library of pre-built modules available in the Terraform Registry.
2. Learning Objectives
By the end of this chapter, you will be able to:- Define what a Terraform Module is.
- Understand the difference between the "Root Module" and "Child Modules".
- Architect a reusable Child Module with variables and outputs.
- Call a custom local module from the Root module.
- Pull official, pre-built modules from the Terraform Registry.
3. Beginner-Friendly Explanation
Imagine building a computer.-
The Resources: You buy individual transistors, wires, and silicon chips. You have to solder them together yourself to make a graphics card. (This is writing raw
resourceblocks).
- The Module: You just buy a pre-packaged "NVIDIA Graphics Card." You don't know how the transistors are soldered inside, and you don't care. You just plug it into the motherboard, give it power (Inputs), and get a picture on your screen (Outputs).
A Terraform Module is a pre-packaged block of infrastructure (e.g., a "Complete Secure Network" module) that you can just plug into your code and use immediately.
4. Creating a Module
A module is simply a folder containing Terraform files. Every Terraform configuration you have written so far is technically a module (The "Root Module").To create a reusable "Child Module", you make a new folder (e.g., modules/webserver/).
Inside that folder, you create main.tf, variables.tf, and outputs.tf.
-
The
variables.tfin the module define the arguments the user MUST pass in (likesizeandname).
-
The
main.tfin the module uses those variables to build the resources.
-
The
outputs.tfin the module returns the results (like theserverip).
5. Calling a Module
Back in your Root Module (the top-level folder), you do not use aresource block. You use a module block!
*We just built two completely different servers by calling the same folder twice with different inputs.*
6. Mini Project: Use a Public Registry Module
You don't always have to write modules yourself. The Terraform Registry contains thousands of verified modules written by cloud providers. Let's create an AWS VPC (Network). Building a secure VPC from scratch requires writing 20 differentresource blocks (subnets, gateways, route tables). We will use the official AWS VPC module to do it in 5 lines.
Step-by-Step Architecture Concept:
*Run terraform init (to download the module) and terraform apply. The module creates 20+ resources perfectly configured according to AWS best practices.*
7. Real-World Scenarios
A security team dictated that every AWS S3 bucket in the company must have encryption enabled, public access blocked, and access logging turned on. Developers constantly forgot to add these extra settings when writingresource "awss3bucket" blocks, causing compliance failures.
The DevOps team created a private Terraform Module named secures3bucket. They hardcoded the encryption and security settings inside the module. Then, they banned developers from using the raw resource block. Developers were only allowed to use module "secures3bucket". Instantly, 100% of the company's buckets became secure by default.
8. Best Practices
-
Remote Module Sources: While our example used a local folder (
source = "./modules/"), enterprise modules are usually stored in dedicated GitHub repositories. You can point the source directly to Git:source = "git::https://github.com/my-company/tf-modules.git//web_server?ref=v1.0.0". This allows version control and sharing across the entire company.
9. Security Recommendations
- Audit Third-Party Modules: When using a module from the public Terraform Registry, you are executing someone else's infrastructure code. While "Verified" modules (like those from AWS) are generally safe, unverified community modules could contain malicious configurations (like opening a backdoor port). Always review the module's source code on GitHub before using it in production.
10. Troubleshooting Tips
-
The
terraform initRequirement: Whenever you add amoduleblock to your code, or change thesourcepath, you MUST runterraform initagain. Terraform needs to physically download the module's code into your.terraform/directory before it can runplanorapply.
11. Exercises
-
1.
What is the primary operational advantage of using a Module instead of raw
resourceblocks?
-
2.
Where does Terraform look for the code when you specify
source = "terraform-aws-modules/vpc/aws"?
12. FAQs
Q: Can a module call another module? A: Yes! This is called "Nested Modules." However, you should avoid nesting modules more than 2 levels deep, as the code becomes extremely difficult to read and debug.13. Interview Questions
- Q: Explain the data flow between a Root Module and a Child Module. How does data pass into the Child Module, and how does the Root Module retrieve data back from the Child Module?
- Q: Your security team requires all databases to be encrypted. Explain how you would utilize custom Terraform Modules to enforce this compliance standard across a team of 50 developers.
14. Summary
In Chapter 7, we achieved true Infrastructure as Code maturity. We learned that Modules are the functions of the Terraform world, allowing us to package complex architectures into simple, reusable, and standardized blocks. We explored how to define input contracts (variables.tf) and extract useful data (outputs.tf) from our child modules. By leveraging the Terraform Registry, we demonstrated how to deploy robust, industry-standard architectures like a full AWS VPC in just a few lines of code, saving hours of development time.