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.

Mastering Terraform 1.15: Dynamic Module Sources and Deprecation Workflows

Prerequisites

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

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.

Tags:

Recommended

Discover More

AMD's Gaming Revenue Outlook: Memory Costs and Forecasted Decline - Q&AFrom Bruises to Diagnosis: Recognizing and Managing Medication-Induced HyperpigmentationTransitioning from Azure Data Studio to Visual Studio Code for SQL Server Development.NET 10 HybridCache Integration with Azure PostgreSQL Promises High-Performance Distributed Caching for Modern ApplicationsCRPG Combat Divide: Experts and Developers Weigh In on Turn-Based vs Real-Time-with-Pause