by_adr - Fotolia
In a programming language, a function organizes code and makes that code reusable. In HashiCorp's Terraform, this important task is carried out by modules.
A Terraform module is a folder that contains a set of configuration files. It enables admins to create a template for infrastructure-as-code components that can accept parameters to build, scale up and scale down with slight modifications.
Before getting started with Terraform modules and reaping the benefits of templated infrastructure configurations, IT engineers need to grasp module structure, including the role of a root module, along with security best practices.
Terraform coding example
This example shows how to use Terraform to build a VM instance in AWS.
First, provide your AWS access key/secret access key, and choose a region of the public cloud provider. Then, define a Terraform resource with properties, such as an Amazon Machine Image (AMI) ID, instance type and count with respective values, like a key-value pair. Save these configurations in a Terraform file:
This process becomes challenging when you want to deploy more than one VM, as it's necessary to copy the same code over and over to replicate the VM deployment step. To avoid this manual work, use Terraform modules.
Let's use the AWS instance example as the basis to explore the structure of a module and its use of variables as parameters. IT engineers and cloud administrators should follow AWS and Terraform best practices for infrastructure coding.
Structure of a module
A complete Terraform execution plan includes the root module, folders for children modules, and input and output variables.
Root module. Terraform defines a root module as the working directory, or the top-level directory, that holds the Terraform configuration files. Here, you can run the terraform apply command, which provides an entry point to the modules used to build IT infrastructure.
First, make a root module folder named terraform, and create a new file called main.tf -- .tf is the suffix for Terraform files -- as an entry point for the cloud infrastructure build. Inside this folder, create another folder called modules to keep all the children Terraform modules.
Modules folder. In the modules directory, define child modules under different folders. This example is used to create an aws_vm folder, which is how we build VM instances on AWS to suit the deployment's needs. All modules should have a minimum of three files: main.tf, output.tf and variables.tf.
Here, main.tf is the main configuration file of this child module. To give it parameters, define variables in key-value pairs, as demonstrated below for the AWS access key, secret key and region, and instance parameters of the AMI, type and count. All argument values use interpolation syntax to access variable values.
Input variables. All the key-value pair variables mentioned in the above code are input variables defined in the variables.tf file. Each has a name and description, and some include a default configuration. For example, unless otherwise specified, the deployment defaults to AWS' U.S. East region, using AWS T2 instances in the micro configuration.
Editor's note: Check out the author's companion articles to dive into Terraform variable types and uses, and built-in functions.
Output variables. The output.tf file exposes useful values -- such as a public IP address or the state of a VM -- generated after the successful deployment of resources defined in a Terraform module. Other modules in the root module folder can consume these values.
In the example below, make note of the asterisk in the value of the variable, which is there to handle output values from more than one AWS Elastic Compute Cloud (EC2) instance:
Create the root module
Now that we have declared a parameterized child module configuration, return to the main.tf file in the root module folder and start using the aws_vm child module. To call it, use the module keyword followed by the name of the module, with required variables.
Terraform users can parameterize the root module just as they do with child modules like aws_vm -- define input and output variables in the top-level directory.
Declare all the input variables in the variables.tf file of the root module, and provide them with default values. To override these default values, declare variables in a file called terraform.tfvars, which can have variable and corresponding values as a key-value pair, as demonstrated below. This enables you to change the values of the file to tweak infrastructure configurations. For example, this configuration's default for the instance size variable is AWS T2 in the micro setup. However, the engineer can use a variable change to run the t2.nano instance instead:
To receive output variables from the child module into the root module, such as to track the public IP address of the AWS VM, point the output variables of the root module to get the values from the aws_vm module:
Sensitive data in Terraform modules
It's not best practice to store sensitive information, such as access keys and passwords, in Terraform configuration files, where they could easily be exposed and shared into different configuration plans than they were intended for. Instead, create a file named secrets.tfvars to hold sensitive data, and place it in the root module folder in the top-level directory.
Never track this file in version control software, as it can open the door to hackers stealing the information. If you use GitHub, for example, list secrets.tfvars in your .gitignore file.
Use the module to apply the Terraform configuration
After everything is set up in the root module and the child module aws_vm, the directory/file structure should look like as it does below:
Before applying these configurations, run terraform init to download and initialize the provider plugins, which, in this example, is terraform-provider-aws. Then, run the terraform plan command to analyze your configuration, without making any changes. This is a step before deployment that helps to prevent issues with live systems. Supply the names of variable files to input variables to the Terraform configuration:
After the plan review, create the infrastructure declared in the root module using the child module aws_vm. Run the terraform apply command with variable files as input:
terraform apply -var-file="secrets.tfvars" -var-file="terraform.tfvars"
Upon successful resource deployment, Terraform displays a similar result with the output variables defined earlier: