Task 1:
What are modules in Terraform and why do we need modules in Terraform?
Terraform, modules are a fundamental concept used to organize and encapsulate infrastructure code into reusable and shareable components. Modules help make Terraform configurations more modular, maintainable, and scalable.
Modules in Terraform improve the organization, maintainability, and collaboration of your infrastructure code. They enable you to build reusable and scalable infrastructure components, reducing the complexity of managing cloud resources and promoting best practices in infrastructure as code (IaC) development.
What are the benefits of using modules in Terraform?
Abstraction and Encapsulation: Modules allow you to encapsulate a set of related resources and configurations into a single, reusable unit.
Reusability: Modules can be reused across multiple Terraform projects and configurations.
Separation of Concerns: Modules promote separation of concerns by breaking down complex infrastructure into smaller, manageable pieces.
Versioning: Modules can be versioned and published, allowing teams to use specific versions of modules in their configurations.
Collaboration: Modules facilitate collaboration among team members. Different team members can work on separate modules, and these modules can be integrated into a larger infrastructure configuration.
DRY (Don't Repeat Yourself) Principle: Modules encourage the DRY principle by eliminating the need to duplicate infrastructure code.
Task 2:
Create/Define a module in Terraform to encapsulate reusable infrastructure configuration in a modular and scalable manner. For example EC2 instance in AWS, Resource Group in Azure, and Cloud Storage bucket in GCP.
In this example, we will be creating 2 Ec2 instances 1 S3 bucket, and 1 DynamoDB. for that, we will create a provider.tf resources.tf ec2.tf s3.tf dynamodb.tf terraform. tf
#provider.tf
provider "aws" {
region = "ap-south-1" # Replace with your desired AWS region
}
#ec2.tf
resource "aws_instance" "ec2_instance" {
ami = var.ami_id
instance_type = var.instance_type
tags = {
Name = var.instance_name
}
}
#provider.tf
terraform {
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 5.0"
}
}
}
resource "aws_s3_bucket" "demo-s3-buck1" {
bucket = var.bucket_name
}
resource "aws_dynamodb_table" "dyno-demo-table" {
name = var.table_name
billing_mode = "PAY_PER_REQUEST"
hash_key = "emailID"
attribute {
name = "emailID"
type = "S"
}
}
Variable. tf
Check everything is correct by doing terraform plan
and terraform apply
to create the instance,S3,dynamodb
Now Create a directory for modules and copy all the required templates.
we will be creating template for my-app
change the variable.tf
1. ami_id: This variable is of type string and represents the AMI (Amazon Machine Image) ID that will be used for your EC2 instances. AMIs are used as templates to create EC2 instances, and by defining this variable, you can specify the AMI to use in different environments.
instance_type: Also of type string, this variable represents the EC2 instance type. EC2 instances come in various types with different compute and memory capacities. Defining this variable allows you to select the appropriate instance type for your infrastructure.
instance_name: This variable is of type string and can be used to specify a name for your EC2 instances. Naming instances can help you identify them easily in your AWS environment.
bucket_name: This string variable can be used to specify the name of an S3 bucket. S3 buckets are used for storing objects and files in AWS. By defining this variable, you can customize the name of the S3 bucket in your Terraform configuration.
table_name: This variable of type string can be used to specify the name of an AWS DynamoDB table. DynamoDB is a managed NoSQL database service in AWS, and by using this variable, you can set the table name for your DynamoDB resources.
env_name: This variable is of type string and can be used to specify an environment name. Environment names can be used to differentiate resources between different environments, such as "development," "staging," and "production."
When you use these variables in your configuration files, you can pass values for them to tailor your infrastructure to specific requirements in different environments. This makes your Terraform code more adaptable and reusable.
The module
block allows you to reference and use a module in your main Terraform configuration.
Here's the syntax of a module
block:
module "module_name" {
source = "module_source"
# Input variable assignments (if any)
variable_name = value
# ...
}
Main. tf
Terraform configuration, each representing a different environment: "dev," "QA" (staging), and "prd" (production). These module blocks are using a module named "my-app" from a local source (./modules/my-app
) to create infrastructure in each environment.
The
env_name
variable is set to "dev" to indicate the development environment.You're using a "t2.micro" instance type with a specific AMI ID, instance name, S3 bucket name, and DynamoDB table name.
The
env_name
variable is set to "QA" to indicate the staging environment.You're using a "t2.small" instance type with a specific AMI ID, instance name, S3 bucket name, and DynamoDB table name.
The
env_name
variable is set to "prd" to indicate the production environment.You're using a "t2.micro" instance type with a specific AMI ID, instance name, S3 bucket name, and DynamoDB table name.
terraform init
terraform plan
terraform apply
All instances are created with module templates.
ec2 instance
s3 bucket
DynamoDB table
Task 3: Dig into modular composition and module versioning
modular composition and module versioning are important aspects of managing infrastructure as code (IaC) effectively. These practices help you create reusable and maintainable infrastructure configurations while ensuring consistency across different projects and environments.
Modular Composition:
Modular composition refers to the practice of combining multiple Terraform modules to build complex infrastructure configurations. This approach allows you to reuse existing modules for common infrastructure components and assemble them into larger configurations.
Module Versioning:
Module versioning is the practice of assigning versions to Terraform modules to ensure reproducibility and compatibility. This is especially important when you have multiple projects or teams using the same modules.
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.
#module-version.tf
module "CKP-app" {
source = "hashicorp/example/aws"
version = ">= 1.0, < 2.0"
# Version constraint, any version in the 1.x range
}
In this example, Terraform will only use module versions that are greater than or equal to 1.0.0 but less than 2.0.0.
Happy Learning :)