Multi-file configs

plan and apply accept -c more than once. Every listed file is parsed independently, then concatenated into one document and evaluated as a single config. Hosts and secrets declared in any file are visible to references in any other file.

stratum apply -y \
  -c infra.strat \
  -c app.strat \
  -s .stratum/host.json

The shape on disk is one .strat file per logical concern (the host's bootstrap, each app, each shared service). The shape on a host is one state file per host, never one per .strat file.

For multiple deployable slices on the same host where you want each slice to plan and apply on its own — without juggling a long -c list and without one slice's state file silently owning another slice's resources — see Namespaces. Namespaces are the higher-level alternative; the bundle workflow described on this page is unchanged and remains the right shape when you have a single deployable slice.

One state per host

Every config that touches a given host must apply against the same -s state file. State is the authority on "what is currently tracked on this host"; splitting it across files means each file's state thinks it owns the host alone, and applying one of them produces a plan full of Delete steps for the resources owned by the others.

The destruction guard catches this case — apply refuses to run if any Delete is present without --allow-destroy — but the structural fix is to apply all -c files for a host together against one state file. Do not apply them one at a time.

If you forget a -c, the apply will still refuse to run, and the error names every loaded config so the missing one is visually obvious:

refusing to apply: plan would delete 9 resources not in config:
  - docker_container.traefik
  - docker_network.edge
  - ...

loaded configs: app.strat
state file: .stratum/host.json

The missing config here is infra.strat — it owns the deleted resources, but it isn't in the loaded set.

If you'd rather apply each slice independently against its own state file, that's what Namespaces are for. The per-namespace state file is scoped to its namespace's resources, and the implicit per-host tuning resources land in a shared file so multiple namespaces sharing a host don't fight over them.

Cross-file references

A host or secret declared in file A is referenceable in file B without redeclaration.

# hosts.strat
host "primary" {
  addr = "root@192.0.2.10"
}
# app.strat — no `host "primary"` redeclaration
resource "ssh_exec" "uptime" {
  host    = host.primary.addr
  command = "uptime"
}
stratum plan -c hosts.strat -c app.strat -s .stratum/host.json

This works because all files merge into one Document before evaluation. The evaluation order (hosts → secrets → providers + resources) is global across the merged set, not per file.

Per-file base directories

content_file (on system_file) and source_dir (on system_dir) resolve relative to the declaring file's directory, not relative to the working directory or the first -c file. Two system_file blocks in two different files can both reference files/foo.txt next to themselves, and each resolves to its own files/foo.txt.

Duplicates are hard errors

Three categories of duplicate are caught at load time, and the error names both source paths:

categoryerror
Same host name in two filesDuplicateHost { name, first, second }
Same provider name in two filesDuplicateProvider { name, first, second }
Same <kind>.<name> resourceDuplicateResource { addr, first, second }
Same secret nameDuplicateSecret { name, first, second }
duplicate host `primary`: defined in hosts.strat and infra.strat

There is no "last file wins" rule. Pick one file to own the declaration and remove the other.

Merging existing state files

If you started with per-config state files (e.g. .stratum/infra.json, .stratum/app.json) and want to consolidate into one bundle state, use stratum state merge — it merges two or more state files into one, refusing on overwrite and on any <kind>.<name> collision. After merging, run stratum plan against the consolidated state to confirm zero diff before removing the old files.