Jump into concepts and practice - no test required
or
Recommended
Test this pattern10 questions across easy, medium, and hard to know if this pattern is strong
Dependency inversion with modules
📖 Scenario: You are building a Terraform configuration to deploy cloud infrastructure. You want to organize your code using modules so that your main configuration depends on module outputs, not on internal details. This approach helps keep your code clean and flexible.
🎯 Goal: Create a Terraform project with a root module and a child module. The root module will use the child module's output to configure a resource, demonstrating dependency inversion by relying on module outputs instead of internal variables.
📋 What You'll Learn
Create a child module with a variable and an output
Create a root module that calls the child module
Use the child module's output in the root module to configure a resource
Follow Terraform best practices for module usage and dependency inversion
💡 Why This Matters
🌍 Real World
Organizing Terraform code into modules with clear inputs and outputs is a common practice in real-world cloud infrastructure projects. It helps teams manage complexity and reuse code.
💼 Career
Understanding dependency inversion with Terraform modules is important for cloud engineers and DevOps professionals to build scalable, maintainable infrastructure as code.
Progress0 / 4 steps
1
Create the child module with a variable and output
Create a Terraform module in a folder called child_module. Inside it, create a file variables.tf with a variable called instance_name of type string. Then create a file outputs.tf with an output called instance_name_output that outputs the value of the variable instance_name.
Terraform
Hint
Define a variable block with the exact name instance_name and type string. Then define an output block named instance_name_output that returns var.instance_name.
2
Create the root module and call the child module
In the root module, create a main.tf file. Add a module block named child that uses the source ./child_module. Pass the string "my-instance" to the module variable instance_name.
Terraform
Hint
Use a module block with the exact name child. Set source to ./child_module and pass instance_name = "my-instance".
3
Use the child module output in the root module resource
In the root module main.tf, add a resource block of type null_resource named example. Set the resource's triggers argument to a map with a key instance_name and value from the child module output module.child.instance_name_output.
Terraform
Hint
Create a null_resource named example. Inside, set triggers to a map with key instance_name and value module.child.instance_name_output.
4
Add output in root module to expose child module output
In the root module main.tf, add an output block named root_instance_name that outputs the value of module.child.instance_name_output.
Terraform
Hint
Define an output block named root_instance_name that returns module.child.instance_name_output.
Practice
(1/5)
1. What does dependency inversion mean in Terraform modules?
easy
A. Modules cannot accept variables
B. Modules depend on inputs instead of creating resources themselves
C. Modules always create all resources internally
D. Modules must be written in the root configuration
Solution
Step 1: Understand module dependency principle
Dependency inversion means modules should not create resources directly but rely on inputs.
Step 2: Identify correct description
Modules depend on inputs instead of creating resources themselves correctly states modules depend on inputs, making them flexible and reusable.
Final Answer:
Modules depend on inputs instead of creating resources themselves -> Option B
Quick Check:
Dependency inversion = Modules use inputs [OK]
Hint: Modules get resource info via inputs, not by creating resources [OK]
Common Mistakes:
Thinking modules must create all resources internally
Assuming modules cannot accept variables
Believing modules must be in root config
2. Which of the following is the correct way to pass a resource ID to a module in Terraform?
easy
A. module "example" { resource_id = aws_instance.example.id }
B. module "example" { input_id = aws_instance.example.id }
C. module "example" { instance_id = var.instance_id }
D. module "example" { instance_id = aws_instance.example.id }
Solution
Step 1: Identify correct variable passing syntax
Modules accept variables by name; the value can be a resource attribute like aws_instance.example.id.
Step 2: Check option correctness
module "example" { instance_id = aws_instance.example.id } correctly passes instance_id with the resource ID aws_instance.example.id.
Final Answer:
module "example" { instance_id = aws_instance.example.id } -> Option D
Quick Check:
Pass resource ID as variable = module "example" { instance_id = aws_instance.example.id } [OK]
Hint: Use variable name = resource.attribute to pass IDs [OK]
Common Mistakes:
Using undefined variable names like resource_id or input_id
Inside the module, the variable is declared as variable "subnet" { type = string }. What error will occur?
medium
A. Error: Unknown variable 'subnet_id' in module
B. Error: Variable 'subnet' not provided
C. No error, variable names can differ
D. Error: aws_subnet.app.id is invalid
Solution
Step 1: Compare variable name and input argument
The module expects a variable named 'subnet' but the input is 'subnet_id'.
Step 2: Understand Terraform variable matching
Terraform matches input arguments to variable names exactly. 'subnet_id' does not match any variable, causing an unsupported argument error.
Final Answer:
Error: Unknown variable 'subnet_id' in module -> Option A
Quick Check:
Variable name mismatch causes unknown variable error [OK]
Hint: Variable names must match exactly between module and call [OK]
Common Mistakes:
Assuming variable names can differ
Confusing variable name with resource attribute name
Ignoring error messages about missing variables
5. You want to create a reusable module for an AWS security group that attaches to any VPC. Which approach follows dependency inversion best?
hard
A. Module accepts a VPC ID as input and creates security group in that VPC
B. Module hardcodes a VPC ID inside the module code
C. Module requires the user to create security group outside and passes its ID
D. Module creates its own VPC and security group inside
Solution
Step 1: Understand dependency inversion for modules
Modules should not create dependent resources like VPCs but accept them as inputs.
Step 2: Evaluate options for best practice
Module accepts a VPC ID as input and creates security group in that VPC accepts VPC ID as input and creates the security group inside that VPC, following dependency inversion.
Final Answer:
Module accepts a VPC ID as input and creates security group in that VPC -> Option A
Quick Check:
Pass dependencies as inputs for flexibility [OK]
Hint: Pass VPC ID as input; module creates resources inside it [OK]
Common Mistakes:
Hardcoding resource IDs inside modules
Modules creating dependent resources themselves
Requiring users to create resources outside without module help