Learning bite
Modules and environment boundaries
Reuse a configuration interface without confusing it with isolation.
On this page
Reuse a small piece before building a large abstraction
A Terraform module is a directory of configuration. The directory in which you run Terraform is the root module. It can call a child module, supplying inputs and receiving outputs. A module is useful when its interface explains a coherent capability; moving every resource into its own wrapper can instead make the configuration harder to follow.
Create a separate module-practice directory, leaving terraform-basics and its state untouched. Inside it create modules/service-label and environments/dev. Save modules/service-label/main.tf:
variable "environment" {
type = string
}
variable "service_name" {
type = string
}
resource "terraform_data" "label" {
input = "${var.environment}-${var.service_name}"
}
output "label" {
value = terraform_data.label.output
}
Save environments/dev/main.tf:
terraform {
required_version = ">= 1.12, < 2.0"
}
module "service" {
source = "../../modules/service-label"
environment = "dev"
service_name = "accounts"
}
output "service_label" {
value = module.service.label
}
Run terraform init, terraform validate, and terraform plan from environments/dev. Expect one proposed resource at module.service.terraform_data.label. The root can read the child's published label output; it does not reach into arbitrary internal resources. No apply is necessary for this exercise.
Change the consumer, not the shared implementation
Create environments/qa, copy only the dev root's main.tf into it, and change the input to environment = "qa". Initialize and plan there. The same child module now describes a qa-accounts label, with separate local state if later applied. Do not copy .terraform, state, or saved plans between roots.
A reusable module should document supported inputs, non-secret outputs, assumptions, and upgrade behavior. Root modules normally configure providers; children declare their requirements and receive configurations. Aliases allow deliberate provider mappings, such as a second region. Changing an AWS provider name to GCP does not translate AWS resource schemas into Google Cloud resources.
Remote modules also need version control. Registry sources support a version constraint; Git sources select a ref in the source URL. Provider lock files do not lock arbitrary remote modules. Pin reviewed module versions and inspect plans when upgrading.
Separate names from actual isolation
A CLI workspace gives one configuration/backend a separate state instance. Calling a workspace production does not supply different credentials, prevent access to another account, or isolate a network. Two root directories are also not a security barrier on their own.
For a real environment, identify four things explicitly: who can run changes, which account or target they can access, where its state is stored, and which inputs distinguish it. The local dev/qa directories demonstrate independent state without claiming production isolation.
Refactoring an already managed root resource into this child changes its address. Without a reviewed migration, Terraform can interpret the old address as removed and the new one as needing creation. A moved block can preserve identity when supported. Do not perform that refactor on the earlier fixture just to make its layout match this one.
Practice and answers
Change only the QA service_name to ledger and plan both roots. QA should propose a different label; dev's source input remains accounts. If both roots change, inspect whether you edited the shared child instead. Why initialize after adding a module call? Terraform must discover and install its module dependencies before planning.
Retain the two small roots as an example of reuse. If you chose to apply either, review and run its own destroy plan before removing its state. The platform module lesson later extends this interface into target-specific infrastructure.
References: module usage↗, developing modules↗, workspaces↗, and refactoring↗.
Your notes and evidence
Record observations, questions, or links to your work. Keep credentials out of your notes.
Back up or restore this path
Progress and notes stay in this browser. A backup contains only this learning path.