Day 5: Terraform module

Day 5: Terraform module

ยท

9 min read

Terraform, modules are a way to encapsulate and organize infrastructure code into reusable components. They serve several important purposes and are used to address various challenges in infrastructure as code (IaC) development.

Task 1:

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

Modules in Terraform allow you to encapsulate reusable infrastructure configurations into a modular and scalable format. They enable you to organize your codebase, promote code reuse, and abstract away complexities. Modules act as self-contained components that represent a set of resources and their associated configurations.

Why do we need modules in Terraform?

  1. Reusability:
    Modules allow you to define and configure infrastructure resources once and reuse them across different projects or environments. This eliminates the need to rewrite or duplicate code, saving time and effort.

  2. Abstraction:
    Modules abstract away the implementation details, enabling you to focus on the higher-level aspects of your infrastructure. They provide a simplified interface for consuming the module, hiding the underlying complexity.

  3. Scalability:
    By encapsulating infrastructure configurations into modules, you can easily scale your deployments without sacrificing maintainability. Modules can be reused and composed to create complex infrastructures.

  4. Standardization:
    Modules promote consistency by enforcing best practices, naming conventions, and configuration standards across deployments. They provide a standardized way to provision resources, ensuring uniformity and reducing the chance of errors.

  5. Collaboration:
    Modules facilitate collaboration by providing a clear separation of concerns, allowing multiple teams to work concurrently on different modules. Teams can develop and maintain modules independently, promoting modular development and reducing dependencies.

  • What are the benefits of using modules in Terraform?

Modules in Terraform serve several important purposes:

  1. Modularity and Organization: Modules allow you to break down your infrastructure code into smaller, self-contained components. This modularity makes it easier to organize your codebase, as you can have separate modules for different parts of your infrastructure.

  2. Reusability: Once you've defined a module, you can reuse it across multiple projects or environments. This reduces duplication of code and promotes consistency, as you're using the same configuration logic in multiple places.

  3. Abstraction: Modules provide an abstraction layer that hides the implementation details of the resources they manage. Users of a module interact with it using input variables and outputs, without needing to understand all the underlying configuration details.

  4. Parameterization: Modules can accept input variables, allowing you to customize the behavior of the module when you use it. This parameterization makes modules flexible and adaptable to different use cases within your infrastructure.

  5. Encapsulation: Modules encapsulate configuration and logic related to a specific resource or service. This isolation makes it easier to understand and manage your infrastructure code because you can focus on one module's details at a time without getting overwhelmed by the entire configuration.

  6. Versioning: You can version modules independently of your main configuration. This is crucial when multiple teams or projects are using the same module, as it ensures that changes to a module don't inadvertently break other parts of your infrastructure.

  7. Testing and Validation: Modules can be tested independently, simplifying the process of ensuring that individual components of your infrastructure are configured correctly. You can perform unit testing and validation for each module before using them in larger configurations.

  8. Documentation: Modules can include documentation, either as comments within the module's code or in dedicated README files. This documentation helps users understand how to use the module, what input variables are available, and any specific considerations when using the module.

  9. Scalability: As your infrastructure grows, modules make it easier to scale by adding or modifying resources in a consistent and organized manner. You can extend your infrastructure by adding more instances of the same module.

  10. Collaboration: Modules enable collaboration between teams or individuals responsible for different parts of an infrastructure project. Each team can work on and maintain their modules independently, making it easier to manage large, complex projects.

  11. Code Quality and Maintainability: With well-defined modules, your codebase becomes more maintainable and less error-prone. Modules promote best practices, code consistency, and code quality.

  12. Security and Compliance: Modules can be designed to adhere to security and compliance standards, ensuring that resources are provisioned in a secure and compliant manner.

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.

Create all the files

dynamodb.tf variable.tf ec2.tf providers.tf s3.tf terraform.tf variables.tf

#terraform.tf
terraform {
         required_providers {
         aws = {
                 source = "hashicorp/aws"
                 version = "~> 5.0"
                 }
         }
 }
#providers.tf
provider "aws" {
  region = "us-east-1"  # Replace with your desired AWS region
}
#ec2.tf

resource "aws_instance" "terra1" {
        ami = var.ami_id   
        instance_type = var.instance_type  

  tags = {
    Name = var.instance_name  
  }
}
#s3.tf

resource "aws_s3_bucket" "terra-buk" {
        bucket = var.bucket_name
}
#dynamodb.tf

resource "aws_dynamodb_table" "terra_table_1" {
        name = var.table_name
        billing_mode = "PAY_PER_REQUEST"
        hash_key = "d5"

        attribute {
                name = "d5"
                type = "N"
}
}
#variable.tf

variable "ami_id" {
        default = "ami-053b0d53c279acc90"

}

variable "instance_type" {
        default = "t2.micro"

}

variable "instance_name" {
        default = "terraweek-d5"

}

variable "bucket_name" {
        default = "terraweek-d5"
}

variable "table_name" {
        default = "terraweek-d5"
}

After that we have to do terraform init then check terraform plan and then apply terraform apply.

Now Create a directory for modules and copy all the required templates.

Now we have created terra-app template modules.

#variable.tf
variable "ami_id" {
        description = "This is AMI ID based on modules"
        type = string

}

variable "instance_type" {
        description = "This is instance based on env"
        type = string

}

variable "instance_name" {
        type = string

}

variable "bucket_name" {
        type = string
}

variable "table_name" {
        type = string
}

variable "env_name" {
        type = string
}
#s3.tf
resource "aws_s3_bucket" "terra-bucket" {
        bucket = "${var.env_name}-${var.bucket_name}"
}
#ec2.tf
resource "aws_instance" "terra_instance" {
        ami = var.ami_id   
        instance_type = var.instance_type  

  tags = {
    Name = "${var.env_name}-${var.instance_name}"  
  }
}
#dynamodb.tf
resource "aws_dynamodb_table" "terra-table" {
        name = "${var.env_name}-${var.table_name}"
        billing_mode = "PAY_PER_REQUEST"
        hash_key = "d5terraID"

        attribute {
                name = "d5terraID"
                type = "S"
}

}

Module is Block which allows you to use templates to create a new infrastructure.

Define the EC2 instance configuration in the main.tf

#main.tf
# Dev
module "dev-app" {
        source = "./module/app"
        env_name = "dev"
        instance_type = "t2.micro"
        ami_id  = "ami-053b0d53c279acc90"
        instance_name = "terraweek-d5-dev"
        bucket_name = "terraweek-d5-bucket"
        table_name = "terraweek-d5-dev"
}
#QA
module "qa-app" {
        source = "./module/app"
        env_name = "qa"
        instance_type = "t2.small"
        ami_id  = "ami-053b0d53c279acc90"
        instance_name = "terraweek-d5-QA" 
        bucket_name = "terraweek-d5-bucket"
        table_name = "terraweek-d5-QA"
}
#Production
module "prd-app" {
        source = "./module/app"
        env_name = "prd"
        instance_type = "t2.micro"
        ami_id  = "ami-053b0d53c279acc90"
        instance_name = "terraweek-d5-Prd"
        bucket_name = "terraweek-d5-bucket"
        table_name = "terraweek-d5-Prd"
}

Run terraform apply:

All instances are created with module templates.

All S3 buckets will be created.

All DynamoDB tables are created.


๐Ÿ”ถ Task 3: Dig into modular composition and module versioning.

Modular composition and module versioning are essential aspects of Terraform that help you manage infrastructure as code (IaC) projects efficiently, promote reusability, and ensure consistency across different environments and teams.

They play a crucial role in ensuring the maintainability, reusability, and stability of your Terraform configurations.

Modular Composition:

Modular composition in Terraform refers to the practice of breaking down your infrastructure code into smaller, reusable components or modules. Each module encapsulates the configuration for a specific resource, service, or a logically related set of resources. Modular composition provides several advantages:

  1. Reusability: You can reuse modules across different Terraform configurations or projects. This reduces code duplication and ensures consistency in your infrastructure deployments.

  2. Abstraction: Modules abstract the implementation details of the resources they manage. Users of a module interact with it using input variables and outputs, which simplifies the main configuration files and hides complex logic.

  3. Encapsulation: Modules encapsulate configuration and logic, making it easier to manage and maintain your infrastructure code. Changes to one module are less likely to impact other parts of your codebase.

  4. Testing and Validation: Modules can be tested independently, allowing you to validate their functionality and correctness before using them in larger configurations.

module "web_server" {
  source      = "./modules/web_server"
  instance_count = 2
  instance_type  = "t2.micro"
}

Modular composition in Terraform refers to the practice of building complex infrastructure by combining smaller, reusable modules.

Module Versioning:

Module versioning is the practice of assigning unique versions to your Terraform modules. This is crucial for maintaining stability and ensuring that changes to modules do not unintentionally break existing infrastructure.

  1. Version Constraints: You can specify version constraints for modules in your configuration. These constraints can be exact versions, version ranges, or even version operators (e.g., >= 2.0, < 3.0). This allows you to control which module versions are used in your configuration.

  2. Terraform Lock Files: Terraform can generate a lock file (.terraform.lock.hcl) that records the exact versions of modules used in your configuration. This lock file can be shared with your team to ensure everyone is using the same module versions.

  3. Terraform Registry: If you're using modules from the official Terraform Registry (registry.terraform.io), you can specify module versions directly in your configuration. Terraform will automatically fetch the specified versions from the registry.

  4. Private Module Registries: If you have private modules, you can use similar versioning practices as those mentioned above, depending on your private registry's capabilities.


๐Ÿ”ถ Task 4: What are the ways to lock Terraform module versions? Explain with code snippets.

Locking Terraform module versions is important to ensure that your infrastructure remains stable and doesn't break due to unexpected changes in module versions.

When referencing a module in your Terraform configuration, we can specify a version constraint using the version argument. This allows us to ensure that only compatible module versions are used.

You can create a .tf file dedicated to module versions and constraints. For example, you can create a file named module-versions.tf and define module versions and constraints there

# versions.tf

terraform {
  required_version = ">= 0.13, < 0.14"  # Terraform core version constraint
}

# Module version constraints
module "example" {
  source  = "terraform-aws-modules/vpc/aws"
  version = ">= 2.0, < 3.0"  # Version range constraint for the module
}

In conclusion, Terraform modules are a powerful and essential feature for managing infrastructure as code (IaC) effectively. They offer a way to encapsulate, reuse, and share infrastructure configurations in a modular and scalable manner. Here's a summary of the key points regarding Terraform modules:

Happy Learning :)

If you find my blog valuable, I invite you to like, share, and join the discussion. Your feedback is immensely cherished as it fuels continuous improvement. Let's embark on this transformative DevOps adventure together! ๐Ÿš€

ย