BasicsLesson 4 of 16

Variables, Locals & Outputs

Parameterize infrastructure cleanly, reduce duplication, and expose the right values between stacks and modules without hardcoding environment-specific details.

🧒 Simple Explanation (ELI5)

Variables are the inputs you can change, locals are the helper values you calculate once and reuse, and outputs are the important results you want to show or pass to something else.

If Terraform files are a recipe, variables are ingredients you swap by environment, locals are shorthand notes that simplify the recipe, and outputs are the final values you hand to the next team.

🤔 Why Do We Need It?

🔧 Technical Explanation

hcl
variable "environment" {
  type    = string
  default = "dev"
}

locals {
  name_prefix = "platform-${var.environment}"
}

output "resource_group_name" {
  value = azurerm_resource_group.platform.name
}
ConceptBest Use
VariableInputs that change by environment, workspace, or caller
LocalDerived values and naming helpers inside the configuration
OutputValues exposed to callers, operators, or downstream automation

Good Terraform design makes inputs explicit, internal composition readable, and outputs intentional. Not every value should become an output.

Value Flow
Variables
Locals
Resources
Outputs
💡
Naming Pattern

Locals are especially useful for name prefixes, standard tags, and environment-aware identifiers. That keeps resources consistent without copying the same string logic everywhere.

🌍 Real-World Use Case

A platform module may take environment, location, and address_space as variables, build standard naming and tagging with locals, then output subnet IDs and resource group names for an AKS module or CI/CD pipeline to consume later.

🛠️ Hands-on

Reusable Azure Resource Group Example

hcl
variable "environment" {
  type = string
}

variable "location" {
  type    = string
  default = "eastus"
}

locals {
  rg_name = "rg-platform-${var.environment}"
  common_tags = {
    environment = var.environment
    managed_by  = "terraform"
  }
}

resource "azurerm_resource_group" "platform" {
  name     = local.rg_name
  location = var.location
  tags     = local.common_tags
}

output "resource_group_name" {
  value = azurerm_resource_group.platform.name
}

Try It Yourself

🐛 Debugging Scenario

Problem: Values are not changing between environments as expected.

⚠️
Common Mistake

Teams often overuse outputs and expose far more internal details than callers need. Keep outputs purposeful to avoid tight coupling between modules.

📋 Interview Questions

Beginner

What is a variable in Terraform?

A variable is an input value used to customize the configuration without editing the resource blocks directly.

What is a local value?

A local is an internal named expression used to simplify repeated or derived values in a configuration.

What is an output?

An output exposes a value from the Terraform configuration for operators, modules, or automation to consume.

Why not hardcode environment names everywhere?

Because it reduces reuse, increases mistakes, and makes multi-environment maintenance harder.

Where can variable values come from?

Defaults, tfvars files, environment variables, CLI arguments, or automation inputs.

Intermediate

When should you use locals instead of extra variables?

When the value is derived from other values and should not be set directly by the caller.

How do outputs help module composition?

They provide explicit values such as subnet IDs or resource names that other modules or pipelines can consume safely.

What is a sign a Terraform interface is badly designed?

Too many variables, unclear naming, and outputs that expose internal details the caller should not need to care about.

How do you keep variables safe for secrets?

Do not hardcode sensitive values. Use secret-aware input mechanisms and mark variables sensitive where appropriate.

What is the benefit of shared tagging through locals?

It enforces consistency and makes governance easier across many resources.

Scenario-Based

A module has 40 variables and nobody understands it. What do you do?

I reduce the interface to the real inputs that should be caller-controlled, move derived logic into locals, and split responsibilities if the module is doing too much.

A downstream pipeline depends on a Terraform output that keeps changing name. What is the lesson?

Outputs are part of the module interface and should be treated as stable contracts, especially when CI/CD or other stacks consume them.

How would you structure environment-specific values for AKS networking?

I would keep environment inputs explicit through variables or tfvars files, use locals for naming and tags, and output only the values later modules or pipelines truly need.

Why can defaults become dangerous in Terraform?

Because a silent default can provision into the wrong region, wrong size, or wrong environment if the caller forgets to override it intentionally.

How do you explain outputs to a beginner engineer?

They are the important values Terraform shows you after building something, like the name, ID, or endpoint another step will need.

🧾 Summary

Variables, locals, and outputs are how Terraform becomes reusable instead of hardcoded. Good value design makes infrastructure clearer, easier to compose, and safer to operate across environments.