Terraform - Modules & Demos
Tags: terraform, modules, iac, registry
Published: 2024-03-20 11:11:48

**Use case why we using Terraform Modules :**

We do repeat multiple times various terraform resources for multiple projects, create once and reuse it when ever required 

**Understanding the DRY principle**
In software engineering, Don't repeat yourself (DRY) is a principle of software development aimed at reducing repetition of software patterns.


**Sample EC2 Resource**

```
resource "aws_instance" "myweb" {
     ami = "ami-bf5540df"
    instance_type = "t2.micro"
  }
```
Instead of repeating a resource block multiple times, we can make use of a centralized structure.

**Centralized Structure:**
We can centralize the terraform resources and can call out from TF files whenever required. So we are going to use Terraform modules for this approach.


**Modules** : Understanding the DRY principle
In software engineering, Don't repeat yourself (DRY) is a principle of software development aimed at reducing repetition of software patterns.

- A module is a container for multiple resources that are used together.
- Every Terraform configuration has at least one module, known as its root module, which consists of the resources defined in the .tf files in the main working directory.
- A module can call other modules, which lets you include the child module's resources into the configuration in a concise way. Modules can also be called multiple times, either within the same configuration or in separate configurations, allowing resource configurations to be packaged and re-used.


**Calling a Child Module**

- To call a module means to include the contents of that module into the configuration with specific values for its input variables. 
- Modules are called from within other modules using module blocks

```
module "CT-Server"{
    source =   "./Modules/CT-Server"
    instance_type = "t2.nano"
    ami_id = "ami-bf5540df"    # ami id changes based on the region
}
```

- A module that includes a module block like this is the calling module of the child module.
- The label immediately after the module keyword is a local name (CT-Server is the local name), which the calling module can use to refer to this instance of the module.
- Within the block body (between { and }) are the arguments for the module. Module calls use the following kinds of arguments:

  - The source argument is mandatory for all modules.
  - The version argument is recommended for modules from a registry.
  - Terraform defines a few other meta-arguments that can be used with all modules, including for_each and depends_on.

**Version** : Use the version argument in the module block to specify versions

```
module "consul" {
  source  = "hashicorp/consul/aws"
  version = "0.0.5"

  servers = 3
}

```
**Meta-arguments**
Along with source and version, Terraform defines a few more optional meta-arguments that have special meaning across all modules
- count
- for_each
- providers
- depends_on

**Accessing Module Output Values** : The resources defined in a module are encapsulated, so the calling module cannot access their attributes directly. However, the child module can declare output values to selectively export certain values to be accessed by the calling module.

```
resource "aws_elb" "example" {
  # ...

  instances = module.servers.instance_ids
}

```
**References:**
- https://developer.hashicorp.com/terraform/language/modules
- https://developer.hashicorp.com/terraform/tutorials/modules?utm_source=WEBSITE&utm_medium=WEB_IO&utm_offer=ARTICLE_PAGE&utm_content=DOCS

**Terraform Registry :**

The terraform registry is a repository of modules written by the terraform community.
The terraform can help you get started with Terraform more quickly. 

https://registry.terraform.io/browse/modules 

**Example:** Creating an AWS EC2 Module and trying to call the terraform module.

My folder structure and files looks like this

- TerraformTraining  ( Base folder)
      Modules  (sub folder)
        - CT-Server (sub folder)
          - main.tf
          - variable.tf
      main.tf
      provider.tf


1.Create a folder  TerraformTraining as Base folder and create a subfolder Modules inside TerraformTraining folder then create one more folder **CT-Server** under Modules folder.
2.Create a file main.tf and place the content below

```
resource "aws_instance" "ec2-training" {
    ami = var.ami_id
    instance_type = var.instance_type
}

```


3.Create a file variable.tf and place the content below
 

```
variable "ami_id"{
   type = string
   default = ""
}

variable "instance_type"{
  type = string
  default = "t2.micro"
}

```
4.Go back to the base folder TerraformTraining and create a file main.tf and copy the below mentioned code

```

data "aws_ami" "app_ami" {
   most_recent =true
   owners = ["amazon"]
    filter{
     name = "name"
     values = ["amzn2-ami-hvm*"]
   }
}

## Creating EC2 using Terraform module
module "CT-Server"{
    source =   "./Modules/CT-Server"
    instance_type = "t2.nano"
    ami_id = data.aws_ami.app_ami.id
}


```
  
5.Go back to the base folder TerraformTraining and create a file provider.tf and copy the below mentioned code

```
provider "aws" {
  region = "eu-west-1"
}

```

Note : Already i have configured aws credentials using aws configure

Conclusion : Discussed about terraform modules, create your own terraform modules and use it or use terraform modules from terraform registry.
💬 If you enjoyed reading this blog post and found it informative, please take a moment to share your thoughts by leaving a review and liking it 😀 and follow me in [linkedin](https://www.linkedin.com/in/srinivasuluparanduru)