Terraform Modules : Package and Reuse

Nilesh Jaiwal
Globant
Published in
5 min readDec 23, 2021

Introduction

Infrastructure-as-Code (IaC) is a practice that has become mainstream with the growing popularity of public cloud providers, such as AWS, Google, and Microsoft. In a nutshell, it consists of managing a set of resources (computing, network, storage, etc.) using the similar approach developers use to manage application code.

In this article, we’ll do a quick tour of Terraform modules looking at how to create Terraform modules to enable users to use the same code anywhere and customize it via use of variables.

Terraform modules allow you to group distinct resources of your infrastructure into a single, unified resource. You can reuse them later with possible customization's, without repeating the resource definitions each time you need them, which is beneficial to large projects with complex structures. You can customize module instances using the input variables which you define, also you can extract the information from them using outputs. Aside from creating your own custom modules, existing modules are available publicly at the Terraform Registry.

Terraform module Background

Modules: Package and Reuse Code

Terraform modules are comparable to functions or methods in scripting or programming languages. They present a standard interface for creating resources by providing inputs and returning outputs. Modules also simplify projects by increasing readability and allowing teams to organize infrastructure in logical blocks. Modules can be easily shared and sourced into any Terraform project. For example, if tasked with creating multiple VPCs for different environments — one could invoke a single VPC module multiple times, rather than creating each individual resource necessary for a fully functioning VPC.

The module structure contains Terraform files like main.tf, output.tf, provider.tf, variable.tf and terraform.tfvars.json.

Lets understand the significance of these files:

provider.tf :- Terraform relies on plugins called “providers” to interact with cloud providers, SaaS providers, and other APIs. To use resources from a given provider, you need to include some information about it in your configuration. We have used AWS as a provider in the image below since we are creating AWS resources in our example.

main.tf :- This file contains the resource configuration. The arguments can provide inputs to customize the resource as can be seen below:

variable.tf :- We use this file to mention all the input variables which we have parameterized in the main.tf file as can be seen below:

output.tf :- In this file we generate output for the resource to refer to in the module. We have generated the output for security group id as can be seen below:

terraform.tfvars.json :- This is the important file where we pass values to the variable. We just need to make the changes in this file only as per our requirement and the rest of the configuration will be reusable anywhere.

Dynamic Blocks :- Last but not the least, dynamic blocks are one of the best features Terraform provides. Within top-level block constructs like resources, expressions can usually be used only when assigning a value to an argument using the name = expression form. This covers many uses, but some resource types include repeatable nested blocks in their arguments which typically represent separate objects that are related to (or embedded within) the containing object. You can dynamically construct repeatable nested blocks using a special dynamic block type, which is supported inside resource, data, provider, and provisioner blocks.

I have used dynamic blocks in my code to understand this practically. Usually the user will be able to allow limited IP’s to only specific ports in security rule resources. But with dynamic blocks users can add any number of IP’s to any port. In the below image we have shown a dynamic blocks example.

Prerequisites

  • Terraform installation consists of a single binary file that we can freely download from Hashicorp’s download page.
  • A Code editor such as Visual Studio Code or Atom.
  • The cloud provider credentials and permissions to create the resources.

Terraform module structure

In this section, we will define the folder structure to map all the Terraform code. So here we have created 2 folders, one is modules and the other one is resources.

Terraform always runs in the context of a single root module. A complete Terraform configuration consists of a root module and the tree of child modules (which includes the modules called by the root module, any modules called by those modules, etc.)

Modules:- In the modules folder we need to add all the resource configurations which we want to create. We will be creating an EC2 instance and a security group for our example.

Both AWS EC2 instance and security group we have created terraform files like main.tf, outputs.tf and variable.tf.

Resources :- In the resources folder we will be calling modules created within our modules folder. We call the security group module within the EC2 instance module so that the security group will automatically attach to EC2. We have generated security group output from the output.tf file at the time of security group resource creation.

Terraform Execution

Terraform init :- The terraform init command is used to initialize a working directory containing Terraform configuration files. This is the first command that should be run after writing a new Terraform configuration or cloning an existing one from version control. It is safe to run this command multiple times. Terraform relies on plugins called “providers” to interact with cloud providers, SaaS providers, and other APIs.

The terraform init does search the configuration for providers and then install any plugins associated with providers.

Terraform plan :- The terraform plan command is used to create an execution plan. Terraform performs a refresh, unless explicitly disabled, and then determines what actions are necessary to achieve the desired state specified in the configuration files.

Terraform apply :- The terraform apply command executes the actions proposed in a Terraform plan. Post the execution we can see 2 resources have been created (EC2 instance and security group) and we can also see the output which we have generated for security group id.

Terraform destroy :- We can destroy the created infrastructure with terraform destroy command.

Conclusion

For the remainder of this post, we will set the stage by diving into Terraform modules. If you have never used Terraform and are looking for more hands-on experience, the tutorials at Hashicorp’s site are useful. Let’s talk a little bit about Terraform providers. Terraform has more than 100 cloud providers it serves. At Fairwinds we use Terraform for three — AWS, GCP, and Azure. The provider is what enables interfacing with the specific API and exposes whatever resource you have defined. HCL, or HashiCorp language, is the common language used to define a resource, no matter what provider is being used.

Reference

https://www.terraform.io/language/modules/develop

https://www.terraform.io/language/expressions/dynamic-blocks

https://registry.terraform.io/browse/modules

https://github.com/nileshjaiwal/Terraform-Modules

--

--