Terraform 1.15 Deep Dive: Dynamic Module Sources and Variable Deprecation Explained

Terraform 1.15 introduces two powerful features that give module authors and practitioners more flexibility and better lifecycle management. First, the new const attribute lets you flag variables as usable during terraform init, enabling dynamic module sources. Second, the deprecated attribute for variables and outputs allows authors to gently phase out old parameters while guiding users to replacements. Below, we answer key questions about these features, with code examples and practical tips.

What is the new const attribute and how does it enable dynamic module sources?

The const attribute is a boolean option you add to a variable block. When set to true, it signals that the variable can be resolved during terraform init. This allows you to use that variable in module source paths, as shown here:

Terraform 1.15 Deep Dive: Dynamic Module Sources and Variable Deprecation Explained
variable "folder" {
  type  = string
  const = true
}

module "zoo" {
  source = "./${var.folder}"
}

Before 1.15, module sources had to be static strings because Terraform evaluated them before variables were resolved. With const = true, Terraform now treats that variable as a constant—it cannot change after initialization, and it must not be marked as sensitive or ephemeral (those attributes are mutually exclusive). This feature works recursively for nested modules, but each input variable in the chain must also be declared with const = true. If you try to use a non-const variable or a local value in a module source, Terraform will report an error during init.

How does Terraform 1.15 support variable and output deprecation?

Module authors can now add a deprecated string attribute to variable and output blocks. The value is a human-readable message advising users of the alternative. When Terraform validates the configuration, it scans for any usage of that deprecated item—whether it's assigning a value to a deprecated variable, reading a deprecated output, or referencing a deprecated resource—and issues a warning diagnostic. For example:

# mod/main.tf
variable "bad" {
  deprecated = "Please use 'good' instead, this variable will be removed"
}

If you call the module and pass a value to bad, you'll see a warning. This gives users time to migrate before the variable is removed entirely. The deprecation message appears during terraform plan and terraform validate, not during init, so it's a lightweight reminder.

Can you give an example of using deprecated variables in module calls?

Certainly. Suppose you have a root module that defines a variable root with deprecated, and a submodule that also has a deprecated variable. Here's a complete example:

# mod/main.tf
variable "bad" {
  deprecated = "Please use 'good' instead, this variable will be removed"
}

output "old" {
  value = ...
  deprecated = "Please use 'new' instead"
}
# main.tf
variable "root" {
  deprecated = "This should no longer be used."
}

module "myModule" {
  source = "./mod"
  bad    = "not good"  # triggers warning
}

locals {
  moduleUsage = module.myModule.old  # triggers warning for deprecated output
}

When you run terraform validate, it will emit three diagnostics: one for var.root if a value is passed externally (e.g., via CLI or environment variable), one for module.myModule.bad because you're passing a value to a deprecated variable, and one for locals.moduleUsage because it references the deprecated output. This helps both module consumers and authors ensure no lingering usage remains.

What happens when you reference a deprecated output?

When your configuration references a deprecated output (either directly or through a local value), Terraform issues a warning diagnostic during validation. For example, if a module exposes output "old" { deprecated = "..." } and you write locals { x = module.myModule.old }, you'll see a message like: Warning: Deprecated output reference – use 'new' instead. The diagnostic includes the deprecation message you wrote. Importantly, the warning only appears when you actually use that output. Simply declaring it in the module (but not referring to it) does not trigger a warning. This allows module authors to keep deprecated outputs in place for backward compatibility without cluttering every user's output. However, if the output itself is used in another deprecated output, the warning is suppressed for that intermediate usage (see next question).

How can module authors gradually manage deprecation of outputs?

Module authors often need to replace an output while keeping the old one available for a transition period. Terraform 1.15 allows what we call deprecated value chaining. You can reference a deprecated output inside a new deprecated output, and only the outermost usage triggers a warning. For instance:

# mod/main.tf
output "old" {
  value = ...
  deprecated = "Please use 'new' instead"
}
# main.tf
module "myModule" {
  source = "./mod"
}

output "ancient" {
  value = module.myModule.old
  deprecated = "Please stop using this"
}

If a user references module.myModule.old directly, they get a warning pointing to new. But if they only reference output.ancient, they get a warning about ancient instead—not about old. This lets you create a deprecation chain so users don't see double warnings. You can later remove output "old" entirely after everyone has migrated to ancient (or directly to new). It's a clean, user-friendly way to phase out outputs.

Are there any restrictions on using const with other attributes?

Yes. The const attribute is mutually exclusive with sensitive and ephemeral. That means you cannot mark a variable as both constant and sensitive, or constant and ephemeral. The reason is practical: a constant variable must be available during terraform init, which runs before the full configuration is evaluated. Sensitive and ephemeral values are often computed or injected later, so they cannot be guaranteed to be known at init time. If you attempt to combine them, Terraform will produce an error. Also, const only accepts true or false (it defaults to false). Only variables with const = true can be used in module sources; regular variables, locals, and other expressions are forbidden in those positions. If you try, Terraform will report an error during init, preventing the configuration from being loaded.

Tags:

Recommended

Discover More

Curiosity's Wheels After Six Years on Mars: A Detailed Q&AAmazon Extends Price History Feature to a Full Year, Empowering Shoppers with Deeper InsightsOffice Snack Shortage Triggers Anxiety Epidemic: Psychologists Identify 'Chicken Little' SyndromeCyberattacks on Polish Water Utilities: ICS Breaches and Public Safety Risks10 Shocking Facts About Alaska’s 500-Meter Tsunami That No One Heard About