Open In App

Modules Block in Terraform

Last Updated : 16 Jul, 2023
Improve
Improve
Like Article
Like
Save
Share
Report

Pre-requisite: Terraform

Users can define and provision infrastructure resources declaratively using the open-source infrastructure as code (IaC) tool known as Terraform. It enables teams to effectively manage their infrastructure across a range of cloud providers and on-premises settings. The capability to generate reusable infrastructure components known as modules is one of the primary characteristics that contribute to Terraform’s power. We will examine the modules block in Terraform and offer examples to show how to use it in this article.

Terraform Modules

A module in Terraform is a group of Terraform configurations that may be used to build and maintain a certain kind of infrastructure resource. It serves as a building block with a certain configuration, set of resources, and logic. The use of modules, which can be thought of as reusable templates, can help to standardize and make infrastructure provisioning more modular.

Defining a Terraform Module

We make a directory containing a collection of Terraform configuration files in order to define a module. The resource definitions are normally contained in main.tf, input variables are defined in variables.tf, and outputs of the module are configured in outputs.tf. To set variable values, we can also use other files like variables.tfvars.

Syntax of the Terraform Modules Block

Within your primary Terraform setup, you can call and instantiate modules using the modules block. The syntax is:

module "module_name" {
source = "path_of_module"
[other_arguments]
}
  • module_name: The user-defined name for the module instance is module_name.
  • source: This identifies the module’s location. A remote module registry (like GitHub or Terraform Registry) or a local file path could both be used.
  • other_arguments: Optional arguments which module can accept as optional arguments.

For example, Let’s say we want to set up and provision EC2 instance using a module:

In a different directory, we first define a module called “ec2_instance” with the following structure:

ec2_instance
├── main.tf
├── variables.tf
└── outputs.tf

The required AWS EC2 resource structure is contained in the main.tf file located in the module directory. The module’s needed input variables, such as instance type and AMI ID, are defined in the variables.tf file. The outputs of the module, including the instance ID, are specified in the outputs.tf file.

Now, we can instantiate this module as follows in our main Terraform configuration file:

provider "aws" {
region = "us-east-2"
}

module "gfg_server" {
source = "./ec2_instance"

instance_type = "t2.micro"
ami_id = "ami-98656754364"
}

output "instance_id" {
value = module.gfg_server.instance_id
}

  • The region is set to “us-east-2” and the provider block specifies the AWS provider.
  • The “gfg_server” module is created by the module block. The module found in the “./ec2_instance” directory is referred to.
  • AMI_id is set to “ami-98656754364” and instance_type is set to “t2.micro” inside the module block. The module will use these settings to provision the EC2 instance.
  • A “instance_id” output variable is defined in the output block. The “gfg_server” module is accessed to obtain the instance_id output variable’s value.

The local file path “./ec2_instance” is used as the module’s source in the example above. Following that, we set the instance_type and ami_id input variables’ values inside the module block. In order to retrieve the output value of the instance_id output variable declared within the module, we lastly use the module.gfg_server.instance_id reference.

Fundamentals of Modules

Calling a Child Modul

Let’s say you have a “vpc” Terraform module that builds a virtual private cloud (VPC) with your cloud provider. You can call this module a child module by using the following syntax to use it in your main Terraform configuration.

module "my_vpc" {
source = "./modules/vpc"

vpc_name = "gfg-vpc"
cidr_block = "10.0.0.0/16"
// etc...
}

In this, the “vpc” module, which is placed in the “./modules/vpc” directory, is called by the module block. Input variables like vpc_name and cidr_block are also provided for configuring the VPC module.

Version

The version attribute can be used to express a module’s or provider’s version constraint. For

Example:

module "gfg_vpc" {
source = "terraform-aws-modules/vpc/aws"
version = "~> 2.0"
// etc ...
}

In this instance, the “terraform-aws-modules/vpc/aws” module repository is being used to source the module. Versions greater than or equal to 2.0 but are less than 3.0 are allowed, as specified in the version attribute.

Meta-arguments

Let’s have a look at the count meta-argument, which enables the creation of many instances of a resource depending on a count value.

resource "aws_instance" "gfg_instances" {
count = 2

ami = "ami-3uir3215678"
instance_type = "t2.micro"
// etc..
}

By repeatedly iterating over the resource block with the count value of 2, Terraform will in this instance construct two AWS EC2 instances.

Accessing Module Output Values

Let’s say you have a module called “app” that generates a DNS name for an application load balancer (ALB) that it creates. You can use the name of the module and the output name in the following format to access this output value in your primary configuration:

module "gfg_app" {
source = "./modules/app"

// etc..
}

resource "aws_route53_record" "app_dns" {
zone_id = "ABC123456"
name = "gfg-app.example.com"
// etc..
records = [module.gfg_app.alb_dns_name]
}

In this illustration, the output value alb_dns_name set in the “app” module is referred to by the module.gfg_app.alb_dns_name. In order to create an AWS Route 53 DNS record, it fetches the ALB’s DNS name.

Transferring Resource State Into Modules

Assume you currently handle an AWS S3 bucket outside of Terraform. You can use the terraform import command in the following way to import its state into Terraform

terraform import aws_s3_bucket.gfg_bucket gfg-created-bucket

With the help of this command, the current S3 bucket is linked to the Terraform resource aws_s3_bucket.gfg_bucket, enabling Terraform to control its settings.

Replacing Resources Within a Module

Let’s say your “security_group” module controls an AWS security group. You may use the Terraform state mv command to swap out the current security group resource by typing the following

terraform state mv aws_security_group.existing sg.new

The current security group resource aws_security_group.existing is moved in this example using the Terraform command state mv to a new address sg. new. With this alternative, you can modify the resource without affecting the module’s other resources.

Benefits of Modules

Using modules in Terraform has various advantages for managing infrastructure, including:

  • Reusability: By encapsulating infrastructure resources and configurations, modules support reusability. They may be easily shared between projects and teams, minimizing effort duplication.
  • Abstraction: Modules encapsulate complicated infrastructure provisioning into straightforward, reusable parts. They give customers the ability to design infrastructure at a more abstract level, which makes it simpler to reason about and maintain.
  • Separation of Concerns: By establishing distinct boundaries between various components of the infrastructure, modules enable the separation of concerns. This enhances teamwork and makes it easier for independent module creation and testing.
  • Maintainability: Updating and maintaining infrastructure configurations is made simpler via modules. Modifications to a module spread to all instances, guaranteeing uniform and standardized deployments.

Conclusion

The modules block makes it possible to create reusable infrastructure components. Modules make the provisioning and maintenance of complicated infrastructure easier by encapsulating infrastructure resources and configurations. Using modules increases the overall maintainability of infrastructure deployments by encouraging reusability, abstraction, and the separation of responsibilities.



Like Article
Suggest improvement
Share your thoughts in the comments

Similar Reads