Till now we went through the basics of terraform and how we can use it for provisioning our infrastructure. What are states in terraform and how we can use remote backend to store our states? We looked into an example to use S3 as a remote backend with dynamoDB as a locking mechanism for effective collaboration. Worked on a real-world example on AWS cloud to set up an EC2 instance inside AWS VPC. Let’s see more about terraform and understand the what, why and how of terraform modules.

In production, we need to manage multiple environments, different products with similar infrastructure. Writing code to manage each of these similar configurations increases a lot of redundancy in the code. No reusability adds an overhead of managing code and doing changes across the infrastructure. Collaboration on the different part of the code is hard when everyone is working on the same code. At times members of different teams have similar needs, which makes them write the same code. So, we need a mechanism to share code among teams, reuse existing code and make it robust. We need the capability to test different versions while keeping production infrastructure stable.

Terraform provides modules which allow us to abstract away re-usable parts, which we can configure once, and use everywhere. Modules allow us to group resources together, define input variables which are used to change needed resource configuration parameters, define output variables that other resources or modules can use. Modules are basically like files with exposed input and output variables which facilitate reuse. We don’t need to do anything special to create a module, it is just like our terraform configuration which runs independently. Modules can’t inherit or reference parent resources, we need to pass them to the module explicitly as input variables. Modules are self-contained packages which can be shared across teams for different projects.

Using modules in terraform is similar to using resources except we use module clause for modules instead of resource clause.

module "moduleName" {

source = "module/path"

}

In modules, we only specify a name, which is used elsewhere in the configuration to reference module outputs. Source parameter is a required field for modules. This specifies from where to download module configuration. We can download modules from multiple resources i.e. local path, terraform registry, GitHub, HTTP URLs, s3 etc. There is a public terraform registry which contains many modules which can be used by anyone for faster development. When we use any module, we first need to do terraform init. This command will download module configuration along with other init tasks. We can add a version attribute to specify a specific version of the module. This helps with third-party modules as we get more control on when we want to incorporate updated changes in our code. This also helps us with testing changes of different version in environments other than production. We can gradually roll out new versions on production after proper testing and validation.

We are going to use the same example from this article to create an EC2 instance inside AWS VPC. We are going to create a network module which creates a networking layer for AWS. This module is used by our main configuration file where we create EC2 instance inside our networking layer created with help of network module.

module "networkModule" {

source = "./module/network"

}

We are going to use public subnet id from the output of our networking module inside main configuration file using below code.

module.networkModule.public_subnet_id

Our final EC2 resource is going to look something like mentioned below.

resource "aws_instance" "testInstance" {

ami = "${var.instance_ami}"

instance_type = "${var.instance_type}"

subnet_id = "${module.networkModule.public_subnet_id}"

vpc_security_group_ids = ["${module.networkModule.sg_22_id}"] tags {

"Environment" = "${var.environment_tag}"

}

}

Complete code can be found in this git repository: https://github.com/MiteshSharma/TerraformModules

PS: If you liked the article, please support it with claps. Cheers