Resources, variables, outputs and references
🎯You'll be able to
Read and write Terraform's language: resources, references between them, input variables with validation, locals, outputs and count.
🏠The everyday picture
A recipe for a family-size biryani says "rice: 2 cups per 4 people". The number of people is the input; the quantities follow from it. Change one number and the whole recipe adjusts, without rewriting it.
📘What it really is
-
Terraform files end in
.tfand use HCL. Terraform reads every.tffile in the folder together; the split intomain.tf,variables.tfandoutputs.tfis a convention for people. -
A resource is one thing to manage:
hcl resource "docker_volume" "db" { name = "${local.prefix}-db" }docker_volumeis the type (from the provider) anddbis your name for it. Its address isdocker_volume.db. -
References connect resources:
volume_name = docker_volume.db.name. Terraform builds a dependency graph from them, so the volume is created before the container that uses it. Usedepends_ononly for dependencies Terraform can't see from references. -
Input variables make one configuration serve many situations:
hcl variable "app_count" { type = number default = 2 validation { condition = var.app_count >= 1 && var.app_count <= 8 error_message = "app_count must be between 1 and 8." } }Set them with-var app_count=3, a.tfvarsfile, or an environment variableTF_VAR_app_count=3. Files ending.auto.tfvarsare read automatically (Project 2's pipeline and Project 3's autoscaler use this). -
Locals are named values inside the configuration:
locals { prefix = "routerani-${var.env}" }, used aslocal.prefix. -
Outputs publish values for people and tools:
output "app_version" { value = var.app_version }, read withterraform output -raw app_version. -
countmakes several copies:count = var.app_countcreatesdocker_container.app[0],[1]and so on;count.indexis each copy's number, anddocker_container.app[*].namelists all names.for_eachdoes the same over a map or set of names, which is safer when items are added or removed from the middle. -
Checks before applying:
terraform fmtlays files out consistently (-checkfails if anything needs formatting), andterraform validatechecks the configuration is well formed.
📝A worked example
Input: add the app_count variable above and change the app resource to count = var.app_count, with
name = "${local.prefix}-app-${count.index}". Run terraform plan -var app_count=3.
Expected output: the plan shows docker_container.app[0], [1] and [2]. Running terraform plan -var app_count=9 fails before
planning with app_count must be between 1 and 8. That validation protects you from a typo that would start 90 copies.
🌍Where it's used
- Environment sizes: the same files with
instance_count = 2in staging and12in production. - Regions and teams:
for_eachover a list of cities or teams to create one bucket or network each. - Pipelines read outputs such as a database address or load balancer URL to configure the next step.
📝Case scenario
A media company's Terraform had the number of video servers written in six places. During a cricket final, an engineer raised it in five of them; the sixth, in a load balancer rule, kept sending traffic to only the old servers. After the match they replaced the six numbers with one variable referenced everywhere, so one change updated all of them.
🖱️Try it
Run terraform console in infra/ and type local.prefix, then var.env, then upper(local.prefix), then exit. Success: you can
evaluate expressions against your configuration without changing anything.
⚠️Common mistakes
- Copying values instead of referencing. Sign: the same name or number appears in several places. Fix: one variable or local, referenced everywhere.
- Overusing
depends_on. Sign: slow, tangled plans. Fix: rely on references; adddepends_ononly for hidden dependencies. countfor things with identities. Sign: removing the middle item replaces every later one. Fix: usefor_eachkeyed by name.
🛠️For your project
Project 1 adds the app_version and app_count variables and the app_containers and app_version outputs, which the pipeline and the
autoscaler read.
✅Quick check
How does Terraform know to create the volume before the container?
Show the answer
The container refers to the volume, and Terraform orders work from those references.
How do you set a variable without editing a file?
Show the answer
-var name=value, or an environment variable TF_VAR_name.
