Automax Technical Design
Goals
- Python implementation.
- External YAML definitions for jobs, inventories, variables and secrets.
- Modular plugin architecture.
- SSH-first execution model.
- Three-level job structure: task, step, substep.
- Step-scoped SSH connection reuse.
- State store for resume and audit.
- Serial, parallel and rolling execution strategies.
- Tag-based selection and skip filters.
- Declarative failure policy.
- Canonical builtin plugin names with no public short aliases.
Execution model
A step opens one fresh SSH connection per target and reuses it for all its
substeps. The runtime context is kept by Automax, not by a long-lived remote
shell. Plugins that need step-local state can use the ExecutionContext.step_state
mapping internally. Job authors should pass explicit plugin parameters such as
cwd instead of relying on implicit cross-substep shell state.
Flow-control nodes are engine-level constructs, not plugins. They let job authors
branch, switch, retry nested blocks, loop, group blocks, set values, echo messages, assert conditions, pause explicitly, record no-op branches, fail deliberately, recover with
try/rescue/always, and use break/continue in loops while keeping nested
plugin executions visible in the state store.
Targets can be scoped at job, task, step or substep level. When substeps in the same step resolve to different target sets, Automax keeps one execution group per step/target and runs only the matching substeps for that target.
External operational files
Automax does not require job, inventory, variable or secret files to live inside the Python source tree. The CLI receives them explicitly:
automax run \
--job /srv/automax/jobs/deploy.yaml \
--inventory /srv/automax/inventory/prod.yaml \
--vars /srv/automax/vars/prod.yaml \
--secrets /srv/automax/secrets/prod.yaml
Secrets
Secrets are resolved on the controller through env, file, command,
vault, aws_secrets_manager, azure_key_vault, gcp_secret_manager and
onepassword providers. External secret manager providers use vendor CLIs so
the runner does not require cloud SDK dependencies.
Strategy
Strategy can be declared at job, task or step level. More specific scopes override less specific scopes.
strategy:
mode: serial
strategy:
mode: parallel
max_parallel: 5
strategy:
mode: rolling
batch_size: 2
pause_between_batches: 10
Tags
Tags can be declared at job, task, step or substep level and are inherited as an effective set for each substep.
automax run --job job.yaml --inventory inventory.yaml --tags deploy --skip-tags dangerous
Failure policy
Failure policy can be declared at job, task or step level. More specific scopes override less specific scopes.
failurePolicy:
onFailure: stop_job
onUnreachable: stop_host
maxFailedHosts: 1
Supported actions:
stop_job
stop_task
stop_host
continue
Builtin plugin scope
Builtins are grouped into these public families:
commands: command.local.run, command.remote.run
flow: if/then/else, switch/case/default, retry/do, for/in/do, block, set/let, echo, assert, sleep, noop, fail, try/rescue/always, break/continue
filesystem: fs.*
data: data.archive.*, data.compression.*, data.download.*, data.transfer.*, data.backup.*, data.restore.*
database: database.<engine>.check, database.<engine>.query
identity: identity.user.*, identity.group.*
network: network.connectivity.*, network.dns.*, network.firewall.*, network.http.*, network.link.*, network.route.*
os/packages: os.*, os.package.*
security: security.*
storage: storage.*
system: system.host.*, system.service.*, system.systemd.*, system.kernel.*, system.process.*, system.cron.*, system.journal.*, system.log.*
devices: device.udev.*
notifications: notify.mail.send
Builtin plugin names are canonical only: no short or ambiguous aliases are
exposed by default. External plugins can still define aliases, but
automax plugins list shows canonical names unless --include-aliases is
requested.
External plugins can be loaded with --plugin-path.
Remaining non-goals for this implementation
- Central database state backend.
- Deploy-release orchestration plugins with rollback semantics.
- Full Ansible-equivalent module coverage.
Database design
SQLite is built in. PostgreSQL, MySQL and Oracle use optional Python extras. The shared database plugin base owns statement validation, transaction flow and output shaping so new database backends can be added as small driver-specific modules.