Mastering Terraform 1.15: Dynamic Module Sources and Deprecation Workflows
Overview
Terraform 1.15 introduces two powerful capabilities that streamline infrastructure management: dynamic module sources and a formal deprecation mechanism for variables and outputs. These features give practitioners more flexibility in composing configurations and help module authors communicate lifecycle changes clearly. This guide walks through both features with practical examples, prerequisites, step-by-step instructions, and common pitfalls.
Prerequisites
- Terraform 1.15 or later installed (
terraform versionshould show 1.15 or higher) - Basic familiarity with Terraform modules, variables, and outputs
- A working Terraform project (e.g., a simple root module and a child module) for experimentation
Step-by-Step Instructions
1. Defining a Constant Variable with const
The new const attribute on a variable block marks it as usable during terraform init. This is essential for dynamic module sources because initialisation must resolve source paths before full evaluation. The const attribute accepts a boolean value (true or false) and is mutually exclusive with sensitive and ephemeral.
variable "folder" {
type = string
const = true
}
When const = true, Terraform treats the variable as a compile-time constant. Any attempt to use a non-constant expression (like a local variable or another variable without const) in a source will produce an error during terraform init.
2. Using Constant Variables in Module Sources
Once you have a variable declared with const = true, you can reference it in a module source:
module "zoo" {
source = "./${var.folder}"
}
This pattern works for any module source string, including remote sources like git::..., as long as the variable value is known at initialisation time. Nested modules can also use constant variables, provided their input variables are explicitly declared with const = true.
Important: The variable must be defined at the root module level; you cannot use const in child modules for sources that depend on parent variables.
3. Deprecating a Variable
To deprecate a variable, add a deprecated attribute with a string message explaining the replacement:
# mod/main.tf
variable "bad" {
deprecated = "Please use 'good' instead; this variable will be removed in a future version"
}
When someone passes a value to this variable (via CLI, environment variable, or .tfvars), Terraform emits a warning diagnostic during validation. The warning also appears if the variable is referenced elsewhere. For root module variables, the diagnostic fires only when a value is supplied—this helps detect leftover assignments.
4. Deprecating an Output
Similarly, outputs can carry a deprecated attribute:
# mod/main.tf
output "old" {
value = module.some_resource.id
deprecated = "Please use 'new' output instead"
}
Any reference to a deprecated output in the root module (or another module) triggers a warning diagnostic. This includes uses in output, locals, and module blocks.
5. Chaining Deprecated Outputs
Terraform 1.15 allows a deprecated output to use a value from another deprecated output without producing a double warning. The warning appears only at the outermost reference:
# mod/main.tf
output "old" {
value = "some value"
deprecated = "Use 'new' instead"
}
# main.tf
module "myModule" {
source = "./mod"
}
output "ancient" {
value = module.myModule.old
deprecated = "Please stop using this"
}
In this case, a reference to module.myModule.old will not issue a warning if it appears inside another deprecated output. Only the consumer of output.ancient sees a warning. This enables gradual deprecation across module boundaries.
Common Mistakes
- Using
constwithsensitiveorephemeral: These attributes are mutually exclusive. Terraform will produce a validation error. - Expecting non-constant variables in sources: Only variables declared with
const = trueare allowed. Using a regular variable or a local in a module source causes an init-time error. - Deprecating a variable but still requiring it: The
deprecatedattribute does not remove the variable; it only warns. If you later remove the variable, ensure no references remain. - Ignoring warning diagnostics: Warnings are not errors. Users can still apply configurations, but they indicate that future versions will break. Always address them during migration.
- Nested module variable deprecation without
const: Whiledeprecatedworks anywhere, dynamic sources requireconst. Don't mix the two concepts.
Summary
Terraform 1.15’s const attribute unlocks dynamic module sources by marking variables usable during initialisation. The deprecated attribute on variables and outputs provides a clean, standardised way to signal lifecycle changes without breaking existing configurations. By following the patterns in this guide, you can build more flexible modules and manage deprecation gracefully. Always test deprecation notices in a development environment before rolling out changes.