The .strat language

A .strat file is a flat list of top-level blocks. Five kinds exist:

  • host "<name>" { ... } — a named SSH target. See Hosts.
  • secret "<name>" { ... } — a sensitive value sourced from env or file, referenced as secret.<name>.value. See Secrets.
  • provider "<name>" { ... } — provider configuration. See Providers.
  • resource "<kind>" "<name>" { ... } — a piece of declared infra. See Resources.
  • namespace "<name>" { ... } — a deployable slice; lists the .strat files that apply together against one dedicated state file. Only meaningful in a top-level manifest. See Namespaces.
document    ::= block*
block       ::= ident label* "{" body "}"
label       ::= string
body        ::= ( attr | block )*
attr        ::= ident "=" value
value       ::= string | number | bool | list | map | ref
list        ::= "[" ( value ( "," value )* ","? )? "]"
map         ::= "{" ( ( ident | string ) "=" value )* "}"
ref         ::= ident ( "." ident )+

Whitespace is insignificant. Block bodies may also contain nested blocks; those are folded into the parent map under the key <kind> (or <kind>_<label> when labels are present).

Comments

Both # and // start a line comment. There are no block comments.

# this is a comment
// so is this
resource "ssh_exec" "uptime" {
  host    = host.prod.addr  # inline comments work too
  command = "uptime"
}

Evaluation order

The evaluator runs four passes:

  1. Hosts first. All host blocks are evaluated with an empty scope, so they must be made of literals only. Any ref inside a host block is a hard error.
  2. Secrets next. All secret blocks are evaluated, sources resolved eagerly. Secrets are also literal-only — refs inside secret bodies error.
  3. Namespaces. All namespace blocks are collected. Body attributes (configs, optional state) must be literal — no refs allowed. The namespaces don't take part in resource evaluation; they only inform the CLI's -n NAME resolution.
  4. Providers and resources. With the host + secret scope built, provider and resource bodies are evaluated and any host.<name>.<field> / secret.<name>.value reference is resolved.

See References & scope for the resolution rules.

Resource kind naming

A resource kind must start with the provider name, separated by an underscore — for example system_package, ssh_exec, docker_container. The prefix is what stratum uses to route resources to a provider. A kind with no underscore (or with only an underscore as a separator) is rejected.

Values

Strings, numbers, booleans, lists, and maps. See Types & values for the exact rendering rules — in particular the integer-vs-float behavior for numbers.

Strings may embed ${<ref>} placeholders that are substituted at config-load time. See String interpolation.