Skip to main content
Errand’s file format is defined in terms of HCL (HashiCorp Configuration Language). This page covers the HCL features that Errand uses. For the complete syntax definition, see the HCL native syntax specification.

Blocks

A block has a type, an optional name label, and a body enclosed in {}:
task "build" {
  commands = ["go build ./..."]
}
The block type is task. The label is "build". The body contains one attribute. Some blocks (like errand) take no label:
errand {
  working_dir = "./src"
}

Attributes

An attribute assigns a value to a name:
description = "Build the project"
working_dir = "/tmp/build"
commands    = ["go build ./...", "go vet ./..."]
Attribute values can be strings, numbers, booleans, lists, or expressions. Alignment of = signs is optional but common for readability.

Strings

Strings are enclosed in double quotes. You can use ${} for expression interpolation:
commands = ["docker build -t ${var.image}:${var.tag} ."]
For multi-line shell commands, use heredoc syntax:
commands = [
  <<-EOT
    if [ "${var.env}" = "production" ]; then
      echo "deploying to prod"
    fi
  EOT
]
See heredocs for details.

Lists

Lists are written with square brackets. Items are separated by commas. A trailing comma is allowed:
depends_on = [task.lint, task.test]

commands = [
  "go build ./...",
  "go vet ./...",
]

Comments

Single-line comments start with // or #. Block comments use /* */:
// This task builds the project
task "build" {
  # Run tests first
  depends_on = [task.test]
  commands   = ["go build ./..."]
}

/* This is a
   multi-line comment */

Expressions

Expressions can be literals, references, function calls, or combinations:
# String literal
description = "Build the project"

# Reference to a variable
commands = ["echo ${var.version}"]

# Function call
expression = lower(env("BUILD_ENV", "development"))

# Arithmetic and comparison (used in conditions)
condition = length(var.targets) > 0
See expressions for operators, conditionals, index access, and function calls.