📖 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
Step 1: Understand module purpose
Terraform modules are designed to group related cloud resources together for reuse and better organization.
Step 2: Compare options
Only To group and reuse cloud resource configurations correctly describes this purpose. Other options describe unrelated tasks.
Final Answer:
To group and reuse cloud resource configurations -> Option A
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" }
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
Step 1: Understand file roles in module
In Terraform modules, variables.tf defines input variables the module accepts.
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.
Final Answer:
To define input variables for the module -> Option B
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
Step 1: Understand error meaning
"Unsupported argument" means the module does not expect the given input variable.
Step 2: Check module inputs
If db_name is not declared as a variable in the module's variables.tf, Terraform rejects it.
Final Answer:
The module does not declare an input variable named db_name -> Option C
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
Step 1: Define optional input variable
To make tags optional, define a variable with type map(string) and default empty map {}.
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.
Final Answer:
In variables.tf: variable "tags" { type = map(string) default = {} } -> Option D