0
0
Terraformcloud~5 mins

Module composition patterns in Terraform - Commands & Configuration

Choose your learning style9 modes available
Introduction
When building infrastructure with Terraform, you often need to reuse and organize code. Module composition patterns help you combine smaller modules into bigger ones, making your infrastructure easier to manage and scale.
When you want to reuse a set of resources like networking or compute across multiple projects.
When you need to organize complex infrastructure into smaller, understandable parts.
When you want to share common infrastructure code with your team or across environments.
When you want to avoid repeating the same resource definitions in multiple places.
When you want to build layered infrastructure where one module uses other modules.
Config File - main.tf
main.tf
terraform {
  required_version = ">= 1.3.0"
}

provider "aws" {
  region = "us-east-1"
}

module "network" {
  source = "./modules/network"
  vpc_cidr = "10.0.0.0/16"
}

module "compute" {
  source = "./modules/compute"
  subnet_id = module.network.public_subnet_id
  instance_type = "t3.micro"
}

This file shows how to compose two modules: network and compute.

The network module creates a VPC and subnet. The compute module creates an EC2 instance inside the subnet created by the network module.

This pattern helps organize infrastructure by responsibility and reuse modules easily.

Commands
This command initializes the Terraform working directory. It downloads the modules and providers needed for the configuration.
Terminal
terraform init
Expected OutputExpected
Initializing the backend... Initializing provider plugins... - Finding latest version of hashicorp/aws... - Installing hashicorp/aws v4.60.0... - Installed hashicorp/aws v4.60.0 (signed by HashiCorp) Terraform has been successfully initialized! You may now begin working with Terraform. Try running "terraform plan" to see any changes that are required for your infrastructure.
This command shows what Terraform will create or change based on the composed modules before applying any changes.
Terminal
terraform plan
Expected OutputExpected
Refreshing Terraform state in-memory prior to plan... An execution plan has been generated and is shown below. Resource actions are indicated with the following symbols: + create Terraform will perform the following actions: # aws_vpc.main will be created + resource "aws_vpc" "main" { + cidr_block = "10.0.0.0/16" + id = (known after apply) } # aws_subnet.public will be created + resource "aws_subnet" "public" { + vpc_id = (known after apply) + cidr_block = "10.0.1.0/24" + id = (known after apply) } # aws_instance.web will be created + resource "aws_instance" "web" { + instance_type = "t3.micro" + subnet_id = (known after apply) + id = (known after apply) } Plan: 3 to add, 0 to change, 0 to destroy.
This command applies the planned changes and creates the infrastructure defined by the composed modules.
Terminal
terraform apply -auto-approve
Expected OutputExpected
aws_vpc.main: Creating... aws_vpc.main: Creation complete after 3s [id=vpc-0abcd1234efgh5678] aws_subnet.public: Creating... aws_subnet.public: Creation complete after 2s [id=subnet-0abcd1234efgh5678] aws_instance.web: Creating... aws_instance.web: Still creating... [10s elapsed] aws_instance.web: Creation complete after 15s [id=i-0abcd1234efgh5678] Apply complete! Resources: 3 added, 0 changed, 0 destroyed.
-auto-approve - Automatically approve the apply without prompting
This command shows the outputs defined by the modules, such as subnet IDs or instance IPs, to verify the composed infrastructure.
Terminal
terraform output
Expected OutputExpected
public_subnet_id = "subnet-0abcd1234efgh5678" instance_id = "i-0abcd1234efgh5678"
Key Concept

If you remember nothing else from this pattern, remember: compose small reusable modules by passing outputs from one as inputs to another to build organized and scalable infrastructure.

Common Mistakes
Not passing outputs from one module as inputs to another module.
Modules won't connect properly, causing errors or isolated resources that don't work together.
Always use module outputs as inputs when composing modules to link resources correctly.
Using relative paths incorrectly in the module source attribute.
Terraform cannot find the module code, causing initialization errors.
Use correct relative paths like "./modules/network" relative to the root module.
Not running terraform init after adding or changing modules.
Terraform won't download or update modules, causing plan or apply failures.
Always run terraform init after modifying module sources.
Summary
Use modules to organize infrastructure into reusable parts.
Pass outputs from one module as inputs to another to compose infrastructure.
Run terraform init, plan, and apply to deploy composed modules.