Terraform Modules

Terraform Modules

Day 70 of 90daysofdevops

ยท

5 min read

What are Terraform Modules

  • Terraform modules are reusable and self-contained collections of Terraform configurations that encapsulate a set of resources and their configurations. A module consists of a collection of .tf and/or .tf.json files kept together in a directory

  • Modules can be created for specific infrastructure patterns, application components, or entire stacks. They promote code reuse, consistency, and maintainability by encapsulating common infrastructure patterns and configurations.

  • Modules can also be called multiple times, either within the same configuration or in separate configurations, allowing resource configurations to be packaged and accelerating development by reducing duplication and promoting reusability.

Different modules of Terraform

Terraform offers different types of modules to enhance infrastructure management:

  1. Provider Modules: Encapsulate cloud provider configurations (e.g., AWS, Azure).

  2. Resource Modules: Represent specific resources or infrastructure patterns (e.g., EC2 instance, VPC).

  3. Application Modules: Focus on deploying and managing application components (e.g., ECS, Lambda).

  4. Composite Modules: Combine lower-level modules into cohesive solutions (e.g., application + network modules).

  5. Utility Modules: Provide generic functionalities or reusable components (e.g., monitoring, security groups).

Difference between Root Module and Child Module

  • The Root Module in Terraform is the main entry point of a Terraform configuration. It is typically represented by the top-level directory containing the main Terraform files.

  • The Root Module defines the infrastructure components, providers, and variables used in the configuration. It may also include references to Child Modules.

  • Child Modules are self-contained modules that encapsulate specific sets of resources and configurations. They can be referenced and used within the Root Module.

  • Child Modules promote code reuse, modularity, and separation of concerns. They enable the organization and reusability of infrastructure code by encapsulating specific functionality or infrastructure patterns, making it easier to manage and maintain complex configurations.

Modules and Namespaces are the same? Justify your answer for both Yes/No

  • No, modules and namespaces are not the same.

  • Modules in Terraform refer to self-contained units of infrastructure code that encapsulate resources and configurations. They promote code reuse, modularity, and organization of infrastructure code. Modules allow for abstraction, reusability, and easier management of complex configurations.

  • While Namespaces provide a way to group and organize related entities, such as classes, functions, or variables, within a codebase. It helps prevent naming conflicts by providing a unique scope for entities within the namespace. Namespace enables logical separation and isolation of code components, improving code organization and readability.

  • On a short note, we can say that modules focus on packaging and reusing code or resources, while namespaces primarily address code organization, isolation, and avoiding naming conflicts within a codebase.

Below is the file structure for modules:

๐Ÿ“ terraform-project 
    --๐Ÿ“„ terraform.tf 
    --๐Ÿ“„ provider.tf 
    --๐Ÿ“„ main.tf

๐Ÿ“ terraform-project/modules/my-app 
    --๐Ÿ“„ variables.tf 
    --๐Ÿ“„ ec2.tf 
    --๐Ÿ“„ s3.tf 
    --๐Ÿ“„ dynamo.tf

Create an AWS infrastructure using Terraform Module

  • Create a variable.tf file and mentioned all the variables here only and provide the type of variable as "string"

      variable "ami" {
             type = string
      }
    
      variable "instance_type"{
          type = string
      }
    
      variable "instance_name"{
          type = string
      }
    
      variable "bucket_name"{
          type = string
      }
    
      variable "dynamo_table_name"{
          type = string
      }
    
      variable "my_environment"{
         type = string
      }
    
  • Create a file ec2.tf and inside it provides all details related to instances like the number of ec2 to be created, AMI Id, instance type and name of the instance using variables.

      resource "aws_instance" "my_instance"{
          count = 2
          ami = var.ami
          instance_type = var.instance_type
          tags = {
               Name = "${var.my_environment}-${var.instance_name}"
         }
      }
    
  • Create a s3.tf file and add details related to the s3 bucket name.

      resource "aws_s3_bucket" "my_bucket"{
           bucket = "${var.my_environment}-${var.bucket_name}"
      }
    
  • Create a dynamo.tf file and add details related to dynamodb like name, billing mode, hash key and attribute using variables.

      resource "aws_dynamodb_table" "my_table"{
           name = "${var.my_environment}-${var.dynamo_table_name}"
           billing_mode = "PAY_PER_REQUEST"
           hash_key = "UserID"
           attribute{
               name = "UserID"
               type = "S"
           }
      }
    
  • In the terraform-project or main directory of the project add terraform.tf for add details of AWS provider.

      terraform {
        required_providers {
          aws = {
            source  = "hashicorp/aws"
            version = "~> 4.0"
          }
        }
      }
    

    provider.tf

      provider "aws"{
         region = "us-east-1"
      }
    
  • Now create a main.tf file and here add all the values of variables that make our project modular.

      module "dev-app"{
         source = "./modules/my-app"
         my_environment = "dev"
         ami = "ami-053b0d53c279acc90"
         instance_type = "t2.micro"
         instance_name = "Server"
         bucket_name = "day70-bucket-my-app1"
         dynamo_table_name = "day70-table-my-app1"
      }
    
      module "prd-app"{
         source = "./modules/my-app"
         my_environment = "prd"
         ami = "ami-053b0d53c279acc90"
         instance_type = "t2.micro"
         instance_name = "Server"
         bucket_name = "day70-bucket-my-app1"
         dynamo_table_name = "day70-table-my-app1"
      }
    
  • To get the ip address of the newly created ec2 instances we can create output.tf and add the following code.

      output "my_ec2_ip"{
        value = aws.instance.my_instance[*].public_ip
      }
    
  • Once all the file setup is done, now execute the terraform init command.

  • Once all the prerequisite plugins is satisfied, execute the terraform plan commands to check as our infrastructure met the conditions that we are provided.

  • Once terraform plan is successfully executed, now execute the terraform apply command to create our complete infrastructure.

  • As the process is successfully completed, we can see 4 new EC2 instances out of which 2 for the prd environment and 2 for the dev environment.

  • 2 new s3 bucket is also created for both prd and dev environment.

  • Same like s3 bucket, with 2 new Dynamodb tables is created for both prd and dev environments.

  • Using terraform state list command you can list out all the states of your infrastructure.

  • To view the state of a particular module we can use

       terraform state show <module-name>
    

  • To destroy the particular state of a particular module we can use

      terraform destroy -target <mod>
    


Thank You,

I want to express my deepest gratitude to each and every one of you who has taken the time to read, engage, and support my journey.

Feel free to reach out to me if any corrections or add-ons are required on blogs. Your feedback is always welcome & appreciated.

~ Abhisek Moharana ๐Ÿ™‚

ย