Hierarchical config and templating for clusters. Merge domain, group, and node config, then fill in any text file from that result.
Same template, different node, different output. The tool does not know or care what the file is for. Something else puts the rendered text in place.
--config points at a directory tree — a checkout, an image, a path on
disk. The tree holds the authored config, the templates, and a wizard for
common values. Inventory is a genders file the wizard maintains.
install.sh downloads the latest release binary and the example config
tree. As a normal user it installs under ~/.local; as root it installs
under /opt.
curl -fsSL https://github.com/alces-software/alces-render/releases/latest/download/install.sh | bashInstalls:
| Path | Contents |
|---|---|
~/.local/alces-render/bin/alces-render |
binary |
~/.local/alces-render/share/example-repo-cluster |
example tree |
~/.local/bin/alces-render |
symlink |
Add ~/.local/bin to PATH if it is not already there.
curl -fsSL https://github.com/alces-software/alces-render/releases/latest/download/install.sh | sudo bashInstalls:
| Path | Contents |
|---|---|
/opt/alces-render/bin/alces-render |
binary |
/opt/alces-render/share/example-repo-cluster |
example tree |
/usr/local/bin/alces-render |
symlink |
Set these before piping to bash (or sudo bash):
| Variable | Default (user) | Default (root) |
|---|---|---|
ALCES_RENDER_VERSION |
latest |
latest |
ALCES_RENDER_PREFIX |
~/.local/alces-render |
/opt/alces-render |
ALCES_RENDER_BINDIR |
~/.local/bin |
/usr/local/bin |
Example — pin a tag and keep the user layout:
curl -fsSL https://github.com/alces-software/alces-render/releases/latest/download/install.sh \
| ALCES_RENDER_VERSION=v0.1.0 bashLinux and macOS, amd64 and arm64, are supported.
After install, --config defaults to the bundled example tree. Render a
domain-scope template:
alces-render hosts.erbRender the same merge for one node:
alces-render motd.erb node01Inspect what a template will see. No path prints the cluster map; a path
dumps that node as JSON. --tree PATH prints a subtree. config expands
as structure; answer is the wizard table (view --tree nodes.node01.answer).
alces-render view
alces-render view --tree nodes.node01
alces-render view --tree nodes.node01.answer
alces-render view nodes.node01.configAnswer common questions at domain, group, node, or local scope. Only overrides are stored. Configuring a group also updates inventory:
alces-render configure domain
alces-render configure group nodes
alces-render configure node node01Pass --config DIR to use your own tree instead of the example.
alces-render [--config DIR] [options] TEMPLATE [NODE]
alces-render [--config DIR] [command] [options]
Without NODE, the template is rendered for the domain. With NODE, it
is rendered in that node's context. There is no group-scope render flag;
a domain-scope template walks alces.groups.<name>.nodes when it needs
members of a group.
Commands:
configure— answer common questions; save overridesview— print the namespace as a tree, or a path as JSON--tree— (view) print a key tree from PATH instead of JSON
Options:
--config DIR— config tree (default:<prefix>/share/example-repo-cluster)--answers-dir DIR— answers directory (default:<config>/configure/answers)--genders FILE— genders inventory (default:<config>/configure/genders)--strict— treat missing values as errors--quiet— suppress missing-value warnings--answers JSON— (configure) supply answers without prompts
<prefix> is the install root: the parent of bin/ when the binary was
installed by install.sh.
configure/
questions.yaml # common-value questions at domain / group / node / local
answers/ # wizard store (deltas only)
domain.yaml
groups/<group>.yaml
nodes/<node>.yaml # local lives at nodes/local.yaml
genders # inventory; first group on a node is primary
cache/groups.yaml # stable primary-group indexes
config/
domain.yaml # cluster-wide structure (strings may be ERB)
<group>.yaml # group layer
<node>.yaml # optional per-node layer, including one-offs
local.yaml # master layer
templates/ # any text files; path is what you pass to render
config/ is the configuration: nested YAML, formulas, and values the
operator types in. The wizard is a guided subset of common identifiers.
Config may reference answer.*, or hardcode a value; both are valid.
Two overlays, same scopes. Answers are flat (last identifier wins). Config hashes deep-merge. Later layers win; groups apply in reverse genders order so the primary group wins, then the node.
configure group NAME writes that group's answer deltas, assigns a
stable index, and inserts or replaces that group's line in the genders
file. Render reads the file. Domain, node, and local configure write
answers only.
Templates are ERB. The binding is the namespace (alces.domain,
alces.groups.<name>, alces.nodes.<name>, alces.local, and scoped
alces.config / alces.answer). Config string values are themselves
ERB, evaluated when first read in the current scope.
Requires Go 1.24+.
go build -o alces-render ./cmd/alces-render
./alces-render --config examples/example-repo-cluster hosts.erbEclipse Public License 2.0. See LICENSE.