๐Ÿš€ DevOps & SRE Certification Program ๐Ÿ“… Starting: 1st of Every Month ๐Ÿค +91 8409492687 ๐Ÿ” Contact@DevOpsSchool.com

Upgrade & Secure Your Future with DevOps, SRE, DevSecOps, MLOps!

We spend hours on Instagram and YouTube and waste money on coffee and fast food, but wonโ€™t spend 30 minutes a day learning skills to boost our careers.
Master in DevOps, SRE, DevSecOps & MLOps!

Learn from Guru Rajesh Kumar and double your salary in just one year.


Get Started Now!

Terraform Tutorials: Module Complete Guide

A Terraform module is a collection of configuration files that encapsulate resources used together to achieve a specific outcome. Modules promote reusability, organization, and maintainability in infrastructure as code by allowing you to group related resources and manage them as a single unit.

Understanding the Module Block

In Terraform, you define a module block to incorporate the contents of another module into your configuration. This allows you to reuse existing configurations and standardize resource provisioning across your infrastructure.

Syntax of a Module Block

A typical module block has the following structure:

module "<MODULE_NAME>" {
  source  = "<SOURCE>"
  version = "<VERSION>"
  # Additional arguments corresponding to the module's input variables
}

๎ˆ†

  • <MODULE_NAME>: A unique identifier for the module instance within your configuration.
  • <SOURCE>: Specifies the location of the moduleโ€™s source code. This can be a local path, a Git repository, or a Terraform Registry address.
  • <VERSION>: Defines the version of the module to use, applicable when sourcing modules from registries.

Example: Using a Module from the Terraform Registry

Suppose you want to deploy an AWS Virtual Private Cloud (VPC) using a community-maintained module from the Terraform Registry. You can define the module block as follows:

module "vpc" {
  source  = "terraform-aws-modules/vpc/aws"
  version = "3.19.0"

  name = "my-vpc"
  cidr = "10.0.0.0/16"

  azs             = ["us-west-1a", "us-west-1b", "us-west-1c"]
  private_subnets = ["10.0.1.0/24", "10.0.2.0/24", "10.0.3.0/24"]
  public_subnets  = ["10.0.101.0/24", "10.0.102.0/24", "10.0.103.0/24"]

  enable_nat_gateway = true
  tags = {
    Terraform   = "true"
    Environment = "dev"
  }
}

In this example:

  • source: Specifies the moduleโ€™s location in the Terraform Registry.
  • version: Ensures that Terraform uses version 3.19.0 of the module, maintaining consistency across deployments.
  • The subsequent arguments (name, cidr, azs, etc.) correspond to the input variables defined by the module, allowing customization of the VPCโ€™s configuration.

Example: Using a Local Module

You can also create and reference local modules within your project directory. Assume you have a module that sets up an AWS EC2 instance, located in the modules/ec2-instance directory:

module "web_server" {
  source = "./modules/ec2-instance"

  instance_type = "t2.micro"
  ami_id        = "ami-0c55b159cbfafe1f0"
  subnet_id     = "subnet-abc12345"
}

๎ˆ†

Here:

  • source: Points to the relative path of the local module.
  • The arguments (instance_type, ami_id, subnet_id) are input variables defined within the ec2-instance module, allowing you to customize the EC2 instanceโ€™s properties.๎ˆ†

Key Components of a Module

A well-structured Terraform module typically includes the following files:๎ˆ†

  • main.tf: Contains the primary resource definitions.๎ˆ†
  • variables.tf: Declares input variables to parameterize the module.๎ˆ†
  • outputs.tf: Defines output values to expose information about the resources.๎ˆ†
  • versions.tf: Specifies the required Terraform version and provider constraints.๎ˆ†
  • README.md: Provides documentation on the moduleโ€™s purpose and usage.๎ˆ†

Best Practices for Using Modules

  • Encapsulation: Modules should encapsulate their resources, exposing only necessary inputs and outputs.๎ˆ†
  • Reusability: Design modules to be reusable across different configurations and environments.๎ˆ†
  • Versioning: Implement version control for modules to manage changes and ensure stability.๎ˆ†
  • Documentation: Provide clear documentation within the module directory to explain its purpose and usage.๎ˆ†
  • Consistency: Use consistent naming conventions and file structures across modules.๎ˆ†

By effectively utilizing module blocks, you can create modular, reusable, and maintainable infrastructure configurations, enhancing the scalability and manageability of your Terraform projects.

$ tree minimal-module/
.
โ”œโ”€โ”€ README.md
โ”œโ”€โ”€ main.tf
โ”œโ”€โ”€ variables.tf
โ”œโ”€โ”€ outputs.tf

module "consul" {
source = "hashicorp/consul/aws"
}
module "moduleName" {
source = "module/path"
}
module "networkModule" {
source = "./module/network"
}
module "s3-bucket" {
source = "terraform-aws-modules/s3-bucket/aws"
version = "1.0.0"
# insert the 6 required variables here
}
Working with Terraform Modules
===================================
$ terraform init
# Add modules in .tf
$ terraform get
$ terraform plan
$ terraform apply
$ terraform show

resource "azurerm_resource_group" "example" {
  name     = "my-resources66"
  location = "West Europe"
}

module "apache"{
	source              = "./modules/install_apache"
}

module "nginx"{
	source              = "./modules/install_nginx"
	instances = ["${module.web.instance_ids}"]
}

module "network" {
  source              = "Azure/network/azurerm"
  resource_group_name = azurerm_resource_group.example.name
  address_spaces      = ["10.0.0.0/16", "10.2.0.0/16"]
  subnet_prefixes     = ["10.0.1.0/24", "10.0.2.0/24", "10.0.3.0/24"]
  subnet_names        = ["subnet1", "subnet2", "subnet3"]

  subnet_service_endpoints = {
    "subnet1" : ["Microsoft.Sql"], 
    "subnet2" : ["Microsoft.Sql"],
    "subnet3" : ["Microsoft.Sql"]
  }

  tags = {
    environment = "dev"
    costcenter  = "it"
  }

  depends_on = [azurerm_resource_group.example]
}

key parameters available for a Terraform module block

Certainly! Hereโ€™s a table summarizing the key parameters available for a Terraform module block:

ParameterDescriptionRequiredExample
sourceSpecifies the location of the moduleโ€™s source code. This can be a local path, a Git repository, or a Terraform Registry address.Yessource = "./modules/network" or source = "terraform-aws-modules/vpc/aws"
versionDefines the version of the module to use, particularly when sourcing modules from registries.Noversion = "3.0.0"
providersOverrides the default provider configurations for the module. Useful when you need to specify different provider settings for a particular module.Noproviders = { aws = aws.us_east }
countCreates multiple instances of the module. Allows you to scale resources by specifying the number of instances.Nocount = 3
for_eachCreates multiple instances of the module based on a map or set of strings. Provides more control compared to count, especially when each instance requires unique configurations.Nofor_each = { net1 = "10.0.0.0/16", net2 = "10.1.0.0/16" }
depends_onSpecifies dependencies on other resources or modules. Ensures that the module is provisioned only after certain resources or modules have been created.Nodepends_on = [aws_vpc.main]

*Note: Input variables are user-defined parameters that allow customization of the moduleโ€™s behavior. Each input variable must be defined within the moduleโ€™s variables.tf file. When calling the module, you provide values for these variables.*๎ˆ†

By utilizing these parameters, you can effectively manage and customize the behavior of your Terraform modules, leading to more modular and maintainable infrastructure configurations.

In Terraform, a module block is used to incorporate the configuration of one module into another, promoting reusability and organization in your infrastructure as code. The module block supports several parameters, allowing you to customize its behavior and the resources it provisions. Here's a breakdown of the key parameters you can define within a module block:

  1. source (Required):

    • Description: Specifies the location of the module's source code.
    • Usage: This can be a local file path, a URL to a version control system (like Git), or a reference to a module in the Terraform Registry.
    • Example:
      module "network" {
        source = "./modules/network"
      }
      or
      module "network" {
        source = "terraform-aws-modules/vpc/aws"
      }
  2. version (Optional):

    • Description: Specifies the version of the module to use.
    • Usage: Particularly useful when sourcing modules from the Terraform Registry to ensure compatibility and stability.
    • Example:
      module "network" {
        source  = "terraform-aws-modules/vpc/aws"
        version = "3.0.0"
      }
  3. Input Variables:

    • Description: These are user-defined parameters that allow customization of the module's behavior.
    • Usage: Each input variable must be defined within the module's variables.tf file. When calling the module, you provide values for these variables.
    • Example:
      module "network" {
        source = "./modules/network"
        cidr   = "10.0.0.0/16"
        region = "us-west-1"
      }
      Here, cidr and region are input variables defined within the network module.
  4. providers (Optional):

    • Description: Overrides the default provider configurations for the module.
    • Usage: Useful when you need to specify different provider settings for a particular module.
    • Example:
      provider "aws" {
        region = "us-west-1"
      }
      
      module "network" {
        source    = "./modules/network"
        providers = {
          aws = aws.us_east
        }
      }
      
      provider "aws" {
        alias  = "us_east"
        region = "us-east-1"
      }
  5. count (Optional):

    • Description: Creates multiple instances of the module.
    • Usage: Allows you to scale resources by specifying the number of instances.
    • Example:
      module "network" {
        source = "./modules/network"
        count  = 3
      }
      This will instantiate the network module three times.
  6. for_each (Optional):

    • Description: Creates multiple instances of the module based on a map or set of strings.
    • Usage: Provides more control compared to count, especially when each instance requires unique configurations.
    • Example:
      module "network" {
        source  = "./modules/network"
        for_each = {
          net1 = "10.0.0.0/16"
          net2 = "10.1.0.0/16"
        }
        cidr = each.value
      }
      This will create two instances of the network module with different CIDR blocks.
  7. depends_on (Optional):

    • Description: Specifies dependencies on other resources or modules.
    • Usage: Ensures that the module is provisioned only after certain resources or modules have been created.
    • Example:
      module "network" {
        source     = "./modules/network"
        depends_on = [aws_vpc.main]
      }
      Here, the network module will be created only after the aws_vpc.main resource is provisioned.

By utilizing these parameters, you can effectively manage and customize the behavior of your Terraform modules, leading to more modular and maintainable infrastructure configurations.

view raw README.md hosted with โค by GitHub

Terraform Module Block Source Arguments Style

In Terraform, the source argument within a module block specifies the location of the module's source code. Terraform supports various methods to define this source, allowing flexibility in module sourcing. Here are the different ways to specify the source parameter, along with examples:

1. Local Paths

You can reference modules stored locally on your filesystem using relative paths.

module "network" {
  source = "./modules/network"
  # Additional module arguments
}

In this example, Terraform will load the module from the modules/network directory relative to your current working directory.

2. Terraform Registry

Modules can be sourced directly from the Terraform Registry, which hosts a vast collection of publicly available modules.

module "consul" {
  source  = "hashicorp/consul/aws"
  version = "0.0.5"
  # Additional module arguments
}

Here, the Consul module for AWS is sourced from the Terraform Registry. Specifying the version ensures that Terraform uses the desired module version. ๎ˆ€cite๎ˆ‚turn0search6

3. GitHub

Modules can be sourced from GitHub repositories using the github.com prefix.

module "vpc" {
  source = "github.com/terraform-aws-modules/terraform-aws-vpc"
  # Additional module arguments
}

This example fetches the VPC module from the specified GitHub repository. ๎ˆ€cite๎ˆ‚turn0search0

4. Generic Git Repositories

Terraform supports sourcing modules from any Git repository by specifying the repository URL.

module "vpc" {
  source = "git::https://example.com/terraform-modules.git//vpc?ref=tags/v0.1.0"
  # Additional module arguments
}

In this case, Terraform retrieves the vpc module from the specified Git repository at the v0.1.0 tag. ๎ˆ€cite๎ˆ‚turn0search0

5. Bitbucket

Modules can also be sourced from Bitbucket repositories.

module "vpc" {
  source = "bitbucket.org/organization/terraform-modules.git//vpc?ref=tags/v0.1.0"
  # Additional module arguments
}

This example fetches the vpc module from a Bitbucket repository at the specified tag. ๎ˆ€cite๎ˆ‚turn0search0

6. HTTP URLs

Modules can be downloaded from HTTP URLs pointing to a ZIP archive of the module.

module "network" {
  source = "https://example.com/terraform-modules/network.zip"
  # Additional module arguments
}

Terraform will download and extract the module from the specified URL. ๎ˆ€cite๎ˆ‚turn0search0

7. Amazon S3 Buckets

Modules stored in Amazon S3 buckets can be referenced directly.

module "network" {
  source = "s3::https://s3.amazonaws.com/mybucket/terraform-modules/network.zip"
  # Additional module arguments
}

Here, Terraform retrieves the module from the specified S3 bucket. ๎ˆ€cite๎ˆ‚turn0search0

8. Google Cloud Storage (GCS) Buckets

Similarly, modules can be sourced from GCS buckets.

module "network" {
  source = "gcs::https://storage.googleapis.com/mybucket/terraform-modules/network.zip"
  # Additional module arguments
}

Terraform will download the module from the specified GCS bucket. ๎ˆ€cite๎ˆ‚turn0search0

Note on Parameterizing the source Argument

As of Terraform v0.13, the source argument must be a literal string and cannot directly reference variables or expressions. This design ensures that module sources are known before evaluating the configuration. ๎ˆ€cite๎ˆ‚turn0search6

By utilizing these methods, you can flexibly source Terraform modules from various locations, tailoring your infrastructure as code to your project's needs.

view raw README.md hosted with โค by GitHub

In Terraform, you can specify a module's source using various Git options to control which version or part of the repository to use. Here are examples illustrating different scenarios:

1. Default Branch

By default, Terraform fetches the module from the repository's default branch (usually main or master):

module "network" {
  source = "git::https://github.com/username/repository.git"
  # Additional module arguments
}

2. Specific Branch

To use a specific branch, append the ref parameter with the branch name:

module "network" {
  source = "git::https://github.com/username/repository.git?ref=branch-name"
  # Additional module arguments
}

3. Specific Tag

To use a specific tag, set the ref parameter to the tag name:

module "network" {
  source = "git::https://github.com/username/repository.git?ref=v1.0.0"
  # Additional module arguments
}

4. Specific Commit ID

To use a specific commit, set the ref parameter to the commit hash:

module "network" {
  source = "git::https://github.com/username/repository.git?ref=commit-sha"
  # Additional module arguments
}

5. Subdirectory in a Specific Branch

If the module resides in a subdirectory of a specific branch, specify both the branch and the subdirectory:

module "network" {
  source = "git::https://github.com/username/repository.git//subdirectory?ref=branch-name"
  # Additional module arguments
}

6. SSH Protocol

To clone a private repository over SSH, use the SSH URL:

module "network" {
  source = "git::ssh://git@github.com/username/repository.git"
  # Additional module arguments
}

7. GitHub Shortcut

For public GitHub repositories, you can use a shorthand notation:

module "network" {
  source = "github.com/username/repository"
  # Additional module arguments
}

8. Git Over SSH with Subdirectory

To access a module in a subdirectory over SSH:

module "network" {
  source = "git::ssh://git@github.com/username/repository.git//subdirectory"
  # Additional module arguments
}

9. Git Over HTTPS with Authentication

For private repositories over HTTPS, include the username and token:

module "network" {
  source = "git::https://username:token@github.com/username/repository.git"
  # Additional module arguments
}

10. Bitbucket Repository

To source a module from a Bitbucket repository:

module "network" {
  source = "git::https://bitbucket.org/username/repository.git"
  # Additional module arguments
}

11. GitLab Repository

To source a module from a GitLab repository:

module "network" {
  source = "git::https://gitlab.com/username/repository.git"
  # Additional module arguments
}

12. Using a Depth Parameter for Shallow Clone

To perform a shallow clone and limit the history depth:

module "network" {
  source = "git::https://github.com/username/repository.git?ref=branch-name&depth=1"
  # Additional module arguments
}

By utilizing these Git options, you can precisely control which version or part of a repository Terraform uses for your modules.

Certification Courses

DevOpsSchool has introduced a series of professional certification courses designed to enhance your skills and expertise in cutting-edge technologies and methodologies. Whether you are aiming to excel in development, security, or operations, these certifications provide a comprehensive learning experience. Explore the following programs:

DevOps Certification, SRE Certification, and DevSecOps Certification by DevOpsSchool

Explore our DevOps Certification, SRE Certification, and DevSecOps Certification programs at DevOpsSchool. Gain the expertise needed to excel in your career with hands-on training and globally recognized certifications.