Day 70 - Terraform Modules

Day 70 - Terraform Modules

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.

Are Modules and Namespaces same?

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.

File structure for Modules

Below is the file structure of terraform Modules: -

📁 terraform-aws 
    --📄 terraform.tf 
    --📄 provider.tf 
    --📄 main.tf

📁 terraform-aws/modules/my-app 
    --📄 variables.tf 
    --📄 ec2.tf 
    --📄 s3.tf 
    --📄 dynamo.tf
    --📄 output.tf

TASK : Create an AWS infrastructure using Terraform Module

Step 1: Create a terraform.tf file to declare AWS providers required for the system.

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

Step 2: Create a provider.tf file to specify the AWS region required for instance.

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

Step 3: Create a variables.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
}

Step 4: 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}"
   }
}

Step 5: 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}"
}

Step 6: 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"
    }
}

Step 7: 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-0c7217cdde317cfec"
   instance_type = "t2.micro"
   instance_name = "Server"
   bucket_name = "day70-bucket-app-021"
   dynamo_table_name = "day70-table-app-021"
}

module "prd-app"{
   source = "./modules/my-app"
   my_environment = "prd"
   ami = "ami-0c7217cdde317cfec"
   instance_type = "t2.micro"
   instance_name = "Server"
   bucket_name = "day70-bucket-app-021"
   dynamo_table_name = "day70-table-app-021"
}

Step 8: 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
}

Step 9: Once all the file setup is done, now execute the terraform init command.

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

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

Step 12: 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.

Step 13: 2 new s3 bucket is also created for both prd and dev environment.

Step 14: Same like s3 bucket, with 2 new DynamoDB tables is created for both prd and dev environments.

Step 15: Using terraform state list command you can list out all the states of your infrastructure.

Step 16: To view the state of a particular module, use the below command: -

terraform state show <module-name>

Step 17: To destroy the particular state of a particular module we can use

terraform destroy -target <mod>

Step 18: Once you are done with the newly created instance we can use terraform destroy command which will delete the complete infrastructure.

Conclusion

In Conclusion, Terraform modules offer a powerful abstraction for organizing infrastructure as code, promoting reusability, consistency, and scalability. By encapsulating configuration logic into modular units, they enhance maintainability and enable teams to efficiently manage complex cloud environments.

Leveraging modules facilitates collaboration, simplifies deployments, and streamlines infrastructure management processes, ultimately contributing to more robust and manageable infrastructure deployments.

Hope you find it helpful🤞 So I encourage you to try this on your own and let me know in the comment section👇 about your learning experience.✨

👆The information presented above is based on my interpretation. Suggestions are always welcome.😊

~Smriti Sharma✌