Skip to navigation

Syntax and source files

A configuration is a directory of *.hcl files. Rivet loads the files directly in that directory, in sorted order, as one configuration. Subdirectories are not loaded, except as modules you call explicitly, so assets such as templates and config files can live there.

HCL files must be regular UTF-8 files, not symlinks. All loaded HCL, including modules, can total at most 16 MiB.

Blocks and attributes

Resources use a type and exactly one label:

file "message" {
path = "/etc/rivet-message"
content = "Hello\n"
meta {
description = "A managed message"
}
}

There is no Terraform-style resource "file" "message" wrapper. Built-in root blocks are file, package, user, group, group_membership, exec, service, timer, ssh_key, mount, module, variable, locals, output, and plugin. Approved plugins can register additional resource type names.

Identifier labels start with an ASCII letter or underscore and continue with letters, digits, underscores, or hyphens. Resource labels also accept normalized absolute paths, such as file "/etc/myapp/config.conf"; reference them with file["/etc/myapp/config.conf"]. A path label does not supply the resource’s path attribute. Module, variable, and output labels retain identifier rules. Labels are unique within their resource type; variables, locals, and outputs have their own namespaces. Duplicate declarations and attributes fail.

locals has no label. Resource child blocks, including meta and package provider blocks, are unlabelled and must be unique within the declaration. Unknown fields and child blocks are errors. Top-level attributes aren’t allowed; put named values in locals.

HCL comments use #, //, or /* ... */. Strings use double quotes and escape sequences such as \n. Lists use square brackets; objects use braces with named entries.

Agent and server configuration files use a different, literal-only format. Keep them outside your configuration directory.

Plugin requirements

A plugin "ALIAS" block has exactly two attributes: literal string source and version. It checks that a matching plugin is installed and approved on this machine; it can’t install or approve one. Duplicate requirements fail. Exact versions, = VERSION, and numeric ~> MAJOR.MINOR or ~> MAJOR.MINOR.PATCH constraints are supported.

plugin "example" {
source = "example.com/rivet/example"
version = "~> 1.0"
}

Plugin functions use plugin::ALIAS::NAME(...). Service and package providers use provider = "NAME" and an unlabelled provider-specific child block. See subprocess plugins for installation and complete examples.

What expressions can do

Rivet supports most of the HCL expression language: numbers, strings, collections, operators, conditionals, for expressions, splats, interpolation, functions, heredocs and templates, modules, and count and for_each. Values come from variables, facts, and input files or data hierarchies.

Everything is evaluated at compile time. Expressions can read files inside the configuration directory and render templates, but can’t run commands, inspect the host, or download data. Remote modules, cloud file sources, and SOPS layers are fetched or decrypted by their own separate steps.

resource("file") and the other resource type names are valid as output and variable types, not as callable functions.

See limitations for unsupported constructs.