Quick Answer
# ❌ Don't quote type names
variable "name" {
type = "string" # Wrong — quotes make it a string literal
}
# ✅ Types are keywords, not strings
variable "name" {
type = string
}
The Error
Error: Invalid type specification
on variables.tf line 2, in variable "name":
2: type = "string"
A type specification is either a primitive type keyword (bool, number,
string) or a complex type constructor call, like list(string).
What Causes This
- Quoted type names —
"string"instead ofstring - Invalid type constructor —
array(string)instead oflist(string) - Missing parentheses —
list stringinstead oflist(string) - Old Terraform 0.11 syntax —
type = "list"was valid before 0.12
All Valid Types
Primitive Types
variable "name" { type = string } # "hello"
variable "count" { type = number } # 42, 3.14
variable "enabled" { type = bool } # true, false
Collection Types
variable "names" { type = list(string) }
# ["web", "api", "db"]
variable "ports" { type = list(number) }
# [80, 443, 8080]
variable "tags" { type = map(string) }
# { Environment = "prod", Team = "platform" }
variable "unique_ids" { type = set(string) }
# ["a", "b", "c"] — duplicates removed
Structural Types
# Object — fixed keys with types
variable "database" {
type = object({
engine = string
instance_class = string
port = number
multi_az = bool
})
}
# Tuple — fixed-length list with typed positions
variable "config" {
type = tuple([string, number, bool])
# ["web", 8080, true]
}
Nested Types
variable "ingress_rules" {
type = list(object({
port = number
protocol = string
cidr_blocks = list(string)
}))
}
variable "environment_tags" {
type = map(map(string))
# { prod = { owner = "ops" }, dev = { owner = "dev" } }
}
Optional Attributes (Terraform 1.3+)
variable "instance" {
type = object({
name = string
instance_type = string
monitoring = optional(bool, false) # Default: false
tags = optional(map(string), {}) # Default: {}
ebs_size = optional(number) # Default: null
})
}
Any Type
variable "flexible" {
type = any # Accepts anything — use sparingly
}
variable "mixed_list" {
type = list(any) # List of anything
}
Common Mistakes
| Wrong | Correct | Why |
|---|---|---|
type = "string" | type = string | Don’t quote keywords |
type = "list" | type = list(string) | Old TF 0.11 syntax |
type = array(string) | type = list(string) | No array type in HCL |
type = hash(string) | type = map(string) | No hash type |
type = dict(string) | type = map(string) | No dict type |
type = int | type = number | No int — use number |
type = float | type = number | No float — use number |
type = boolean | type = bool | It’s bool, not boolean |
Hands-On Courses
- Terraform for Beginners on CopyPasteLearn
- Terraform By Example — practical code examples
Conclusion
Type specifications are keywords (string, number, bool) or constructors (list(string), map(number), object({...})), never quoted strings. If upgrading from Terraform 0.11, replace type = "list" with type = list(string). Use optional() for object attributes with defaults.