Terraform 1.15 was just released, let’s take a look at the new language features!
TL;DR
- Use variables (with
const = trueset) in the modulesourceandversionfields. - Use
deprecated = "Please use XYZ instead"onvariableandoutputblocks to deprecate them. - Use
convert([[1, 2, 3]], set(list(number)))to convert values to a specific complex type. - Outputs now have a
typeattribute like variables do
Content
- Dynamic Module Sources
- Marking Variables and Outputs as Deprecated
- Precise inline type conversion with
convert - Type Constraints for output blocks
- Enhancements
Dynamic Module Sources
Making module sources dynamic was one of the most requested issues, so I am really happy we could finally ship it! Shout-out to my friend Daniel Banck for making it a reality.
Let’s take this example:
# Source: https://github.com/DanielMSchmidt/demo-tf-module-sources-and-deprecation/blob/d56dfe645f6d02eaf29dffc58a1b70ce1c562d29/dynamic-sources/main.tf#L1-L30
variable "s3_bucket_source" {
const = true
default = "terraform-aws-modules/s3-bucket/aws"
// or my fork at github.com/DanielMSchmidt/terraform-aws-s3-bucket
}
variable "word" {
default = "hello"
const = true
}
locals {
public_s3_bucket_source = "terraform-aws-modules/s3-bucket"
default_s3_version = "5.12.0"
}
module "s3-bucket" {
source = var.s3_bucket_source
version = var.s3_bucket_source == local.public_s3_bucket_source ? local.default_s3_version : null
}
module "word" {
source = "./${var.word}-world"
}
output "out" {
value = module.word.out
}
You can see we use the new const variable attribute which allows the variable to be present (and if no default is set requires them) during terraform init and all operations that load the config.
Turns out there are a lot of operations that load the config, e.g. terraform show, terraform test, and terraform validate to name the most used ones. If your configuration makes use of const variables you will need to make sure to run them with the correct variables. You can supply them as you would with normal variables right now (-vars flag, vars files, environment vars, etc).
Daniel Banck will write a blog post about the ins and outs of this feature soonish, I’ll link it here when it is ready.
Marking Variables and Outputs as Deprecated
If you are writing modules used by multiple projects / people / teams you might have run into a situation where you want to change the the outside contract of your module. Before Terraform 1.15 you don’t have a chance to communicate this to your users efficiently doing the breaking change and increasing the major version.
With Terraform 1.15’s deprecation feature you can now warn them ahead of time by adding deprecated = "Your personal message on how to upgrade" to your output / variable block. The user will see a warning during terraform validate / terraform plan / terraform apply when the input value is supplied or the output value is used.
This should help module consumers to update their configuration ahead of a breaking change and make upgrading the modules major version easier as a result.
You can read more about this in my blog post:
Precise inline type conversion with convert
We have a new convert function that takes a value and a type and converts the values underlying type to the given type constraint (or fails if they are not compatible). They way Terraform / HCL handles types through go-cty there can be subtle bugs where two values might look equal but or not due to a difference in their type. This function will help against these kinds of issues. See the PR and the linked comments for reference.
Type Constraints for output blocks
With Terraform 1.15 output blocks will have a type attribute similar to variables. This will help enforce and communicate expected types for the output. terraform validate will fail if the type constraint is not met. This should be a small but super helpful addition!
Enhancements
terraform validatenow validates the backend block- S3 Backend now supports
aws loginauthentication terraform initwith dev overrides skips dependencies declared in the override - scratching my own itch here, this was so annoying 😂terraform testsupports functions insidemockblocks