---
title: "How to Build a Terraform Module Example"
description: "Learn to build a Terraform module to manage increasingly complex configurations by going through a Terraform module example in this step-by-step tutorial!"
canonical: "https://adamtheautomator.com/terraform-module-example/"
---

# How to Build a Terraform Module Example

> Learn to build a Terraform module to manage increasingly complex configurations by going through a Terraform module example in this step-by-step tutorial!

Source: https://adamtheautomator.com/terraform-module-example/

---

ATA Learning

Tap to hide

[

ATA Learning

](/)

*   [Home](/)
*   [Tutorials](/tutorials/)
*   [Instructors](/author/)
*   [Advertising](/advertising/)
*   [Recommended Resources](/resources/)
*   [About Adam](/about-adam/)

Search for:  

*   [](https://twitter.com/adbertram)
*   [](https://github.com/Adam-the-Automator)
*   [](https://www.linkedin.com/company/adam-the-automator-llc)
*   [](/feed/)

![How to Build a Terraform Module Example](https://adamtheautomator.com/wp-content/uploads/2022/01/How-to-Build-a-Terraform-Module-Example.jpg)

# How to Build a Terraform Module Example

[![](https://secure.gravatar.com/avatar/2d7cef07ef659b643023a33acb03a593ea4aa235dd7dbd9b03b8e3f47133212c?s=192&d=mm&r=g)Michael Thanh](https://adamtheautomator.com/author/michael-thanh/)21 January 20226 min. read

Categories: [DevOps](/category/devops/)

Tags:[Terraform](/tag/terraform/)

Table of Contents

*   [Prerequisites to Build Terraform Module Example](#prerequisites)
*   [Setting up a Directory Structure](#setting-up-a-directory-structure)
*   [Writing Terraform VPC Module Codes](#writing-terraform-vpc-module-codes)
*   [Writing Main Terraform Codes](#writing-main-terraform-codes)
*   [Deploying Terraform Code](#deploying-terraform-code)
*   [Conclusion](#conclusion)

Terraform modules are a fantastic way to encapsulate common parts of code, making them more reusable across multiple Terraform projects and configurations. But how do you build a Terraform module example? Well, you’re in for a treat!

In this article, you’ll learn how to build a Terraform module that you can use to create a basic AWS EC2 instance.

Ready? Read on and start building!

## Prerequisites to Build Terraform Module Example

This tutorial will be a hands-on demonstration. If you’d like to follow along, be sure you have the following:

*   An [AWS](https://adamtheautomator.com/terraform-aws/) account – If you don’t have an AWS account, a **[free tier](https://aws.amazon.com/free/?all-free-tier.sort-by=item.additionalFields.SortRank&all-free-tier.sort-order=asc&awsf.Free%20Tier%20Types=*all&awsf.Free%20Tier%20Categories=*all)** account is available.
*   An EC2 instance with Terraform installed – This tutorial uses Terraform v0.14.4.
*   An installed and configured **[AWS CLI](https://aws.amazon.com/cli/)**.

Related:[Getting Started with the Terraform AWS Provider](https://adamtheautomator.com/terraform-aws/)

## Setting up a Directory Structure

Why must you set up terraform project directory structure in the first place? Firstly, Terraform needs a directory structure to organize your scripts and files like other programming languages. Secondly, Terraform uses a _.tf_ file to describe main Terraform configurations, and other terraform files (.tf states) to describe Terraform resources.

Terraform reads configurations from the root directory when it starts, so terraform configurations must be in the root directory.

1\. Open your terminal and run the following commands to create a new directory named `terraform_project` and switch to that directory. You can name the directory differently as you prefer. This directory will hold all the files and subdirectories for this project.

```bash
mkdir terraform_project
cd terraform_project
```

2\. Run the `mkdir` command below to create two directories. First is `modules`, a parent directory, and `vpc`, a subdirectory of the `modules` directory.

```bash
mkdir -p modules/vpc
```

3\. Finally, run the following command to change your current directory to the `vpc` directory inside the `modules` directory using an absolute path. Be sure to replace `cloud_user` with your username.

You specify the absolute path of the `vpc` directory since each user in your system has their own home directory.

```bash
cd /home/cloud_user/terraform_project/modules/vpc/
```

## Writing Terraform VPC Module Codes

Now that your project directory structure is ready, it’s time to build a Terraform module to create an [AWS Virtual Private Cloud (VPC)](https://docs.aws.amazon.com/vpc/latest/userguide/what-is-amazon-vpc.html). You’ll create multiple Terraform configuration files, so get your favorite code/text editor ready.

Related:[Building an AWS VPC with Terraform Step-by-Step](https://adamtheautomator.com/terraform-vpc/)

> Y_ou’ll create configuration files in the ~/terraform\_project/modules/vpc/ directory throughout this section._

1\. Create a new file called _main.tf_ (Terraform VPC module) with your text editor and populate the file with the following code. The below code will initialize variables, declare the AWS provider block and specify the subnet range with the `cidr_block` attribute. The resource block belonging to this VPC module will define the AWS\_VPC and AWS\_SUBNET resources.

```powershell
# The provider block is where the parameters for this module are defined. 
# In this case, it defines a single parameter named region, 
# which  is the AWS Region where the VPC will be deployed.
provider "aws" {
region = var.region
}

# This is a resource block and it's where you define VPC resources.
resource "aws_vpc" "this" {
# This cidr_block defines the VPC as a 10.0.0.0/16 network. 
# In other words, it's a 256 Class C (CIDR) IP address  range.
cidr_block = "10.0.0.0/16"
}
# This is a resource block and it's where you define VPC resources.
resource "aws_subnet" "this" {
# This line will bind the vpc_id to the vpc defined in the "aws_vpc" module.
vpc_id     = aws_vpc.this.id
cidr_block = "10.0.1.0/24"
}
# This block defines a single parameter for this module 
# named /aws/service/ami-amazon-linux-latest/amzn2-ami-hvm-x86_64-gp2
data "aws_ssm_parameter" "this" {
name = "/aws/service/ami-amazon-linux-latest/amzn2-ami-hvm-x86_64-gp2"
}
```

2\. Next, create another file called _variables.tf_ and populate the file with the following code. The _variables.tf_ file contains all variables that the configuration file references.

```powershell
# A variable block, which defines one or more variables inside it.
variable "region" {
	# Defines the data type of this variable as a string.
	type  = string
	# Sets the default value for the region variable.
	default = "us-east-1"
}
```

3\. Finally, create a file called _outputs.tf_ and paste the code below to the file.

The code below is critical to exporting values from a module to the calling environment. When a module is called, Terraform creates a single resource. That resource has the name of the module and a type of output.

The contents of _outputs.tf_ define the values for this resource.

```powershell
# Outputs the id of the subnet you created in the module
output "subnet_id" {
	value = aws_subnet.this.id
}
# Outputs the value of the 
# /aws/service/ami-amazon-linux-latest/amzn2-ami-hvm-x86_64-gp2 parameter.
output "ami_id" {
	value = data.aws_ssm_parameter.this.value
}
```

## Writing Main Terraform Codes

You’ve completed setting up your modules and auxiliary files, so you can now start working on the main code.

1\. Run the below command to navigate to your main project directory (`~/terraform_project`)

```bash
cd ~/terraform_project 
```

2\. Create a file called _main.tf_ file with the following contents.

The code below will create a VPC with an ID of vpc-xxxxxxx in the AWS region specified by `var.main_region` and a single subnet with an ID of subnet-yyyyyyy.

```powershell
# Binds the variable to the value of var.main_region.
variable "main_region" {
	type  = string
	default = "us-east-1"
}
# Binds the value of the variable to the AWS region.
provider "aws" {
	region = var.main_region
}
# Calls the code in the vpc module you created earlier.
module "vpc" {
	source = "./modules/vpc"
	region = var.main_region
}
resource "aws_instance" "my-instance" {
	# Binds the value of the ami variable to the AMI id in this module.
	ami = module.vpc.ami_id
	# Binds the value of the subnet id to the subnet id in the module.
	subnet_id = module.vpc.subnet_id
	# Binds the value of instance type to t2.micro.
	instance_type = "t2.micro"
}
```

3\. Lastly, create another file called _outputs.tf_ and populate the file with the code below.

The code below defines the values of outputs when this module is called.

```powershell
# Print out the private ip of the EC2 instance that will be created using this module
output "PrivateIP" {
	description = "Private IP of EC2 instance"
	value    = aws_instance.my-instance.private_ip
}
```

## Deploying Terraform Code

You now have your module and configuration files ready. But they’re not doing much at the moment unless you deploy your code.

1\. Run the [`terraform fmt`](https://www.terraform.io/cli/commands/fmt) command below to ensure your code is formatted correctly. The `-recursive` flag tells Terraform to go through all the files in your directory.

Terraform uses a set of rules to determine how it should format your code called the Terraform [Style Conventions](https://www.terraform.io/language/syntax/style). If you have files that do not comply with these rules, this command will resolve that for you.

```bash
terraform fmt -recursive
```

![Checking the code format](https://adamtheautomator.com/wp-content/uploads/2022/01/image-238.png)

Checking the code format

2\. Next, run the [`terraform init`](https://www.terraform.io/cli/commands/init) command below to initialize your Terraform project.

This command is a helper that initializes a new Terraform project. This command goes through all the files in your project and automatically detects modules while downloading any necessary dependencies for modules.

```bash
terraform init
```

> _Make sure to run this `terraform init` command in your main project directory. You should also initialize a Terraform project only once, or you might end up with many useless files._

![Initializing your Terraform project.](https://adamtheautomator.com/wp-content/uploads/2022/01/image-239.png)

Initializing your Terraform project.

Run the [`terraform validate`](https://www.terraform.io/cli/commands/validate) command to test your code for errors.

This command checks if the code you wrote is syntactically correct and will not break anything. If any files contain errors, this command will tell you which ones and how to fix them.

```bash
terraform validate
```

> _Ensure that you have no errors before continuing, or Terraform cannot deploy your code when the time comes._

![Validating your code](https://adamtheautomator.com/wp-content/uploads/2022/01/image-240.png)

Validating your code

4\. Run the [`terraform plan`](https://www.terraform.io/cli/commands/plan) command to create an execution plan.

This command analyzes all the files in your project and then displays what actions to perform without changing anything. `terraform plan`

```bash
terraform plan
```

In this demo, the output below shows three resources configured in this module, and no resources will be modified or deleted.

![Creating an execution plan](https://adamtheautomator.com/wp-content/uploads/2022/01/image-241.png)

Creating an execution plan

5\. Now run the `terraform apply` to apply your execution plan (from step four) while accepting prompts automatically (`--auto-approve`). This command tells Terraform to start creating the resources described in the execution plan.

> _Deploying your resources may take a while, so be patient and just wait it out._

```bash
terraform apply --auto-approve
```

Once the creation phase is over, Terraform will present you with a summary of what took place, as shown below.

You can see that Terraform created the EC2 instance and outputted the private IP address as was configured in the _outputs.tf_ file in your main project directory.

![Previewing the execution plan deployment progress](https://adamtheautomator.com/wp-content/uploads/2022/01/image-242.png)

Previewing the execution plan deployment progress

6\. Finally, run the `terraform state` command below. This command lists resources that have been created and are now tracking in the state file.

The state file is a small file that stores the status of your resources. The state file also lets you run commands without specifying whether or not they have been created or destroyed. As a result, this file saves you time and makes Terraform run faster.

```bash
terraform state list
```

You will get a resources list, as shown below, that includes your EC2 instance that was configured and created by the main code.

You can also see three resources (with **module.vpc** as their prefix) configured and created via the VPC module code.

This output confirms that your modules are all working properly.

![Confirming the modules are working properly](https://adamtheautomator.com/wp-content/uploads/2022/01/image-243.png)

Confirming the modules are working properly

## Conclusion

In this tutorial, you’ve gone through a Terraform module example and learned how to create one by writing your own code. You’ve also touched on passing variables between modules, testing code functionality before deployment, and applying the module to deploy the code.

At this point, you should be familiar with the basic structure of a Terraform module and how to create your own. Now, why not engage yourself more with Terraform? Perhaps learn how to [Deploy an EC2 instance to run Docker with Terraform](https://klotzandrew.com/blog/deploy-an-ec2-to-run-docker-with-terraform)?

Share this article

[Share on X](https://twitter.com/intent/tweet?url=https%3A%2F%2Fadamtheautomator.com%2Fterraform-module-example%2F&text=How%20to%20Build%20a%20Terraform%20Module%20Example)[Share on Facebook](https://www.facebook.com/sharer/sharer.php?u=https%3A%2F%2Fadamtheautomator.com%2Fterraform-module-example%2F)[Share on LinkedIn](https://www.linkedin.com/sharing/share-offsite/?url=https%3A%2F%2Fadamtheautomator.com%2Fterraform-module-example%2F)

## Related Posts

![](https://adamtheautomator.com/wp-content/uploads/2023/02/terraform-best-practices.jpg)

### [Ensuring Success by Learning Terraform Best Practices](/terraform-best-practices/)

Discover Terraform best practices and ensure that your DevOps environment is being utilized safely and securely to it’s fullest potential!

![](https://adamtheautomator.com/wp-content/uploads/2022/08/Which-Tool-Terraform-vs-Cloudformation-in-the-Fight-for-AWS.jpg)

### [Which Tool? Terraform vs. Cloudformation in the Fight for AWS](/terraform-vs-cloudformation/)

Learn which tool, Terraform vs Cloudformation is right for infrastructure as configuration with AWS in this ATA Learning tutorial!

![](https://adamtheautomator.com/wp-content/uploads/2022/07/A-Definitive-Guide-to-Leveraging-the-AWS-Terraform-IAM-Role.jpg)

### [A Definitive Guide to Leveraging the AWS Terraform IAM Role](/terraform-iam-role/)

Discover this definitive guide to the AWS Terraform IAM role and take your devops game to the next level in this ATA Learning tutorial.

## Categories

*   [IT Ops](/category/it-ops/)
*   [Cloud](/category/cloud/)
*   [DevOps](/category/devops/)
*   [Home Ops](/category/home-ops/)
*   [Information Security](/category/infosec/)
*   [Software Development](/category/software-development/)

## Site

*   [Home](/)
*   [Tutorials](/tutorials/)
*   [Instructors](/author/)
*   [Advertising](/advertising/)
*   [Recommended Resources](/resources/)
*   [About Adam](/about-adam/)

Copyright 2026© ATA Learning | [Privacy Policy](/privacy/)
