Expressions, types and conditionals

Terraform · Essentials · 10 min

Almost every non-trivial configuration transforms lists and maps; HCL expressions are how.

HCL values have types: string, number, bool, and collections list(...), set(...), map(...), plus structural object({...}) and tuple([...]). Terraform converts between them automatically where safe ("5" to 5), and errors where not.

Expressions you'll use constantly:

  • Interpolation: "web-${var.env}".
  • Conditional: var.env == "prod" ? 3 : 1. Both branches must have compatible types.
  • Operators: ==, !=, &&, ||, !, arithmetic, comparisons.
  • Indexing: var.subnets[0], var.tags["team"], var.cfg.size.
  • Splat: aws_instance.web[*].id gives the list of IDs from a counted resource.
  • for expressions: [for s in var.names : upper(s)] builds a list; {for k, v in var.sizes : k => v * 2} builds a map; add if to filter: [for u in var.users : u.name if u.admin].
  • null means "unset", so an argument set to null behaves as if omitted, handy in conditionals.

Experiment interactively with terraform console, which evaluates expressions against your configuration and state: the fastest way to debug a tricky for expression.

Example

variable "env" {
  type    = string
  default = "prod"
}

variable "users" {
  type = list(object({ name = string, admin = bool }))
  default = [
    { name = "ana", admin = true },
    { name = "bo", admin = false },
  ]
}

locals {
  replicas = var.env == "prod" ? 3 : 1
  admins   = [for u in var.users : u.name if u.admin]
  by_name  = { for u in var.users : u.name => u.admin }
}

output "replicas" { value = local.replicas } # 3
output "admins"   { value = local.admins }   # ["ana"]
output "by_name"  { value = local.by_name }  # { ana = true, bo = false }

Remember

  • Conditionals: cond ? a : b with compatible types
  • for expressions build lists [...] and maps {...}, with optional if
  • Splat [*] collects an attribute; terraform console for experiments

Watch out for

  • Mixing types in a conditional (a list on one side, a string on the other), which fails to evaluate.

Check yourself

  1. What is [for n in [1, 2, 3, 4] : n * 10 if n % 2 == 0]?

Sign in to answer, see the explanations, and get this lesson back as a quick review later.

Official docs: developer.hashicorp.com/terraform/language/expressions