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 assecret.<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.stratfiles 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:
- Hosts first. All
hostblocks are evaluated with an empty scope, so they must be made of literals only. Any ref inside a host block is a hard error. - Secrets next. All
secretblocks are evaluated, sources resolved eagerly. Secrets are also literal-only — refs inside secret bodies error. - Namespaces. All
namespaceblocks are collected. Body attributes (configs, optionalstate) must be literal — no refs allowed. The namespaces don't take part in resource evaluation; they only inform the CLI's-n NAMEresolution. - Providers and resources. With the host + secret scope built, provider and resource bodies are evaluated and any
host.<name>.<field>/secret.<name>.valuereference 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.