»Dynamic module sources
With the Terraform 1.15 release, practitioners can now use variables within Terraform dependencies, encompassing aspects such as module sources and versions.
For example, we are introducing a new const attribute for variables. This attribute takes a boolean value (true/false) and signals whether the variable can be used during terraform init. Note that const cannot be used in conjunction with the sensitive or ephemeral attributes; they are mutually exclusive.
variable "folder" {
type = string
const = true
}
These variables can then be used in module sources:
module "zoo" {
source = "./${var.folder}"
}
This functionality extends to nested modules, provided their input variables are explicitly declared with const = true.
Terraform will report an error during init when you reference something else that is a variable or local.
»Module variable and output deprecation
As module authors update their module's lifecycle, they may need to deprecate existing variables and outputs. To support this, we are introducing a new attribute called deprecated for both variable and output blocks.
When using a deprecated variable or making a reference to a deprecated output or resource, a warning diagnostic will be issued during validation.
Below is an example of this:
# mod/main.tf
variable "bad" {
deprecated = "Please use 'good' instead, this variable will be removed"
}
# Some module code
output "old" {
value = ...
deprecated = "Please use 'new' instead, this output will be removed"
}
# main.tf
variable "root" {
deprecated = "This should no longer be used."
}
module "myModule" {
source = "./mod"
bad = "not good"
}
locals {
moduleUsage = module.myModule.old
}
The following diagnostics will be emitted by this example:
For
var.root: A diagnostic will be emitted if a value is passed in for this variable via CLI arguments, environment variables, or other means. This helps users verify that no lingering values remain in their environment (e.g., in TFC).For
module.myModule.bad: Diagnostics will be emitted from the module call because a value is being passed to the deprecated variablebad.For
locals.moduleUsage: Diagnostics will be emitted due to the reference to the deprecated output.For
locals.resourceUsage: If the resource is deprecated, a diagnostic will be emitted when it is referenced.
To give module authors a way of gradually managing deprecation of module outputs, we will allow deprecated values in deprecated outputs.
# mod/main.tf
output "old" {
value = ...
deprecated = "Please use 'new' instead, this output will be removed"
}
# main.tf
module "myModule" {
source = "./mod"
}
output "ancient" {
value = module.myModule.old
deprecated = "Please stop using this"
}
A diagnostic warning is emitted only when the output, output.ancient, is referenced in the calling module, not when the deprecated attribute, module.myModule.old, is used internally as a child module.
However, if this were the root module, using the deprecated attribute would result in a diagnostic error, informing the user that the deprecated attribute is not permitted on root-level outputs.
Other enhancements include improving the detection and detail of deprecation warnings within the CLI. These updates ensure provider-defined, specific messages about deprecated attributes or blocks are surfaced more consistently during planning and application.
»Inline type conversions
The new convert function, introduced in this release, enables precise, inline type conversions. This feature is designed to enhance the clarity of your HCL logic and significantly reduce the likelihood of errors.
While Terraform's type inference usually handles data assignment in configuration, several edge cases still pose challenges for users when the inferred types are incorrect. These issues often stem from situations like:
Conditional expressions where the opposing results have different inferred types
The absence of literal syntax for expressing specific collection values (e.g., maps, lists, or sets)
Equality comparisons where implicit type conversion does not occur
Users often struggle to create empty containers for complex types because of how Terraform interprets empty literal values. For example, {} is treated as an empty object that cannot have attributes, not an empty map that requires a specified element type. Similarly, [] is interpreted as an empty tuple with zero elements, not an empty list that needs an element type.
The convert function resolves this issue by explicitly allowing users to create these necessary zero values.
»Other enhancements
»Native Windows ARM64 builds
Terraform now officially supports Windows ARM64 binaries, enabling it to be used on devices such as the Surface Pro and the Windows Dev Kit 2023. This support also enables Terraform usage on Windows for ARM virtual machines running on Mac M1/M2 devices via Parallels.
»S3 backend: support authentication via AWS login
AWS recently introduced a new authentication method, aws login (AWS CLI v2.32.0+), enabling developers to use AWS Management Console credentials for programmatic access, thereby eliminating the need for long-term access keys. The AWS Provider for Terraform now includes native support for credentials generated via aws login.
»Type constraints for output blocks
Terraform now supports explicit type constraints within output blocks, a feature introduced to bring the same level of validation and documentation to outputs that has long existed for input variables.
output "string" {
type = string
value = var.some_string
}
»Terraform test: Allow functions within mock blocks
This enhancement enables the use of functions within mock blocks in the Terraform Test framework.The primary goal of this feature request is to enable the mocking of data and resources. This is necessary to correctly set dependency values — specifically in the required format, such as a GUID or resource ID — for the resource currently under development and testing.
To generate test data, you can create strings that match specific data types or formats:
GUID: Use the
uuid()functionAzure Resource ID: Use
format("/subscriptions/%s",uuid())
mock_data "azurerm_client_config" {
defaults = {
client_id = uuid()
}
}
override_resource {
target = azurerm_storage_account.example
values = {
id = format("/subscriptions/%s/resourceGroups/example/providers/Microsoft.Storage/storageAccounts/myaccount", uuid())
}
}
Error when trying to use a function:
Error: Function calls not allowed
│
│ on tests/mock_data/data.tfmock.hcl line 9, in mock_data "azurerm_client_config":
│ 9: client_id = uuid()
│
│ Functions may not be called here.
»Stacks variable validation blocks
This release continues to build the foundation for the wider Stacks ecosystem by introducing a validation block for variables on Stacks as a CLI feature.
Variable blocks now include support for a validation block, which contains condition and error_message attributes. The condition is a boolean expression that can reference the variable's value using var.value.
This feature is particularly beneficial for authors of reusable modules, as it allows them to enforce expectations early in the configuration process, preventing delayed errors that would otherwise only surface after a provider attempts an operation.
variable "prefix" {
type = string
validation {
condition = length(var.prefix) > 5
error_message = "prefix must be longer than 5 characters."
}
}
»Next steps
To get started with Terraform:
Review the Terraform 1.15 upgrade guide
Explore our Terraform tutorials
This release was made possible by the invaluable contributions and ongoing support from our community, including feedback via GitHub issues, HashiCorp Discuss forums and continuous input from our customers. For a comprehensive list of changes, please see the full Terraform 1.15 changelog.









