What Is New in Terraform 0.15
Terraform 0.15 brings a set of focused enhancements that streamline workflows and tighten up the configuration language. The changes are less about flashy new features and more about refining the core experience for production use.
| Category | Key Changes |
|---|---|
| New Features | Optional object type attributes, Provider-defined sensitive inputs |
| Improvements | Enhanced CLI output, Improved `terraform console`, Refined `-replace` functionality |
| Deprecations & Removals | Final removal of legacy graph engine, Removal of various deprecated features |
| Bug Fixes | Numerous fixes across core and providers |
How does Terraform 0.15 handle sensitive data better?
Terraform 0.15 introduces first-class support for provider-defined sensitive inputs. This is a significant step up from the previous generic method of marking entire variables as sensitive.
Providers can now explicitly declare that certain input values are sensitive. When you use these inputs, Terraform's CLI UI will automatically redact their values from plan and apply output to prevent accidental exposure in logs. In practice, this means you get more granular and reliable protection for secrets like API keys and passwords without having to remember to mark the variable yourself.
What's new with Terraform's type system?
The Terraform type system gets a powerful addition: optional object type attributes. This allows module authors to define more flexible object structures where certain keys can be omitted.
Before 0.15, every attribute in an object type was mandatory. Now, you can define an object type with optional attributes, making your module interfaces cleaner and more intuitive. This matters because it reduces the need for workarounds with null defaults or separate variables for complex object structures.
variable "example" {
type = object({
required_attr = string
optional_attr = optional(string)
})
}
What CLI improvements should I expect?
The Terraform CLI output has been redesigned for better readability and consistency. The plan output is now more structured, making it easier to scan for changes, especially in complex infrastructures.
The terraform console command has also been upgraded with improved introspection capabilities and a better experience for experimenting with expressions. Furthermore, the -replace option for plan and apply, which was experimental in v0.14, is now stable and ready for use in forcing resource replacement.
What was finally removed in this release?
Terraform 0.15 completes the removal of the legacy graph engine, which was deprecated back in Terraform 0.12. The newer, more robust graph engine is now the only option.
This release also cleans up several other deprecated features and interpolation behaviors that have been throwing warnings for a few versions. If you've been keeping your configurations up-to-date, the upgrade should be smooth. If you've been ignoring deprecation warnings, now's the time to address them.
FAQ
Is the upgrade from Terraform 0.14 to 0.15 breaking?
It can be. This release removes several features that were previously deprecated. If your code has been free of deprecation warnings, the upgrade path is straightforward. If not, you'll need to address those warnings first.
How do optional object attributes work?
You define them with the new optional() type constructor. When creating an object of that type, you can omit the optional attributes, and Terraform will treat them as null. This simplifies creating flexible module interfaces.
What happens if I don't upgrade my providers for v0.15?
You can use older providers, but you won't benefit from new features like provider-defined sensitive inputs. The core Terraform v0.15 binary remains compatible with existing providers.
Why was the legacy graph engine removed?
The newer graph engine introduced in 0.12 is more reliable and performs better. Maintaining the old one added complexity without benefit, so it was finally phased out to streamline the codebase.
Should I use the new -replace option?
Yes, it's now stable. Use terraform plan -replace="aws_instance.example" to create a plan that forces the replacement of a specific resource, which is handy for tainted resources or imperative fixes.