Define variables with optional type constraints and defaults:
variable "environment" {
type = string
default = "production"
description = "Deployment environment"
}
variable "app_port" {
type = number
default = 8080
}
variable "debug" {
type = bool
default = false
}Variables support Terraform-style type constraints. When a type is specified, values are validated at parse time.
variable "name" {
type = string
default = "myapp"
}
variable "port" {
type = number
default = 8080
}
variable "enabled" {
type = bool
default = true
}variable "hosts" {
type = list(string)
default = ["localhost"]
}
variable "ports" {
type = set(number)
default = [80, 443]
}
variable "tags" {
type = map(string)
default = {
env = "production"
team = "platform"
}
}
variable "config" {
type = object({
debug = bool
log_level = string
workers = number
})
default = {
debug = false
log_level = "info"
workers = 4
}
}variable "servers" {
type = list(object({
host = string
port = number
}))
default = [
{ host = "web1", port = 8080 },
{ host = "web2", port = 8081 }
]
}If a value doesn't match the declared type, hostcfg reports a clear error:
Error: Invalid value for variable "port"
The given value is not valid for variable "port": a number is required.
Expected type: number
Given type: string
Variables without a type attribute accept any value (backward compatible with existing configs):
variable "flexible" {
default = "can be anything"
}Use variables with the var. prefix (see also System Facts for the fact. namespace):
resource "file" "config" {
path = "/etc/myapp/config.conf"
content = "environment = ${var.environment}\nport = ${var.app_port}\n"
}Override variables from the command line using -e:
hostcfg apply -e environment=staging -e app_port=9090When a variable has a declared type, CLI string values are automatically coerced:
# Boolean coercion (accepts: true/false, yes/no, on/off, 1/0)
hostcfg apply -e debug=true
hostcfg apply -e enabled=no
# Number coercion
hostcfg apply -e port=8080
hostcfg apply -e timeout=30.5
# Complex types via JSON
hostcfg apply -e 'hosts=["web1","web2","web3"]'
hostcfg apply -e 'tags={"env":"prod","team":"platform"}'If coercion fails, you'll get a clear error:
$ hostcfg apply -e port=notanumber
Error: Invalid value for variable "port"
Cannot convert "notanumber" to number: not a valid numeric valueWhen using roles, variables are resolved with the following precedence (highest to lowest):
- CLI variables (
-e port=6380) - override everything - Role instantiation variables (
variables = { ... }) - Role defaults (
roles/<name>/variables.hcl) - Main config defaults (
variable "x" { default = ... })
Dependencies are automatically inferred from resource references. You can also declare explicit dependencies using depends_on:
# Automatic dependency - inferred from ${directory.app.path}
resource "directory" "app" {
path = "/opt/myapp"
}
resource "file" "config" {
path = "${directory.app.path}/config.json" # Auto-depends on directory.app
content = "{}"
}
# Explicit dependency - needed when no attribute reference exists
resource "package" "nginx" {
name = "nginx"
}
resource "service" "nginx" {
name = "nginx"
ensure = "running"
depends_on = ["package.nginx"] # Must be explicit
}Dependencies are specified as ["type.name"] references. The engine performs topological sorting to ensure resources are applied in the correct order and detects circular dependencies.