← Back to hometerraform-modules

Understanding Terraform Modules

← All writing

Terraform is a powerful tool for managing cloud infrastructure in a declarative way. As you work with Terraform, you’ll notice that your configurations can quickly grow large and complex. This is where Terraform modules come in. In this article, we’ll dive into the concept of modules in Terraform, why they are important, and how to use them effectively. We’ll also walk through a complete example using an EC2 instance module to demonstrate how everything fits together.

What Are Terraform Modules?

A module in Terraform is a container for multiple resources that are used together. A module allows you to group resources that accomplish a specific task or set of related tasks, making it easier to reuse and manage your infrastructure. With modules, you can create a clean, reusable, and more manageable codebase.

Modules are particularly useful for:

Reusability: You can define a set of resources once and use them in different projects or environments.

Organization: By grouping related resources together, your infrastructure becomes easier to navigate and understand.

Separation of concerns: Modules allow you to abstract complex configurations into simpler, manageable pieces.

Why Use Modules?

Without modules, Terraform configurations could get messy as you add more resources. As your infrastructure grows, it becomes harder to manage, debug, and reuse. By breaking down your infrastructure into smaller, more manageable modules, you improve:

  • Maintainability: You can modify and upgrade a module without affecting other parts of your configuration.
  • Collaboration: Teams can work on separate modules simultaneously, speeding up development.
  • Modularity: Modules allow you to structure your code in a way that can be used by different teams, projects, or even public Terraform modules.

GitHub Repository

You can find all the code examples used in this guide in my GitHub repository:

🔗 GitHub Repo

Structure of a Terraform Project with Modules

To illustrate how modules are structured and used, let’s look at a real-world example. We will build a simple project that uses Terraform modules to launch an EC2 instance on AWS.

Project Structure

my-terraform-project/
├── main.tf
├── modules/
│ └── ec2-instance/
│ ├── main.tf
│ ├── output.tf
│ ├── terraform.tfvars
│ ├── variables.tf

Here’s what each file does:

main.tf (Root module): This file is where you define your provider (in this case, AWS) and where you call other modules (such as ec2-instance).

modules/ec2-instance/main.tf: The module that defines the AWS EC2 instance resource.

modules/ec2-instance/output.tf: Outputs for the EC2 instance module, such as the public IP address.

modules/ec2-instance/variables.tf: This file contains the variable declarations used by the module.

modules/ec2-instance/terraform.tfvars: This file defines the values for the variables, such as the AMI and instance type.

1. Root Module Configuration (main.tf)

This file is the entry point for the project. It contains the provider configuration and module calls.

provider "aws" {
region = "eu-north-1"
}

module "ec2_instance" {
source = "./modules/ec2-instance"
ami_value = "ami-02db68a01488594c5"
instance_type_value = "t3.micro"
}

provider “aws”: This block specifies the provider for AWS. The region is set to eu-north-1, meaning all AWS resources will be created in the North Europe region.

module “ec2_instance”: This block calls the ec2-instance module located in the modules/ec2-instance directory. We pass two variables: ami_value and instance_type_value to the module.

2. Module Configuration (modules/ec2-instance/main.tf)

This is the core of our EC2 instance module. It defines the actual EC2 instance resource.

provider "aws" {
region = "eu-north-1"
}

resource "aws_instance" "example" {
ami = var.ami_value
instance_type = var.instance_type_value
tags = {
Name = "modules-example"
}
}

provider “aws”: This provider block is repeated within the module to ensure the resources inside the module use the correct AWS region.

resource “aws_instance” “example”: This resource block creates an EC2 instance. The AMI and instance type are provided as variables (ami_value and instance_type_value).

3. Output Configuration (modules/ec2-instance/output.tf)

This file defines what output values you want to display after applying the Terraform configuration.

output "public_ip_address" {
value = aws_instance.example.public_ip
}

output “public_ip_address”: This outputs the public IP address of the EC2 instance once it’s created.

4. Variables Declaration (modules/ec2-instance/variables.tf)

This file declares the variables used in the EC2 instance module. These variables can be passed values when calling the module.

variable "ami_value" {
description = "ami value of the EC2 instance"
}

variable "instance_type_value" {
description = "type of the EC2 instance"
}

variable “ami_value”: This variable is used to pass the AMI ID for the EC2 instance.

variable “instance_type_value”: This variable is used to pass the instance type, such as t3.micro.

5. Variables Values (modules/ec2-instance/terraform.tfvars)

This file defines the values for the variables declared in the variables.tf file.

ami_value          = "ami-02db68a01488594c5"
instance_type_value = "t3.micro"

ami_value: This is the value of the Amazon Machine Image (AMI) that will be used to launch the EC2 instance.

instance_type_value: This specifies the type of EC2 instance, such as t3.micro.

6. modules.json and .tfstate Files

modules.json: This file is automatically created by Terraform to track the sources of all modules used in the project. It maps the ec2_instance module to its source, i.e., ./modules/ec2-instance.

• .tfstate: This file is generated when you run terraform apply. It stores the state of your infrastructure, including the EC2 instance that was created. It helps Terraform track resources and manage them effectively.

Running Terraform

  1. Initialize the Project: To get started, initialize the Terraform project using the following command:
terraform init

2. Plan the Changes: Once the initialization is complete, you can preview the changes Terraform will make:

terraform plan

3. Apply the Changes: Finally, apply the changes to create the EC2 instance:

terraform apply

After applying, Terraform will create the EC2 instance based on the configuration in the module. You can view the public IP address of the instance as defined in the output.tf file.

Conclusion

Terraform modules are an essential feature for managing large-scale infrastructure. They allow you to structure your code efficiently, making it reusable and easier to maintain. By creating a module for the EC2 instance, we have abstracted the details into a separate component that can be reused and shared across multiple projects.

In this tutorial, we’ve walked through:

• The structure of a Terraform project with modules.

• How to configure a module and call it from the root configuration.

• How to define variables, outputs, and resource configurations within the module.

With this knowledge, you can start building more complex, reusable Terraform modules to manage your infrastructure more effectively.

🚀 Let’s Connect!

If you found this guide helpful, follow me for more DevOps and Cloud Engineering content:

🔗 GitHubgithub.com/Dhanika-Kumarasiri

🔗 Mediummedium.com/@dhanika-kumarasiri

Have questions? Drop them in the comments! Let’s automate AWS the smart way! 🚀

Originally published on Medium.

Read on Medium