Bird
Raised Fist0
Terraformcloud~10 mins

Module structure and conventions in Terraform - Step-by-Step Execution

Choose your learning style10 modes available
Process Flow - Module structure and conventions
Create module folder
↓
Add main.tf, variables.tf, outputs.tf
↓
Define resources in main.tf
↓
Declare input variables in variables.tf
↓
Declare outputs in outputs.tf
↓
Use module block in root configuration
↓
Pass variables to module
↓
Run terraform init and apply
This flow shows how to organize a Terraform module with standard files, define inputs and outputs, and use the module in a root configuration.
Execution Sample
Terraform
module "example" {
  source = "./modules/example"
  instance_count = 2
}

output "instance_ids" {
  value = module.example.instance_ids
}
This code uses a module named 'example' from a local folder, passing an input variable and exposing an output.
Process Table
StepActionFile AffectedDetailsResult
1Create module foldermodules/example/New folder created for moduleFolder ready for module files
2Add main.tfmodules/example/main.tfDefine resources like aws_instanceResources defined
3Add variables.tfmodules/example/variables.tfDeclare input variables like instance_countInputs declared
4Add outputs.tfmodules/example/outputs.tfDeclare outputs like instance_idsOutputs declared
5Use module blockroot configurationReference module with source and inputsModule block ready
6Run terraform initroot folderInitialize modules and providersModules downloaded and initialized
7Run terraform applyroot folderApply configuration and create resourcesResources created, outputs available
8Access outputroot folderUse output value from moduleOutput instance_ids available
9Exit-All steps completed successfullyInfrastructure deployed
💡 All module structure steps completed and infrastructure deployed successfully
Status Tracker
VariableStartAfter Step 5After Step 7Final
instance_countundefined2 (passed to module)2 (used to create resources)2
instance_idsundefinedundefinedlist of created instance IDslist of created instance IDs
Key Moments - 3 Insights
Why do we separate variables.tf, main.tf, and outputs.tf in a module?
Separating these files helps organize inputs, resource definitions, and outputs clearly, as shown in steps 2-4 of the execution_table.
How does the root configuration pass values to the module?
The root configuration uses a module block with input variables assigned, like instance_count=2 in step 5, which the module uses to create resources.
How do outputs from the module become accessible in the root?
Outputs declared in outputs.tf (step 4) are exposed via module.<name>.<output> syntax in the root, as seen in step 8.
Visual Quiz - 3 Questions
Test your understanding
Look at the execution_table, at which step are input variables declared inside the module?
AStep 3
BStep 2
CStep 5
DStep 7
💡 Hint
Check the 'File Affected' column for variables.tf in the execution_table.
According to variable_tracker, what is the value of instance_count after step 7?
Alist of instance IDs
B2
Cundefined
D0
💡 Hint
Look at the 'After Step 7' column for instance_count in variable_tracker.
If you forget to declare outputs in outputs.tf, what happens when you try to access module outputs in the root?
AOutputs are accessible but empty
BTerraform creates outputs automatically
CTerraform shows an error that output does not exist
DTerraform ignores the module
💡 Hint
Refer to key_moments about how outputs declared in outputs.tf become accessible.
Concept Snapshot
Terraform modules are organized in folders with main.tf for resources,
variables.tf for inputs, and outputs.tf for outputs.
Root configurations use module blocks to call modules,
passing variables and accessing outputs.
This structure keeps code clean and reusable.
Full Transcript
This visual execution shows how to structure a Terraform module with separate files for resources, inputs, and outputs. First, create a module folder and add main.tf, variables.tf, and outputs.tf files. Define resources in main.tf, declare input variables in variables.tf, and outputs in outputs.tf. Then, in the root configuration, use a module block to reference the module folder and pass input variables. Running terraform init downloads and initializes the module. Terraform apply creates the resources using the inputs. Outputs declared in the module become accessible in the root via module.<name>.<output>. Variables like instance_count start undefined, get assigned when passed to the module, and are used to create resources. Outputs like instance_ids become available after apply. This modular approach organizes code and enables reuse.

Practice

(1/5)
1. What is the main purpose of using a Terraform module?
easy
A. To group and reuse cloud resource configurations
B. To write scripts for cloud providers
C. To store cloud provider credentials
D. To monitor cloud resource usage

Solution

  1. Step 1: Understand module purpose

    Terraform modules are designed to group related cloud resources together for reuse and better organization.
  2. Step 2: Compare options

    Only To group and reuse cloud resource configurations correctly describes this purpose. Other options describe unrelated tasks.
  3. Final Answer:

    To group and reuse cloud resource configurations -> Option A
  4. Quick Check:

    Module purpose = reuse and grouping [OK]
Hint: Modules group resources for reuse and clarity [OK]
Common Mistakes:
  • Confusing modules with scripts
  • Thinking modules store credentials
  • Assuming modules monitor usage
2. Which of the following is the correct way to call a module named network located in a folder modules/network?
easy
A. module "network" { source = "modules/network" }
B. resource "network" { source = "modules/network" }
C. module network { path = "modules/network" }
D. resource "network" { path = "modules/network" }

Solution

  1. Step 1: Identify module call syntax

    Terraform uses module "name" { source = "path" } to call modules.
  2. Step 2: Check options

    Only module "network" { source = "modules/network" } uses correct module block and source attribute.
  3. Final Answer:

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

    Module call uses module block and source [OK]
Hint: Use module block with source attribute for calling modules [OK]
Common Mistakes:
  • Using resource instead of module
  • Using path instead of source
  • Omitting quotes around module name
3. Given this module folder structure:
modules/
  webserver/
    main.tf
    variables.tf
    outputs.tf
What is the purpose of the variables.tf file inside the module?
medium
A. To declare output values from the module
B. To define input variables for the module
C. To write the main resource definitions
D. To store provider configurations

Solution

  1. Step 1: Understand file roles in module

    In Terraform modules, variables.tf defines input variables the module accepts.
  2. Step 2: Match options

    To define input variables for the module correctly states this. Outputs are in outputs.tf, main resources in main.tf, and provider configs are outside modules.
  3. Final Answer:

    To define input variables for the module -> Option B
  4. Quick Check:

    variables.tf = input variables [OK]
Hint: variables.tf defines inputs; outputs.tf defines outputs [OK]
Common Mistakes:
  • Confusing variables.tf with outputs.tf
  • Putting resource code in variables.tf
  • Adding provider config inside module
4. You wrote this module call:
module "db" {
  source = "modules/database"
  db_name = "prod"
}
But Terraform shows an error: "Unsupported argument: db_name". What is the likely cause?
medium
A. The source path is incorrect
B. Module names cannot contain underscores
C. The module does not declare an input variable named db_name
D. db_name should be declared inside main.tf

Solution

  1. Step 1: Understand error meaning

    "Unsupported argument" means the module does not expect the given input variable.
  2. Step 2: Check module inputs

    If db_name is not declared as a variable in the module's variables.tf, Terraform rejects it.
  3. Final Answer:

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

    Input variables must be declared to be used [OK]
Hint: Declare input variables in module to avoid unsupported argument errors [OK]
Common Mistakes:
  • Assuming source path causes unsupported argument
  • Thinking module names restrict underscores
  • Trying to declare inputs inside main.tf
5. You want to create a reusable module for deploying a virtual machine with optional tags. Which structure correctly supports optional tags with a default empty map?
hard
A. In variables.tf: variable "tags" { type = list(string) }
B. In main.tf: variable "tags" { default = null }
C. In outputs.tf: output "tags" { value = var.tags }
D. In variables.tf: variable "tags" { type = map(string) default = {} }

Solution

  1. Step 1: Define optional input variable

    To make tags optional, define a variable with type map(string) and default empty map {}.
  2. Step 2: Evaluate options

    In variables.tf: variable "tags" { type = map(string) default = {} } correctly defines this in variables.tf. In main.tf: variable "tags" { default = null } lacks type and uses null default. In outputs.tf: output "tags" { value = var.tags } is output, not input. In variables.tf: variable "tags" { type = list(string) } uses list instead of map.
  3. Final Answer:

    In variables.tf: variable "tags" { type = map(string) default = {} } -> Option D
  4. Quick Check:

    Optional map variable needs default empty map [OK]
Hint: Use map(string) with default {} for optional tags [OK]
Common Mistakes:
  • Using list instead of map for tags
  • Not setting a default value
  • Declaring variables in outputs.tf
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