Skip to content

Core module catalog

A core module is the unit of work applied by a single Destiny or Scenario step. Core modules are compiled statically into the binaries (Soul-side into soul, Keeper-side into keeper): no separate installation, the module version equals the binary version. Custom modules plug in as separate plugin binaries over gRPC and are not covered here.

A step addresses a module and its state in the form core.<module>.<state>:

- name: Install nginx package
module: core.pkg.installed
params:
name: nginx
  • core.<module> — the module name in the registry (for example core.pkg, core.file).
  • <state> — the desired state (installed / present / running) or a verb (run / shell / probe / fetched / extracted / read). Verb forms use the same machinery, just without the declarative “converge to a state” semantics — they do something or read a fact.

Every declarative state is idempotent: the module first checks the host’s current state and changes it only when it differs from the desired one. A step reports changed=true (state changed) or changed=false (already matched).

The changed status is a signal for dependencies between steps (for example, “restart the service only if the config changed” via onchanges:). More in the Destiny section.

Verb modules work differently:

  • read-probe (core.http.probe, core.augur.fetch, core.vault.kv-read) — always changed=false by construction: a read never changes the host.
  • command (core.exec.run, core.cmd.shell) — changed=true by default (the “execute” verb), lowered by the creates / unless / onlyif guard parameters.
  • core.service.restarted — always changed=true on purpose: a restart is requested explicitly.
SideWhere it runsHow it’s addressed
Soul-sideOn the managed host by the soul agent. Applied identically in pull (daemon) and push (oneshot).on: omitted, or Coven labels.
Keeper-sideOn the server in the keeper process. Work with the registries / cloud / Vault, not the host filesystem.on: keeper (required — otherwise a validation error).

Grouped by purpose:

ModuleWhat it doesStates / verbs
Packages and repositories
core.pkgOS packages via the native package manager (apt / dnf / yum / apk).installed · absent · latest
core.repoOS package repository (with a GPG key for apt).present · absent
Files
core.fileA file with content / from a template / a directory / deletion.present · absent · rendered · directory
core.lineIn-place line editing of a file (lineinfile).present · absent
core.archiveExtracting archives (tar / tar.gz / tar.bz2 / zip).extracted
Services and processes
core.serviceOS service via systemd / openrc / sysv.running · stopped · restarted · enabled
core.execA command directly via exec() — no shell.run
core.cmdA shell string via sh -c (pipes, redirects).shell
core.cronCron jobs via /etc/cron.d/.present · absent
Users and groups
core.userLocal OS users.present · absent
core.groupLocal OS groups.present · absent
System
core.mountMount points and /etc/fstab.present · absent · mounted · unmounted
core.sysctlKernel parameters (vm.* / kernel.* / net.*).present · applied
core.firewallA single firewall rule (ufw / firewalld).present · absent
Network and external data
core.gitCloning / updating a git repository.cloned · pulled
core.urlDownloading a file by URL (checksum verification).fetched
core.httpRead-probe HTTP (health check / readiness).probe
core.augurRead-probe of live access to an external system.fetch
Utility
core.noopNo-op / barrier anchor: does nothing, always succeeds with no change. A join point for several preceding steps (via register.*), or a placeholder / carrier of an output: projection.run

core.noop is changed=false by construction (like the read-probes): params: has no schema (anything is ignored). Its purpose is to be a barrier anchor (a task that references register.* of several predecessors gives a point where they all complete) and an empty step that carries output:.

Dispatched with on: keeper. They run on the server and work with the registries / cloud / Vault.

ModuleWhat it doesStates / verbs
core.soul.registeredBinding a host (SID) to the registry’s Coven labels.registered
core.cloud (addressed as core.cloud.created / .destroyed / .resized)Creating / deleting / resizing cloud instances via a provider driver.created · destroyed · resized
core.choir.presentA host’s membership in an incarnation’s Choir.present · absent
core.vault.kv-readReading a secret from Vault KV (v1/v2) with an audit event.read

A note on core.cloud: the operator flow is available — Cloud-Provider and Cloud-Profile are registered through the Operator API (REST /v1/providers, /v1/profiles, MCP parity, web UI) under the provider.* / profile.* RBAC with an audit log. Still on the roadmap: ready-made soul-cloud-* drivers — they aren’t part of the base distribution yet, and a provider is served by its own CloudDriver plugin. More in core.cloud.

Some modules are built on secure-by-default + explicit opt-out: safe behavior by default, with any loosening behind a separate explicit flag that the operator sees in the apply result (the warnings field).

  • core.url / core.httphttps:// only by default, an SSRF guard, TLS chain verification; lifted by the allow_http / allow_private / insecure_skip_verify flags.
  • core.url — checksum verification before the file appears at the target path.
  • core.repogpg_check is on by default; an http:// mirror and disabled verification both emit a mandatory warning.
  • core.firewall — never touches the default policy and never enables the firewall as a whole (so it can’t cut off management of the host).
  • core.archive — protection against zip-slip / zip-bomb, and masking of setuid/setgid during extraction.

Each per-module page has a Security section with the concrete invariants.

  • Destiny — how to assemble steps into the desired state of a single host.
  • Scenario — orchestration across a cluster (on: / where:).
  • Essence — where parameter values come from.