4.4.1. Complex Types
💡 First Principle: Type constraints catch mistakes early and document intent — declaring a variable as map(string) means Terraform rejects a list before anything is created, turning a runtime surprise into a clear configuration error.
Terraform types fall into three groups. Primitives: string, number, bool. Collection types (all elements the same type): list(...), set(...) (unordered, unique), map(...). Structural types (mixed element types): object({...}) (named attributes with types) and tuple([...]) (ordered, per-position types). There's also any (no constraint).
| Type | Shape | Example |
|---|---|---|
list(string) | Ordered, duplicates allowed | ["a", "b", "a"] |
set(string) | Unordered, unique | ["a", "b"] |
map(number) | Key→value, keys unique | { a = 1, b = 2 } |
object({...}) | Named attributes, mixed types | { name = "x", size = 3 } |
tuple([...]) | Ordered, fixed per-position types | ["x", 3, true] |
Instance identity: count vs for_each. count produces a list of instances addressed by zero-based index (aws_instance.web[0]) — even with count = 1 you index it — so removing an element from the middle of the driving list shifts every later index, and Terraform plans changes to those instances to match their new positions. for_each keys each instance by a map key or set member (aws_instance.web["us-east-1a"]), so adding or removing one key touches only that instance; prefer it whenever items come and go. for_each accepts only a map or a set of strings: wrap a list in toset(), which — like any conversion to a set(...) type — silently drops duplicates and order. Lists and tuples are addressed by zero-based position (var.zones[0] is the first element); only maps and objects are addressed by key or attribute name.
⚠️ Exam Trap: Know list vs set: a list is ordered and allows duplicates; a set is unordered and deduplicates. This matters for for_each (which needs a set or map of unique keys) versus count (which uses a list/number by index).
Reflection Question: Why is for_each typically used with a set or map rather than a list?