Terraform 1.15: Enhanced Module Sources and Variable Management

From Moocchen, the free encyclopedia of technology

Terraform 1.15 introduces powerful new features for managing modules and variables. This update empowers practitioners to use variables in module sources and deprecate module variables and outputs with ease. Let's explore the key questions about these enhancements.

What are dynamic module sources in Terraform 1.15?

Dynamic module sources allow you to reference variables within module source and version attributes. Previously, these values had to be hardcoded, limiting flexibility. Now, you can use a variable declared with the new const = true attribute inside module source strings, like source = "./${var.folder}". This is especially useful for environments where module paths depend on configuration. The const attribute signals that the variable can be evaluated during terraform init without needing to load the full state. Note that const is mutually exclusive with sensitive or ephemeral. If you attempt to use a non-const variable or a local inside a module source, Terraform will report an error during init.

Terraform 1.15: Enhanced Module Sources and Variable Management

How do I declare a constant variable for use during initialization?

To declare a constant variable, add const = true in the variable block. For example:

variable "folder" {
  type  = string
  const = true
}

This variable can then be used in a module source:

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

Only variables with const = true are allowed in module source and version attributes. The const attribute cannot be combined with sensitive or ephemeral. This ensures that Terraform can resolve the module path without loading full configuration or state.

Can dynamic module sources be used in nested modules?

Yes, but with a requirement. Nested modules can also use dynamic sources, provided their input variables are explicitly declared with const = true. This extends the benefit of dynamic sources across your entire module tree. If a nested module tries to use a non-const variable in its source, Terraform will emit an error during init. This constraint ensures that module paths are resolvable deterministically at initialization time, avoiding circular dependencies or incomplete data.

What is the new variable and output deprecation feature?

Terraform 1.15 introduces a deprecated attribute for both variable and output blocks. Module authors can now mark variables or outputs as deprecated, providing a deprecation message. When a user references a deprecated variable (e.g., by passing a value) or uses a deprecated output or resource, Terraform issues a warning diagnostic during validation. For example:

variable "bad" {
  deprecated = "Please use 'good' instead, this variable will be removed"
}

Similarly, outputs can be deprecated:

output "old" {
  value = ...
  deprecated = "Please use 'new' instead, this output will be removed"
}

This helps users gradually transition away from deprecated elements while keeping configurations functional.

How does deprecation work for module variables and outputs?

When a deprecated variable is used in a module call (e.g., bad = "value"), Terraform emits a warning diagnostic. Similarly, referencing a deprecated output (e.g., module.myModule.old) triggers a warning. Deprecation warnings also appear when a deprecated variable is provided via CLI arguments, environment variables, or in Terraform Cloud. This helps users verify that no lingering deprecated values remain. The warnings appear during terraform validate or plan, not during initialization, ensuring deprecation messages are visible before applying changes.

How can module authors gradually deprecate outputs?

To allow gradual deprecation, Terraform 1.15 permits deprecated values to be passed into other deprecated outputs without additional warnings. For instance, if a module output old is deprecated, and you use it in an output ancient that is also deprecated, only one warning is issued—for the outermost deprecated output. Example:

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

This avoids cascading warnings and gives module authors a clean way to phase out outputs without overwhelming users with repeated messages.

What happens when a deprecated variable is used in a module call?

When a value is passed to a deprecated variable in a module call (e.g., bad = "value"), Terraform emits a warning diagnostic during validation. The warning includes the deprecation message defined in the variable block. This applies to both root module variables and module input variables. The configuration still works—deprecated variables are not removed—but users are encouraged to update to the recommended alternative. This feature helps module authors communicate lifecycle changes without breaking existing configurations.