Terraform 1.15: Dynamic Module Sources, Backend Validation, and Upgrade Gotchas
Terraform 1.15 is the kind of release that can break a quiet CI lane before anyone notices the changelog. The headline features are useful: Windows ARM64 builds, deprecated variables and outputs, the new convert() function, and variables or locals in module source and version. The sleeper change is backend validation.
If your pipeline runs terraform validate against incomplete backend configuration, Terraform 1.15 can now catch problems earlier. That is good. It can also expose the sloppy bootstrap assumptions teams have carried for years.

What Changed
The module source change will get the most attention because people have wanted dynamic module sources forever. Used carefully, it can remove wrapper scripts and generated HCL. Used loosely, it can make module resolution harder to reason about. Module source is part of supply-chain trust, not a place to hide clever string assembly.
Deprecated variables and outputs are more boring, and more useful. They let platform teams warn consumers before a breaking module cleanup. That is a nice fit with the upgrade discipline in Terraform testing in CI: warnings now become part of the contract.
Backend validation deserves a test run before the team upgrades local Terraform versions. A backend block that only worked because validation never looked closely at it may now fail in pre-commit, CI, or module validation jobs.
The Numbers That Matter
| Fact | Number or date | Source |
|---|---|---|
| Release | Terraform v1.15.0 | HashiCorp / GitHub |
| New build | Windows ARM64 | GitHub release notes |
| Validation change | terraform validate checks backend blocks |
GitHub release notes |
| New function | convert() for explicit type conversion |
GitHub release notes |
| Module change | variables and locals supported in module source and version |
GitHub release notes |
Those facts are the reason this post should be published now, not next quarter. The dates are fresh, the limits are concrete, and the operational impact is clear enough for an engineer to act on today.
How It Works in Practice
Upgrade one root module first. Run terraform init -backend=false, terraform validate, then the normal backend-enabled terraform init for the environment. That split tells you whether the failure is syntax, backend config, provider resolution, or state access.
Use deprecated on module interfaces you control. Do not wait until the removal PR. Give consumers at least one release window where warnings show them exactly what to change.
For module source variables, keep the source set finite. A local mapping from environment to known module source is easier to audit than a free-form variable that lets a pipeline download arbitrary module code.
variable "legacy_bucket_name" {
type = string
default = null
deprecated = "Use bucket_config.name instead."
}
locals {
module_ref = {
prod = "git::https://github.com/example/platform-vpc.git//modules/vpc?ref=v4.2.0"
dev = "git::https://github.com/example/platform-vpc.git//modules/vpc?ref=v4.2.0"
}
}
module "vpc" {
source = local.module_ref[var.environment]
}
Gotchas I Would Check First
- Dynamic module sources can create a supply-chain blind spot if users can pass arbitrary source strings.
- Backend validation may fail jobs that previously validated modules without complete backend context.
- The S3 backend AWS FIPS and dual-stack environment variables now only respect
trueorfalsevalues.
Decision Guide
| Feature | Use now? | Recommendation |
|---|---|---|
| Deprecated variables/outputs | Yes | Low risk and good module hygiene |
| Backend validation | Yes | Add CI coverage before broad rollout |
| Dynamic module sources | Carefully | Restrict to known mappings |
convert() |
Yes | Good for explicit type boundaries |
For related background, keep these existing BitsLovers posts close: Terraform testing in CI, Terraform ephemeral resources, Terraform for_each patterns, Terraform state locking with S3 and DynamoDB, Terraform stacks and state management.
Sources
- Terraform v1.15.0 release
- Terraform changelog
- HashiCorp Discuss release post
- Terraform language docs
Upgrade Terraform 1.15 like an IaC release, not a CLI refresh. Test backend validation and module resolution before it lands on every runner.
Comments