Day 57: #TerraWeekChallenge

Day 57: #TerraWeekChallenge

Day 5: Terraform Modules

Task 1:

  • What are modules in Terraform and why do we need modules in Terraform?

A module is a container for multiple resources that are used together. Modules can be used to create lightweight abstractions, so that you can describe your infrastructure in terms of its architecture, rather than directly in terms of physical objects.

A Terraform module is very simple: any set of Terraform configuration files in a folder is a module.

There are different types of Terraform Modules

  1. Root Module

  2. Child Module

  3. Published Modules

  • What are the benefits of using modules in Terraform?

  1. Code Reduction

By using modules, you can significantly reduce the amount of code you need to write and maintain. Rather than repeating the same code, you can create a module and reference it multiple times, passing different parameters.

  1. Consistency

Modules help ensure consistency across your infrastructure. By standardizing configurations, you can mitigate the risk of configuration drift and ensure that all your environments are set up consistently.

  1. Simplified Management

Modules encapsulate complex components into a single unit, simplifying the process of managing your infrastructure. Even with complex, multi-layer architectures, modules can help to keep your configurations tidy and manageable.


Task 2:

  • Create/Define a module in Terraform to encapsulate reusable infrastructure configuration in a modular and scalable manner. For e.g. EC2 instance in AWS, Resource Group in Azure, Cloud Storage bucket in GCP.

We will create 3 Terraform configuration files just like in the previous blogs:

  1. variables.tf

  2. ec.tf

  3. main.tf

#variables.tf

variable "instance_name" {
  description = "Name of the EC2 instance"
  type        = string
}

variable "instance_type" {
  description = "Type of EC2 instance"
  type        = string
}

variable "ami_id" {
  description = "AMI ID for the EC2 instance"
  type        = string
}

variable "aws_region" {
  description = "AWS region for the resources"
  type        = string
  default     = "us-east-1"
}
#ec2.tf
terraform {
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 3.0"
    }
  }
}

provider "aws" {
  region = var.aws_region
}

resource "aws_instance" "ec2_instance" {
  ami           = var.ami_id
  instance_type = var.instance_type
  tags = {
    Name = var.instance_name
  }
}
#main.tf

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

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

module "aws_ec2" {
  source         = "./path/to/aws_ec2_instance/module/directory"
  instance_name  = "my-instance"
  instance_type  = "t2.micro"
  ami_id         = "ami-0123456789"
  aws_region     = "us-west-2"
}
  1. Initialize: We will first initialize to scan the .tf files in the current directory
terraform init
  1. Plan Execution: To preview the changes that Terraform will make, you can run the below command:
terraform plan
  1. Apply: We execute the files and automation will take place using the apply command.
terraform apply

Task 3:

  • Modular composition

Module composition refers to the practice of combining multiple reusable modules to create a more complex infrastructure configuration.

It allows you to build larger and more sophisticated infrastructure deployments by leveraging the modular nature of Terraform.

It follows a hierarchical structure where a module can include other modules as its building blocks. The advantages are code reusability, maintainability, and scalability.

The step involves using the module block in your Terraform configuration files to instantiate and configure modules. You can pass input variables to the modules and use output values from one module as input to another.

Below is an example of Modular composition:

#Module-1
hclCopy codemodule "vpc" {   #defines a virtual private cloud
  source = "./modules/vpc"
  cidr_block = "10.0.0.0/16"
}

#Module-2
module "app_server" {   #provisions an application server
  source = "./modules/app_server"
  subnet_id = module.vpc.subnet_id   #this variable is derived from VPC module
  instance_type = "t2.micro"
}

#Module-3
module "database" {   #creates a database instance
  source = "./modules/database"
  subnet_id = module.vpc.subnet_id   #this variable is derived from VPC module
}
  • Module versioning

Module versioning is a practice of assigning specific versions to modules to ensure consistency and stability in infrastructure deployments.

When using modules in Terraform, you can specify the version of a module you want to use, allowing you to control which version of the module is used in your infrastructure configuration.

Module versions can be managed using Git or Terraform Registry.

Below is an example of Modular Versioning:

# mymodule is sourced from Git repot
# with version=v1.2.0

hclCopy codemodule "mymodule" {
  source  = "git::https://github.com/mymodule/repo.git?ref=v1.2.0"
}

Task 4:

  • What are the ways to lock Terraform module versions? Explain with code snippets.

There are many ways to lock Terraform module versions to ensure that the same module version is reused again and again across different deployments or team members. Here are the common methods:

  1. Explicit Version Constraint: You can specify an explicit version constraint in your Terraform configuration files.

     # The module version is v1.2.0 
     hclCopy codemodule "mymodule" {
        source  = "git::https://github.com/mymodule/repo.git?ref=v1.2.0"
      }
    
  2. Terraform Configuration Lock File: Terraform can generate a lock file, often named terraform.lock.hcl or terraform.tf.lock.hcl, which captures the exact versions of all modules and providers used in your configuration. This file can be committed to version control, allowing you to recreate the exact infrastructure state with the specified module versions. You can generate the lock file using the "terraform init" command.

  3. Module Registry: If you're using a module registry service like the Terraform Registry, you can specify the module version directly in the module source.

      hclCopy codemodule "example" {
        source  = "registry.example.com/example/repo/aws"
        version = "1.2.0" # The module version is 1.2.0
      }
    
  4. Private Module Registries: If you're using a private module registry, you can set up access controls and permissions to manage module versions and restrict access to specific versions.

Using these mechanisms, you can ensure that the same version of a module is consistently used, reducing the chances of unexpected changes or compatibility issues in your infrastructure deployments.


Hope you like my post. Don't forget to like, comment, and share.