Writing state modules
A module is a YAML document describing a unit of desired state. You declare
what a machine should look like; Ordo plans how to reach and maintain it.
The full, machine-readable shape is published as a
JSON Schema — associate it with
*.ordo.yaml in your editor for autocompletion and validation.
Anatomy
Section titled “Anatomy”A module has four top-level fields:
name— the module’s stable identity, referenced when you apply it.supports— the attribute combinations the module is designed for. An agent matching no clause is rejected before any per-resource work.templates— named, content-only fragments that resources can reference.resources— an ordered list of resource declarations.
name: caddy-sitesupports: - { platform: linux, distro: debian, init_system: systemd } - { platform: linux, distro: fedora, init_system: systemd }templates: - id: caddyfile content: | :80 { root * /var/www/caddy-site file_server }resources: - id: caddyfile resource: file-unix: path: /etc/caddy/Caddyfile template: caddyfile mode: "0644"Resource types
Section titled “Resource types”Each resource has an id and a resource body whose single key selects the
resource kind. The first-class kinds are:
- Packages —
package-apt,package-dnf,package-brew,package-choco,package-winget. Same shape (name, optionalversion); the manager is chosen by the key. - Files & directories —
file-unix,file-windows,directory-unix,directory-windows. A file takes inlinecontentor atemplatereference (the two are mutually exclusive), plusowner/group/modeon Unix. - Services —
service-systemd,service-launchd,service-windows, withenabledandrunningstate. - Scripts —
script, the escape hatch for work the first-class kinds do not model (see below).
Every resource is drift-checked and appears in the plan individually.
Variants
Section titled “Variants”A resource can be universal (one body applies to every supported agent) or
have variants gated by when clauses on agent attributes. The most specific
matching variant wins — use this to swap the package manager per distro while
keeping one logical resource:
resources: - id: caddy-pkg variants: - when: { platform: linux } resource: package-apt: { name: caddy } - when: { platform: linux, distro: fedora } resource: package-dnf: { name: caddy }Ordering and dependencies
Section titled “Ordering and dependencies”Resources apply in declaration order unless you override it with depends_on,
which names the resource ids that must be applied first:
resources: - id: caddy-pkg resource: package-apt: { name: caddy } - id: caddyfile depends_on: [caddy-pkg] resource: file-unix: path: /etc/caddy/Caddyfile template: caddyfile mode: "0644"Change triggers
Section titled “Change triggers”Services and scripts can react when a resource they depend on actually changes, rather than on every apply:
reload_on(systemd only) — reload the service when a listed resource changes.restart_on— restart the service (or re-run, for launchd/Windows which have no live reload) when a listed resource changes.rerun_on(scripts) — re-run the script when a listed resource changes.
reload_on and restart_on must be disjoint within one service. For example,
reload Caddy whenever its config file changes — with no dropped connections:
- id: caddy-service depends_on: [caddyfile] resource: service-systemd: name: caddy enabled: true running: true reload_on: [caddyfile]Triggered actions are predicted in the plan before they run, so you can see a reload or restart coming.
The script escape hatch
Section titled “The script escape hatch”When no first-class kind fits, a script resource runs commands. Because a bare
script has no way to diff its own state, give it a check command (its exit
status decides whether apply needs to run), and declare manages/undo so
removing the resource can tear down what it created. Pair it with rerun_on to
re-run only when its inputs change.
Validate before you apply
Section titled “Validate before you apply”ordo-state validates and inspects modules locally, before they reach the
orchestrator:
ordo-state validate caddy-site.ordo.yaml # schema + semantic checksordo-state deps caddy-site.ordo.yaml # show the resolved apply orderWorked, validated examples ship in the repository — the
caddy-site
module models a static site entirely with first-class resources, and
demo-compose-stack shows the script escape hatch driving Docker Compose.