At some point, most Terraform users hit a moment where a simple list just isn’t strict enough. You want structure. You want predictability. You want Terraform to complain early when something is off.
That’s exactly where tuple type constraints in Terraform step in.
What is a Tuple in Terraform?
A tuple is an ordered collection of elements where each position has a fixed type. Unlike lists, tuples are not just “a bunch of similar items.” Each index is expected to hold a specific type.
Here’s the simplest way to think about it:
- List → all elements must be the same type
- Tuple → each element can have a different type, but the structure is fixed
Quick Example
1variable "server_config" {
2 type = tuple([string, number, bool])
3}
4This means:
- Index 0 → must be a string
- Index 1 → must be a number
- Index 2 → must be a boolean
Terraform will enforce this strictly.
Using Tuple in Practice
Let’s make this a bit more real-world. Imagine you’re defining a compact server configuration:
1variable "server_config" {
2 type = tuple([string, number, bool])
3}
4
5# Example input
6server_config = ["t3.micro", 2, true]
7You can access elements like this:
1locals {
2 instance_type = var.server_config[0]
3 disk_size = var.server_config[1]
4 is_production = var.server_config[2]
5}
6This is compact—but also fragile if not documented properly.
Where Tuples Actually Shine
Here’s where things get interesting. Tuples aren’t just a quirky alternative to lists—they solve specific problems.
1. Enforcing Structure in Module Inputs
If your module expects a very specific structure, tuples ensure callers don’t accidentally pass invalid data.
1variable "db_settings" {
2 type = tuple([string, number])
3}
4This guarantees:
- A database engine (string)
- A port number (number)
2. Fixed-Length Data
Unlike lists, tuples enforce the exact number of elements.
1type = tuple([string, string])This ensures exactly two values—no more, no less.
3. Lightweight Alternatives to Objects
Sometimes you don’t need a full object with named attributes. Tuples can be a compact alternative.
But this comes with trade-offs (we’ll get there).
Tuple vs List: A Common Source of Confusion
Developers often mix these up, especially when starting with Terraform.
| Feature | Tuple | List |
|---|---|---|
| Element types | Mixed | Uniform |
| Length | Fixed | Variable |
| Validation strictness | High | Moderate |
| Readability | Lower | Higher |
A quick comparison:
1# List example
2variable "names" {
3 type = list(string)
4}
5
6# Tuple example
7variable "mixed" {
8 type = tuple([string, number])
9}
10If all elements are the same type, use a list. If structure matters, consider a tuple.
A Subtle Gotcha (That Bites Hard)
A common mistake developers make is assuming tuples are self-documenting. They are not.
This input:
1["t3.micro", 2, true]Doesn’t tell you much unless you already know the order.
Compare that with an object:
1{
2 instance_type = "t3.micro"
3 disk_size = 2
4 production = true
5}The object is far more readable.
Rule of thumb: If humans need to read or maintain it, prefer objects over tuples.
Combining Tuples with Other Types
Terraform allows nesting tuples with other complex types, which opens up interesting patterns.
Example: Tuple Inside a List
1variable "servers" {
2 type = list(tuple([string, number]))
3}
4
5servers = [
6 ["web", 2],
7 ["api", 3]
8]
9Each tuple represents a server role and instance count.
Example: Tuple with Objects
1variable "config" {
2 type = tuple([
3 string,
4 object({
5 cpu = number
6 memory = number
7 })
8 ])
9}
10This mixes strict ordering with structured data.
Validation Behavior You Should Know
Terraform validates tuples at plan time. If the input doesn’t match exactly, you’ll get a clear error.
Invalid value for variable: element 1 must be number
This early feedback is one of the biggest advantages of using strict type constraints.
When Not to Use Tuples
Tuples can be tempting, but they’re not always the right tool.
- If readability matters → use object
- If size varies → use list
- If order doesn’t matter → use set
Tuples are best when:
- The structure is fixed
- The order is meaningful
- You want strict validation
A More Maintainable Alternative
If you find yourself documenting tuple positions in comments, that’s a sign you probably want an object instead.
1# Instead of this
2variable "config" {
3 type = tuple([string, number, bool])
4}
5
6# Prefer this
7variable "config" {
8 type = object({
9 instance_type = string
10 disk_size = number
11 production = bool
12 })
13}
14You trade compactness for clarity—and in most teams, that’s a win.
Final Thoughts
Terraform tuple type constraints are powerful, but they’re also a bit niche. They shine when you need strict, positional data with guaranteed types. Outside of that, they can make configurations harder to read and maintain.
If you’re building reusable modules, tuples can enforce discipline. But if you’re building something meant for humans to understand quickly, you’ll often reach for objects instead.
Use tuples deliberately—not by default.