Terraform Advanced — Modules at Scale Exercises
Practice module design and versioning.
Exercise 1 — Module Interface
Task: Design the variables.tf and outputs.tf for an S3 bucket module with: bucket name, versioning toggle, encryption type, and tags.
Answer
# variables.tf
variable "name" { type = string; description = "Bucket name" }
variable "versioning" { type = bool; default = true; description = "Enable versioning" }
variable "encryption" {
type = string
default = "aws:kms"
description = "SSE algorithm (aws:kms or AES256)"
validation {
condition = contains(["aws:kms", "AES256"], var.encryption)
error_message = "Must be aws:kms or AES256"
}
}
variable "tags" { type = map(string); default = {} }
# outputs.tf
output "bucket_id" { value = aws_s3_bucket.this.id }
output "bucket_arn" { value = aws_s3_bucket.this.arn }
output "bucket_url" { value = "s3://${aws_s3_bucket.this.id}" }
Exercise 2 — Version Constraint
Task: Write the version constraint that allows minor and patch updates but blocks major version bumps from v2.
Answer
module "vpc" {
source = "org/vpc/aws"
version = ">= 2.0.0, < 3.0.0"
# Or equivalently:
# version = "~> 2.0"
}
Exercise 3 — Wrapper Module
Task: Write a wrapper module for terraform-aws-modules/s3-bucket/aws that enforces: versioning always on, SSE-KMS always on, public access always blocked.
Answer
module "s3" {
source = "terraform-aws-modules/s3-bucket/aws"
version = "4.1.0"
bucket = var.name
# Enforced: always on
versioning = { enabled = true }
server_side_encryption_configuration = {
rule = {
apply_server_side_encryption_by_default = {
sse_algorithm = "aws:kms"
}
}
}
block_public_acls = true
block_public_policy = true
ignore_public_acls = true
restrict_public_buckets = true
tags = merge(var.tags, { ManagedBy = "terraform" })
}
Chapter Summary
- Single responsibility: One module, one concern
- Stable interface: Don’t rename/remove variables in minor versions
- Semantic versioning: MAJOR (breaking), MINOR (new feature), PATCH (bugfix)
- Registry publishing:
terraform-<provider>-<name>naming convention - Wrapper pattern: Enforce org standards around community modules