Bird
Raised Fist0
Terraformcloud~30 mins

Module structure and conventions in Terraform - Mini Project: Build & Apply

Choose your learning style10 modes available
Terraform Module Structure and Conventions
📖 Scenario: You are creating a reusable Terraform module to deploy a simple AWS S3 bucket. This module will be used by other teams to quickly create buckets with standard settings.
🎯 Goal: Build a Terraform module with proper structure and naming conventions that defines an AWS S3 bucket resource with input variables and outputs.
📋 What You'll Learn
Create a Terraform module folder structure with main.tf, variables.tf, and outputs.tf files
Define an AWS S3 bucket resource in main.tf
Add input variables for bucket name and versioning in variables.tf
Add an output for the bucket ARN in outputs.tf
💡 Why This Matters
🌍 Real World
Terraform modules help teams reuse infrastructure code safely and consistently across projects.
💼 Career
Knowing how to build and structure Terraform modules is essential for cloud engineers and DevOps professionals managing infrastructure as code.
Progress0 / 4 steps
1
Create the Terraform module main configuration
In the main.tf file, write the Terraform code to create an AWS S3 bucket resource named my_bucket using the variable bucket_name for the bucket's name.
Terraform
Hint

Use resource "aws_s3_bucket" "my_bucket" {} and set bucket = var.bucket_name.

2
Add input variables for bucket name and versioning
In the variables.tf file, define two input variables: bucket_name of type string without a default, and enable_versioning of type bool with a default value of false.
Terraform
Hint

Use variable "bucket_name" { type = string } and variable "enable_versioning" { type = bool default = false }.

3
Add versioning configuration to the S3 bucket
In the main.tf file, add a versioning block inside the aws_s3_bucket.my_bucket resource. Set enabled to the variable enable_versioning.
Terraform
Hint

Add a versioning block with enabled = var.enable_versioning inside the bucket resource.

4
Add output for the bucket ARN
In the outputs.tf file, create an output named bucket_arn that returns the ARN of the aws_s3_bucket.my_bucket resource.
Terraform
Hint

Use output "bucket_arn" { value = aws_s3_bucket.my_bucket.arn }.

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