Exploring Terraform 1.15: Dynamic Sources, Variable Deprecation, and More
Terraform 1.15 introduces two powerful features that give module authors and practitioners greater flexibility: the ability to use variables dynamically in module sources and a formal way to deprecate variables and outputs. These enhancements streamline module versioning, reduce error-prone configuration, and improve the overall development experience. Below, we answer the most pressing questions about these updates.
1. What is the new const attribute for variables and how does it enable dynamic module sources?
The const attribute is a new boolean flag that you can set on a variable block. When set to true, it tells Terraform that the variable’s value must be known during terraform init—not just during plan or apply. This restriction allows the variable to be used in places that are evaluated early, such as module sources. For example:
variable "folder" {
type = string
const = true
}
Once declared as const, the variable can appear in a module source path: source = "./${var.folder}". This solves a long-standing limitation where dynamic module sources were impossible because init could not resolve variable values. Note that const cannot be combined with sensitive or ephemeral attributes, as those imply runtime-only evaluation.
2. How can you use const variables in module sources and what restrictions apply?
You can reference a const variable in a module source string as shown above. However, this works only if the variable is defined at the root level or in a parent module and passed down. For nested modules, the same requirement holds: the input variable to the child module must also be declared with const = true. Terraform checks during init that the source expression contains only const variables and literals. If you accidentally use a non-const variable or a local value, Terraform will raise an error before attempting to fetch the module. This ensures that all dependencies are fully resolved at initialization time, avoiding later surprises.
3. What is the variable and output deprecation feature in Terraform 1.15?
Module authors often need to rename or remove variables and outputs as their modules evolve. Previously, there was no built‑in way to mark these as deprecated. Terraform 1.15 adds a deprecated attribute to both variable and output blocks. When set to a string message, any usage of that variable or output triggers a warning diagnostic during terraform validate, plan, or apply. For instance:
variable "bad" {
deprecated = "Please use 'good' instead, this variable will be removed"
}
The deprecation also propagates: if you pass a value to a deprecated variable, or reference a deprecated output elsewhere, Terraform shows a warning. This gives module consumers clear guidance without breaking existing configurations.
4. How do you mark a variable as deprecated and what happens when it's used?
Simply add the deprecated string attribute to the variable block. When someone sets a value for that variable (via .tfvars, CLI, environment variable, or module input), Terraform prints a warning like: “Warning: Variable 'bad' is deprecated: Please use 'good' instead, this variable will be removed.” If the variable itself is defined at the root but never assigned a value, no warning is emitted. This is intentional—so you can deprecate a variable that defaults to something safe, but alert users only when they explicitly pass a value. The same mechanism works for outputs: referencing a deprecated output in a local or another output will generate a warning. For example:
output "old" {
value = ...
deprecated = "Please use 'new' instead"
}
Use locals.moduleUsage = module.myModule.old in root module triggers a warning.
5. Can you chain deprecated outputs? How does Terraform handle warnings?
Yes, you can create a “chain” of deprecation. For example, you might have a module that still exposes an old output, but you want to deprecate it gradually. You can define a new output that consumes the old (deprecated) output and mark the new output itself as deprecated. Terraform will emit only one warning—for the outermost deprecated output—not for the inner reference. This is designed to reduce noise while still signaling that the final value is not recommended. In the root module, you could write:
output "ancient" {
value = module.myModule.old
deprecated = "Please stop using this"
}
The warning will appear when someone uses ancient in their configuration, but the reference to module.myModule.old inside ancient does not produce an additional warning. This cleanly supports multi‑version transitions.
6. How does Terraform report errors for non‑const variables in module sources?
If you attempt to use a variable that is not marked const = true inside a module source, Terraform will show an error during terraform init. The error message clearly states that the variable must be declared with const = true to be used in that context. For instance, writing source = "./${var.env}" where env is a regular variable will fail. The same applies to any interpolations that involve locals or resource attributes—they cannot be resolved at init time. This strict check prevents misconfigurations and ensures that the module graph is fully determined before any network operations occur.
Related Discussions