Terraform Tutorial — Modules Practice Exercises
Practice creating and using Terraform modules.
Exercise 1: Module Structure
Task: Create the file structure for a module called s3-bucket that creates an S3 bucket with versioning and tagging. List the files and their purpose.
Answer
modules/s3-bucket/
├── main.tf ← S3 bucket resource + versioning
├── variables.tf ← bucket_name, environment, tags
├── outputs.tf ← bucket_id, bucket_arn, bucket_domain
├── versions.tf ← Terraform and AWS provider constraints
└── README.md ← Usage documentation
Exercise 2: Write a Module
Task: Write variables.tf and outputs.tf for an S3 bucket module that accepts bucket_name (required) and environment (default: “dev”), and outputs the bucket ARN.
Answer
# modules/s3-bucket/variables.tf
variable "bucket_name" {
type = string
description = "Name of the S3 bucket"
}
variable "environment" {
type = string
default = "dev"
description = "Deployment environment"
}
# modules/s3-bucket/outputs.tf
output "bucket_arn" {
value = aws_s3_bucket.this.arn
description = "ARN of the S3 bucket"
}
output "bucket_id" {
value = aws_s3_bucket.this.id
description = "Name/ID of the S3 bucket"
}
Exercise 3: Call a Module
Task: Write the root module code that calls the s3-bucket module twice — once for a “logs” bucket and once for an “assets” bucket.
Answer
module "logs_bucket" {
source = "./modules/s3-bucket"
bucket_name = "myapp-logs-${var.environment}"
environment = var.environment
}
module "assets_bucket" {
source = "./modules/s3-bucket"
bucket_name = "myapp-assets-${var.environment}"
environment = var.environment
}
output "logs_bucket_arn" {
value = module.logs_bucket.bucket_arn
}
output "assets_bucket_arn" {
value = module.assets_bucket.bucket_arn
}
Chapter Summary
In this chapter, you learned:
- Modules eliminate copy-paste and enforce consistency
- Standard module structure:
main.tf,variables.tf,outputs.tf,versions.tf - Call modules with the
module {}block andsourceargument - Modules communicate through inputs (variables) and outputs
- The Terraform Registry has thousands of pre-built modules
- Always pin versions with
version = "~> X.Y" - Module sources: local paths, Git repos, S3 buckets, registry
Next up: Workspaces — managing multiple environments with isolated state.