Terraform

Designing Naming and Reuse with Terraform locals

2026-04-19
NicheeLab Editorial Team

locals are a mechanism for giving a name to expressions that appear repeatedly inside a module and reusing them. You can consolidate "rules that rarely change" — naming conventions, shared tags, and the like — in a single place.

This article focuses on the stable concepts a Terraform Associate candidate should understand, and the high-impact uses that pay off in practice.

locals: fundamentals and design principles

locals are named expressions scoped to a single module. They do not represent input values; they represent the result of transformations, joins, and default-value calculations. Reference them with local.<name>.

They are not evaluated in textual definition order; Terraform evaluates them based on the dependency graph, at the moment they are needed. They cannot be overridden from outside.

  • Scope is "that module only" — not shared between parent and child
  • Roles split cleanly: variable for input, locals for computation, output for external exposure
  • Centralizing conventions (naming, tags, suffixes/prefixes) improves maintainability
ConceptMeaningScopeSource
localsPre-computed named expressionCurrent moduleVariables, constants, other expressions
variableInput from outsideCurrent moduletfvars / CLI / environment variables / parent module
outputModule outputCurrent moduleValues inside the module
data sourceExternal readCurrent moduleProvider / API

Value flow centered on locals

Referenceable*.tfvars / CLISource of varvariablesdata sourceslocalsCentralized naming / tags / derived valuesresourcesmodules

Naming strategy: confine consistency and constraints inside locals

Naming constraints differ across clouds and providers, but the universal advice is to "centralize the rules in one place and reuse them across every resource." Consolidating name assembly inside locals localizes the blast radius of any convention change.

The recommended shape: put org, environment, app, and component into an array, combine with join, lowercase with lower, and use substr for length control when needed. Use regexreplace when you need to substitute disallowed characters.

  • Use name_parts = [org, env, app, component] as the canonical shape
  • join("-", compact(name_parts)) automatically skips empty elements
  • Standardize lowercasing and length control with lower and substr
  • Use regexreplace to sanitize disallowed characters in one shot
  • Generate the name in a single place and reference it from every resource

Reuse pattern examples (naming, tags, multiple components)

The example below uses locals to centralize naming and tags, and derives names for several components. To stay provider-agnostic, it is used through module calls.

The key is to finish the convention entirely within locals and pass "already-assembled names/tags" to modules as much as possible.

  • Combine compact and join for readable names
  • Build a common tag set with merge
  • Mass-produce component names with for_each and comprehensions
  • Pass only name_prefix and tags down to child modules

Centralizing naming and tags via locals (example)

variable "org"         { type = string }
variable "environment" { type = string }
variable "app"         { type = string }
variable "region"      { type = string }
variable "extra_tags"  { type = map(string) default = {} }

locals {
  env        = var.environment
  app        = var.app
  component  = "web"

  name_parts = [var.org, local.env, local.app, local.component]
  name       = lower(join("-", compact(local.name_parts)))
  name63     = substr(local.name, 0, 63)

  tags_base = {
    org = var.org
    env = local.env
    app = local.app
  }
  tags_common = merge(local.tags_base, var.extra_tags)

  component_names = toset(["web", "api", "db"])  # adjust as needed
  component_map   = { for c in local.component_names : c => lower(join("-", [var.org, local.env, local.app, c])) }
}

module "web" {
  source      = "./modules/web"
  name_prefix = local.name
  tags        = local.tags_common
}

module "components" {
  source      = "./modules/component"
  for_each    = local.component_map
  name        = each.value
  common_tags = local.tags_common
}

Environment switching: dividing roles between tfvars and locals

Push environment differences into variables and supply their values through per-environment tfvars. locals take those differences in and stay focused on producing "derived values" — names, tags, thresholds, and so on.

You can embed terraform.workspace in names, but leaning on workspaces to separate prod from staging is not recommended. Manage environments with explicit variables and tfvars to keep things reproducible.

  • Split files like env/dev.tfvars, env/stg.tfvars, env/prd.tfvars
  • locals consume the environment differences but stick to conventions and derived values
  • Avoid workspace-dependent naming; use var.environment as the source of truth

Module boundaries and evaluation order: the key points

locals are valid only within a module; parents and children cannot override or reference them. To share, expose values through outputs and pass them from parent to child through variables.

Evaluation follows the dependency graph, not declaration order. locals do not become known any earlier than their dependencies, so values that are unknown at plan time propagate as unknown. Cycles are errors.

  • Local values are immutable and cannot be overridden
  • locals that reference resources are allowed (resolved through dependencies)
  • Unknown values propagate as unknown; locals cannot "pin them down"

Associate exam prep and common pitfalls

At the Associate level, expect questions on the role of locals, how they differ from variables/outputs/data, their scope, and the canonical use cases (naming, tags, pre-computed constants).

The common real-world pitfall is misusing locals as if they were "configuration." Keep the basic pattern: input goes in variables, conventions and derivations go in locals, exposure goes in outputs.

  • Be able to explain that locals are not external input
  • Have a design example using locals to unify naming conventions and tags
  • Be ready to pick "separating environments with workspaces is not recommended"
  • Master evaluation-model basics like cycle detection and unknown-value propagation

Check Your Understanding

Associate

問題 1

Organizational policy requires every resource name to include org-env-app-component in lowercase, hyphen-separated. Which Terraform implementation is the most appropriate?

  1. Build name once in locals and pass that value (or prefix) to every resource and child module
  2. Repeat the same format expression in every resource, duplicating the logic, and manually update every resource when the rule changes
  3. Compute the name in an output and reference it from other resources in the same module
  4. Concatenate terraform.workspace directly into the name and rely on workspaces to separate environments

正解: A

Centralizing derivation and fixed logic like naming conventions in locals and reusing it is optimal. B explodes duplication, C misuses outputs, and D encourages a workspace-dependent design — all unsuitable.

Frequently Asked Questions

What is the difference between locals and variables?

variables are input values supplied from outside, while locals are named, pre-computed expressions derived from those values or constants. locals cannot be overridden and cannot be passed directly from outside the module.

Can a parent module override a child module's locals?

No. locals are an internal implementation detail of the module. Expose values you want to share via the child module's output, and pass them from the parent to another child through variables.

Can locals reference resource attributes? What about evaluation order?

Yes, they can. Terraform evaluates based on the dependency graph, so the order in which you write them does not matter. However, values that are unknown at plan time propagate as unknown into locals as well; locals cannot force them to become known.

Check what you learned with practice questions

Practice with certification-focused question sets

無料で問題を解いてみる
Author

NicheeLab Editorial Team

NicheeLab editorial team focused on data engineering and cloud certification learning. Content is structured around practical study needs and official exam domains.


Related articles
Terraform

HCL Syntax: Terraform's Configuration Language (2026)

HCL2 fundamentals for Terraform — blocks, attributes, expres...

Terraform

Terraform Authoring & Operations Pro: Complete Guide (2026)

Tactics for the Terraform Pro exam — module authoring, works...

Terraform

Terraform Providers: Plugin Management Fundamentals (2026)

Provider mechanics — required_providers, versions, mirrors, ...

Terraform

Terraform Resource Blocks: Declarative Infra Units (2026)

Resource block fundamentals — addresses, references, common ...

Terraform

Terraform Data Sources: Read-Only External Data (2026)

Data source basics — declaration, refresh behavior, dependen...

Browse all Terraform articles (102)
© 2026 NicheeLab All rights reserved.