Config-only quickstart
This walkthrough uses one local host and a config-only service. Run it from the repository root on Linux with Go 1.27.3 or newer, Make, and standard shell tools. It creates all managed targets in a fresh private temporary directory and needs no root, DNF, systemd, or network access after building. Full Linux platform requirements and verification scope are in installation and validation .
Build and describe the file
make build
./bin/richt --version
demo_dir=$(mktemp -d "${TMPDIR:-/tmp}/richt-quickstart.XXXXXX")
chmod 700 "$demo_dir"
printf '%s\n' 'message={{ .greeting }}' > "$demo_dir/greeting.gotmpl"
cat > "$demo_dir/inventory.yaml" <<EOF_INVENTORY
tags:
defaults:
order: 10
services:
greeting: {state: present}
vars:
greeting: Hello from Richt
services:
greeting:
order: 10
configs:
main:
path: $demo_dir/target/greeting.conf
mode: "0644"
template: {file: greeting.gotmpl}
hosts:
- name: local
tags: [defaults]
transport: {type: local}
EOF_INVENTORY
Keep this shell open so demo_dir stays available. Tag defaults assigns the
service and supplies the template’s .greeting variable. The service
definition’s order fixes execution order;
config-only services need no binary or process component. Template paths are
relative to their declaring service file, or the inventory for inline services.
Inspect, prepare, and apply
./bin/richt inventory validate -i "$demo_dir/inventory.yaml"
./bin/richt inventory show -i "$demo_dir/inventory.yaml"
./bin/richt diff -i "$demo_dir/inventory.yaml" -o "$demo_dir/create.json"
./bin/richt apply "$demo_dir/create.json"
cat "$demo_dir/target/greeting.conf"
./bin/richt diff -i "$demo_dir/inventory.yaml"
Inventory inspection does not read templates or contact the host. Diff renders
the template and observes the target, then displays the planned file write and
attributes. It does not change managed resources. Review the display and type
yes at apply’s terminal prompt. The resulting file contains
message=Hello from Richt; the final diff reports no changes.
In a noninteractive shell, use ./bin/richt apply -y "$demo_dir/create.json"
when you intend to skip confirmation. Piping yes into apply does not satisfy
the terminal requirement. The saved JSON contains executable prepared inputs
and task progress; apply does not reread the source files or recalculate the
diff. Keep saved plans private, especially when templates use secrets.
Update and explicitly remove
printf '%s\n' 'message={{ .greeting }} (updated)' > "$demo_dir/greeting.gotmpl"
./bin/richt diff -i "$demo_dir/inventory.yaml" -o "$demo_dir/update.json"
./bin/richt apply "$demo_dir/update.json"
cat "$demo_dir/target/greeting.conf"
sed 's/state: present/state: absent/' "$demo_dir/inventory.yaml" > "$demo_dir/remove.yaml"
./bin/richt diff -i "$demo_dir/remove.yaml" -o "$demo_dir/remove.json"
./bin/richt apply "$demo_dir/remove.json"
test ! -e "$demo_dir/target/greeting.conf"
The update changes the file to message=Hello from Richt (updated). Explicit
state: absent removes the declared file. Deleting an assignment alone does
not request removal. Removal does not render templates or read secret sources,
and leaves the parent directory in place.
To remove this walkthrough’s remaining inputs and plans after reviewing them:
rm -rf -- "$demo_dir"
Continue with inventory rules , the ready-package vmango example , SSH , or the two-source secret example . To see a partial failure and retry only unfinished work, use the continuation walkthrough .