Bird
Raised Fist0
Terraformcloud~5 mins

Creating a child module in Terraform - Step-by-Step CLI Walkthrough

Choose your learning style10 modes available
Introduction
Sometimes your infrastructure code gets big and hard to manage. Creating a child module lets you split your code into smaller parts that you can reuse and organize better.
When you want to reuse the same infrastructure setup in different places without copying code.
When your main Terraform file is too long and you want to make it easier to read.
When you want to share infrastructure code with your team in a clean way.
When you want to separate different parts of your infrastructure logically.
When you want to test or update parts of your infrastructure independently.
Config File - main.tf
main.tf
module "my_child_module" {
  source = "./child_module"
  instance_count = 2
  instance_name = "example-instance"
}

output "child_instance_ids" {
  value = module.my_child_module.instance_ids
}

This is the main Terraform file that calls the child module.

module "my_child_module": This block tells Terraform to use the child module located in the child_module folder.

source: Path to the child module folder.

instance_count and instance_name: Variables passed to the child module.

output: This outputs the instance IDs created by the child module.

Commands
This command initializes Terraform in the current directory. It downloads the child module and prepares the working directory.
Terminal
terraform init
Expected OutputExpected
Initializing the backend... Initializing provider plugins... Terraform has been successfully initialized! You may now begin working with Terraform. Try running "terraform plan" to see any changes.
This command shows what Terraform will do when you apply the configuration. It checks the child module and shows the planned changes.
Terminal
terraform plan
Expected OutputExpected
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_instance.example[0] will be created + resource "aws_instance" "example" { + ami = "ami-12345678" + instance_type = "t2.micro" + tags = { + "Name" = "example-instance-0" } } Plan: 2 to add, 0 to change, 0 to destroy.
This command applies the changes to create the infrastructure defined in the child module. The -auto-approve flag skips the confirmation prompt.
Terminal
terraform apply -auto-approve
Expected OutputExpected
aws_instance.example[0]: Creating... aws_instance.example[1]: Creating... aws_instance.example[0]: Creation complete after 10s [id=i-0abcd1234efgh5678] aws_instance.example[1]: Creation complete after 10s [id=i-0abcd1234efgh5679] Apply complete! Resources: 2 added, 0 changed, 0 destroyed. Outputs: child_instance_ids = ["i-0abcd1234efgh5678", "i-0abcd1234efgh5679"]
→
-auto-approve - Automatically approve the apply without asking for confirmation
This command shows the output value from the child module, which is the list of instance IDs created.
Terminal
terraform output child_instance_ids
Expected OutputExpected
["i-0abcd1234efgh5678", "i-0abcd1234efgh5679"]
Key Concept

If you remember nothing else from this pattern, remember: a child module is a separate folder with its own Terraform files that you call from your main code to organize and reuse infrastructure.

Common Mistakes
Not specifying the correct source path for the child module.
Terraform cannot find the child module and will give an error.
Use a relative path like "./child_module" that points exactly to the folder containing the child module files.
Forgetting to pass required variables to the child module.
Terraform will fail because the child module expects variables that are missing.
Always pass all required variables in the module block in the main Terraform file.
Not running terraform init after adding a child module.
Terraform will not download or recognize the new module, causing errors.
Run terraform init to initialize and download modules before planning or applying.
Summary
Create a child module in a separate folder with its own Terraform files.
Call the child module from the main Terraform file using a module block with source and variables.
Run terraform init to initialize modules, terraform plan to preview changes, and terraform apply to create resources.
Use terraform output to see values returned from the child module.

Practice

(1/5)
1. What is the main purpose of creating a child module in Terraform?
easy
A. To avoid using variables in Terraform
B. To break down infrastructure into smaller, reusable pieces
C. To increase the number of resources in the root module
D. To deploy resources only in one cloud provider

Solution

  1. Step 1: Understand module purpose

    Child modules help organize infrastructure by splitting it into smaller parts.
  2. Step 2: Identify benefits

    This makes code reusable and easier to manage across projects.
  3. Final Answer:

    To break down infrastructure into smaller, reusable pieces -> Option B
  4. Quick Check:

    Child modules = reusable infrastructure parts [OK]
Hint: Child modules = smaller reusable parts of infrastructure [OK]
Common Mistakes:
  • Thinking child modules increase resource count in root
  • Believing child modules remove need for variables
  • Assuming child modules limit to one cloud provider
2. Which Terraform block correctly includes a child module located in the folder ./modules/network?
easy
A. variable "network" { source = "./modules/network" }
B. resource "network" { source = "./modules/network" }
C. provider "network" { source = "./modules/network" }
D. module "network" { source = "./modules/network" }

Solution

  1. Step 1: Identify correct block type

    Child modules are included using the module block in Terraform.
  2. Step 2: Check syntax for source

    The source attribute points to the child module folder path.
  3. Final Answer:

    module "network" { source = "./modules/network" } -> Option D
  4. Quick Check:

    Use module block with source path [OK]
Hint: Use module block with source path to include child module [OK]
Common Mistakes:
  • Using resource or provider blocks instead of module
  • Placing source inside resource or variable blocks
  • Incorrect block type for including modules
3. Given this root module code:
module "web" {
  source = "./modules/webserver"
  instance_count = 3
}

And the child module variables.tf contains:
variable "instance_count" {
  type = number
}

What will be the value of var.instance_count inside the child module?
medium
A. 3
B. 0
C. null
D. 1

Solution

  1. Step 1: Check variable passing

    The root module passes instance_count = 3 to the child module.
  2. Step 2: Confirm variable usage

    The child module declares instance_count variable to receive this value.
  3. Final Answer:

    3 -> Option A
  4. Quick Check:

    Passed variable value = 3 [OK]
Hint: Passed variable values appear inside child module as given [OK]
Common Mistakes:
  • Assuming default or null if variable is declared
  • Confusing variable names or missing passing
  • Thinking child module variables reset automatically
4. You wrote this root module code:
module "db" {
  source = "./modules/database"
  db_name = "prod"
}

But Terraform shows an error: An argument named "db_name" is not expected here. Did you mean to define a variable named "db_name"?
What is the likely cause?
medium
A. Terraform does not support passing variables to modules
B. The source path is incorrect
C. The child module does not declare a variable named db_name
D. The root module must use resource block instead of module

Solution

  1. Step 1: Analyze error message

    The error indicates that the argument "db_name" is not expected, which happens when the child module does not declare a variable named "db_name".
  2. Step 2: Check child module variables

    If child module does not declare variable "db_name", Terraform cannot accept the passed value.
  3. Final Answer:

    The child module does not declare a variable named db_name -> Option C
  4. Quick Check:

    Passing undeclared argument causes "not expected" error [OK]
Hint: Declare variables in child module to accept passed values [OK]
Common Mistakes:
  • Ignoring variable declaration in child module
  • Assuming source path error without checking variables
  • Thinking modules can't receive variables
5. You want to create a child module that provisions an AWS S3 bucket with a customizable name and versioning enabled by default. Which of the following variables.tf and main.tf snippets inside the child module is the best practice?
hard
A. variables.tf:
variable "bucket_name" { type = string }
variable "versioning" { type = bool, default = true }

main.tf:
resource "aws_s3_bucket" "bucket" {
  bucket = var.bucket_name
  versioning {
    enabled = var.versioning
  }
}
B. variables.tf:
variable "bucket_name" { type = string, default = "mybucket" }
variable "versioning" { type = string }

main.tf:
resource "aws_s3_bucket" "bucket" {
  bucket = var.bucket_name
  versioning {
    enabled = var.versioning
  }
}
C. variables.tf:
variable "bucket_name" { type = string }
variable "versioning" { type = string, default = "true" }

main.tf:
resource "aws_s3_bucket" "bucket" {
  bucket = var.bucket_name
  versioning {
    enabled = var.versioning
  }
}
D. variables.tf:
variable "bucket_name" { type = number }
variable "versioning" { type = bool }

main.tf:
resource "aws_s3_bucket" "bucket" {
  bucket = var.bucket_name
  versioning {
    enabled = var.versioning
  }
}

Solution

  1. Step 1: Check variable types and defaults

    Bucket name should be string without default to force user input. Versioning is boolean with default true.
  2. Step 2: Validate resource usage

    Resource uses var.bucket_name and var.versioning correctly with boolean type for versioning enabled.
  3. Final Answer:

    variables.tf with string and bool (default true), main.tf using these variables correctly -> Option A
  4. Quick Check:

    Correct types and defaults = variables.tf:
    variable "bucket_name" { type = string }
    variable "versioning" { type = bool, default = true }

    main.tf:
    resource "aws_s3_bucket" "bucket" {
      bucket = var.bucket_name
      versioning {
        enabled = var.versioning
      }
    }
    [OK]
Hint: Use correct variable types and defaults for best practice [OK]
Common Mistakes:
  • Using string type for boolean variables
  • Setting wrong default types
  • Using number type for bucket name
Recommended

Ready to prove it?

Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard