This blog post introduces modules in Terraform.

In the previous article, we discussed variables and outputs in HCL, which enable flexible and reusable infrastructure configuration management and provisioning in Terraform. However, there's another powerful concept in Terraform called modules, which provides another layer of abstraction and contributes to having cleaner and more reusable Terraform code. In this article, we's discuss how to use and build modules effectively for even more effective organization and seamless provisioning of infrastructure resources in Terraform.
Modules
A module can easily be created by organizing resource and variable .tf
files
into a directory. Typically, we organize different types of resources like databases,
networks, and compute resources into separate files such as database.tf
, network.tf
,
and compute.tf
. A local module can then be loaded and utilized using the relative path
to the directory, as follows.
module "web_app" {
source = "../web_app_module"
# Input Parameters
bucket_name = "web_app_1"
domain = "example.com"
app_name = "web_app_1"
environment_name = "production"
# ...
}
Applying the above will create the resources defined in the local module within
the web_app_module
subdirectory, according to the input parameters and meta-arguments
provided in the module block. The source
argument also accepts links to Terraform
module repositories hosted on GitHub, the Terraform Registry, and other remote
hosting services. When modules are defined with appropriate levels of abstraction,
they can prevent the duplication of work involved in defining complex infrastructures
and allow developers to easily customize them for different applications.
Managing Multiple Environments
Modules are particularly useful for managing different environments, such as development,
staging, and production. Typically, we set up directories like dev
, staging
, and production
,
each containing a main.tf
file that references global modules and a terraform.tfvars
file
for configuring input parameters. Terraform's workspace feature can also be used
to manage different environments, allowing users to switch between them using
the same codebase and backend. However, using modules is generally preferred
because they provide better backend isolation for enhanced security and
a more explicit codebase that fully represents the deployed state, reducing
the risks of human error.
CI/CD Pipeline
As mentioned previously, one of the most important benefits of Terraform is that it can
be version controlled and seamlessly integrated into CI/CD workflows like GitHub Actions.
We can set up a workflow triggered on push to the main branch to test the staging
environment setup, and another workflow triggered by a release event to deploy
the global production environment, automating the testing and deployment of
infrastructure resources. Conveniently, HashiCorp provides a public GitHub Action
for setting up Terraform, hashicorp/setup-terraform@v1
, that can be used for this purpose.
For testing, we could check the formatting with terraform fmt --check
and
verify that the planning succeeds with terraform plan
. Then, we can
write and run a bash script that temporarily creates resources and checks their availability.
Alternatively, if you are familiar with Go, you could write a Go script
using the Terratest library by Gruntwork. If all tests pass,
the resources can be deployed using terraform apply -auto-approve
on modules
and on resources in the corresponding environment. Since out-of-band changes
via CLI and GUI are major causes of conflicts and errors, it's advisable
to set up CI/CD workflows and restrict changes to be made only through Terraform.
Conclusion
In this article, we introduced modules and how they can be utilized to take full advantage of Terraform as an Infrastructure-as-Code tool. This concludes our short Terraform series (at least for now). I highly recommend using modules to rewrite the Terraform code from the previous article for practice and in other projects. For more details and explanations, I highly recommend checking out the resources cited below.
Resources
- DevOps Directive. 2022. Complete Terraform Course - From BEGINNER to PRO! (Learn Infrastructure as Code). YouTube.
- HashiCorp. n.d. Modules. Terraform Registry.
- HashiCorp. n.d. Terraform Language Documentation. Terraform.