Terraform Advanced — try, can, one Functions

1 minute read

Three functions that prevent runtime errors when accessing optional or uncertain attributes.


try() — Fallback Chain

try() evaluates expressions left to right and returns the first one that doesn’t error:

locals {
  # If var.config has a "port" key, use it; otherwise default to 8080
  port = try(var.config.port, 8080)

  # Chain multiple fallbacks
  db_host = try(
    var.override_db_host,                           # First: explicit override
    data.aws_db_instance.main.address,              # Second: RDS lookup
    "localhost"                                      # Last: fallback
  )
}

can() — Boolean Check

can() returns true if the expression evaluates without error:

locals {
  has_custom_domain = can(var.config.custom_domain)
}

resource "aws_route53_record" "custom" {
  count = local.has_custom_domain ? 1 : 0
  name  = var.config.custom_domain
  # ...
}

one() — Extract Single Element

one() extracts a single element from a list, returning null if empty:

# Get the single default VPC (or null if none)
data "aws_vpc" "default" {
  count   = var.use_default_vpc ? 1 : 0
  default = true
}

locals {
  vpc_id = one(data.aws_vpc.default[*].id)
  # Returns the VPC ID if count=1, or null if count=0
}

Combining Them

variable "config" {
  type    = any
  default = {}
}

locals {
  # Safe nested access with fallback
  log_level    = try(var.config.logging.level, "INFO")
  enable_cache = can(var.config.cache) ? var.config.cache.enabled : false
  primary_az   = one([for az in var.availability_zones : az if az == var.preferred_az])
}

⚠️ Warning: Don’t use try() to silence errors you should fix. Use it for genuinely optional configuration.


What’s Next?

Master locals and conditional expressions.

← Splat Expressions Locals and Conditionals →

Updated: