What Is New in Terraform 0.13
This release introduces major enhancements for module management and provider configuration, making large-scale Terraform codebases more flexible and maintainable.
| Category | Key Changes |
|---|---|
| New Features | Custom Validation Rules, Count/For_Each for Modules, Depends_On for Modules |
| Provider Improvements | Implicit Provider Inheritance, Custom Provider Installation Methods |
| Language Enhancements | Extended Configuration Syntax, New Functions |
| Backend & CLI | Enhanced Remote Backend Support, CLI Output Formatting |
How does module composition improve in 0.13?
You can now use count, for_each, and depends_on directly with module blocks. This fundamentally changes how we build reusable infrastructure components.
Before, you had to wrap modules in complex parent modules to achieve similar patterns. Now, you can conditionally include modules or create multiple instances from a single declaration. This makes DRY principles much easier to apply across your Terraform code.
For example, creating multiple similar VPCs is now straightforward:
module "vpc" {
for_each = var.vpc_configs
source = "./modules/vpc"
cidr = each.value.cidr
name = each.key
}
What are custom validation rules for variables?
Variable blocks now support a validation block for writing custom rules. This catches configuration errors at plan time rather than during apply.
You can define validation rules that check variable values against any logic you need. The validation runs early in the Terraform workflow, preventing invalid configurations from reaching your infrastructure.
Here's how to validate an input variable:
variable "instance_type" {
type = string
validation {
condition = can(regex("^t3.", var.instance_type))
error_message = "Must use a t3 series instance type."
}
}
How does provider inheritance work now?
Providers are now automatically inherited by modules unless explicitly overridden. This simplifies provider configuration management across complex module trees.
In practice, you define providers once at the root level and child modules automatically use them. This eliminates the need for repetitive provider passing through every module. You only need to specify providers when you want to use different configurations.
The old explicit provider passing approach still works, but the implicit inheritance reduces boilerplate code significantly in most cases.
What new functions were added?
Terraform 0.13 introduces several new functions including startswith, endswith, reverse, and strcontains for better string manipulation.
These functions fill gaps in the interpolation language, making it easier to write complex expressions without resorting to external data sources or workarounds. The reverse function is particularly useful for working with lists and maps in unconventional orders.
For example, checking if a string ends with a specific suffix:
locals {
is_production = endswith(var.environment, "prod")
}
FAQ
Can I use count with any module?
Yes, but modules using count cannot have providers passed explicitly. They automatically inherit providers from the parent module, which is usually what you want anyway.
Do I need to change my existing modules for 0.13?
Most existing modules will work without changes. The new features are additive. You might want to update modules to take advantage of validation and cleaner provider configuration.
How does depends_on work with modules?
Module-level depends_on creates explicit dependencies between entire modules, not just resources. This is useful when one module's configuration depends on another module's setup completion, even if no specific resources are referenced.
Are there any breaking changes?
The 0.13 release maintains backward compatibility with 0.12. The main considerations are around provider installation changes, but existing configurations should continue to work without modification.
What happens to provider configurations in child modules?
Child modules now implicitly inherit provider configurations from their parent. If you need different provider settings, you must explicitly define them in the module block using the providers argument.