HashiCorp Terraform 0.12 Preview: Rich Value Types
This is the sixth post of the series highlighting new features in Terraform 0.12.
As part of the lead up to the release of Terraform 0.12, we are publishing a series of feature preview blog posts. The post this week is on the addition of rich value types in variables and outputs.
Terraform variables and outputs today support basic primitives and simple lists and maps. Lists and maps in particular have surprising limitations that lead to unintuitive and frustrating errors. Terraform 0.12 allows the use of arbitrarily complex values for both input variables and outputs, and the types of these values can be exactly specified.
» Complex Values
Due to the new type system introduced in 0.12, Terraform now allows use of arbitrary collection values in both input variables and attributes.
Terraform has always supported primitive values (strings, numbers, booleans), and Terraform 0.7 added support for simple lists and maps. Unfortunately, due to limitations of the previous generation core of Terraform, lists and maps had a number of surprising limitations. Terraform 0.12 removes all of these limitations.
In Terraform 0.12, complex objects can now be passed to child modules as inputs, and returned to parent modules as outputs. The example below shows a purposely complex module using complex objects as variables:
# Configuration for Terraform 0.12
module "subnets" {
source = "./subnets"
parent_vpc_id = "vpc-abcd1234"
networks = {
production_a = {
network_number = 1
availability_zone = "us-east-1a"
}
production_b = {
network_number = 2
availability_zone = "us-east-1b"
}
staging_a = {
network_number = 1
availability_zone = "us-east-1a"
}
}
}
These values are then accessed like any other value in Terraform. In the above example, the subnets module could access network information using the new Terraform 0.12 For Expression: for network in var.networks
.
» Rich Types
Terraform providers and resources always expect specific data types to be provided. Terraform will continue to attempt to automatically convert a provided value to the expected type if it doesn't match. An error will be produced if this isn't possible.
Terraform 0.12 introduces a powerful type system that module authors can use to specify expected types for input variables. This forces values to be validated and converted properly if possible. This also improves the error messages shown to users of a module.
Terraform has always supported a very simple type requirement for variables. The example below uses Terraform 0.12 syntax, but showcases functionality that has been possible in Terraform for many years:
# Configuration for Terraform 0.12
variable "environment_name" {
type = string
}
Experienced Terraform users may notice that a difference is that string
is not quoted. Types are now first-class values in Terraform and can be used directly.
Terraform 0.12 can now also represent the types of complex object structures like those shown in the previous section. This was not possible in earlier versions of Terraform. The example below shows a type specification for the example above:
# Configuration for Terraform 0.12
variable "networks" {
type = map(object({
network_number = number
availability_zone = string
tags = map(string)
}))
}
This results in great validation for users of a Terraform configuration or module with clear error messages.
» Resources and Modules as Values
Building on this capability, Terraform 0.12 now permits using entire resources as object values within configuration, including returning them as outputs and passing them as input variables:
# Configuration for Terraform 0.12
output "vpc" {
value = aws_vpc.example
}
The type of this output value is an object type derived from the schema of the aws_vpc
resource type. The calling module can then access attributes of this result in the same way as the returning module would use aws_vpc.example
, such as module.example.vpc.cidr_block
.
This capability also works for modules themselves, with an expression like module.vpc
evaluating to an object value with attributes corresponding to the modules's named outputs.
» Upgrade Guide
The new type system does not introduce any breaking changes. Existing configurations should continue to work as-is. Terraform 0.12 remains compatibile with the simple type system in previous versions of Terraform.
» Next
This was part 6 of the blog post series previewing Terraform 0.12.
This new rich type system will be released in Terraform 0.12, coming later this summer. To learn more about how to upgrade to Terraform 0.12, read the upgrade instructions which will be continuously updated as we get closer to releasing Terraform 0.12. If you have any feedback or concerns about these changes, please communicate with the Terraform team via the public mailing list.
Sign up for the latest HashiCorp news
More blog posts like this one
New Terraform integrations with Crowdstrike, Datadog, JFrog, Red Hat, and more
12 new Terraform integrations from 9 partners provide more options to automate and secure cloud infrastructure management.
Terraform delivers launch-day support for Amazon S3 Tables, EKS Hybrid Nodes, and more at re:Invent
The Terraform provider for AWS now enables users to manage a variety of new services just announced at re:Invent.
HashiCorp at re:Invent 2024: Infrastructure Lifecycle Management with AWS
A recap of HashiCorp infrastructure news and developments on AWS from the past year, from a new provider launch to simplifying infrastructure provisioning and more.