Golden Templates
Golden templates are named, reusable clone sources captured from an existing sand-managed VM. Snapshot an existing VM once you've provisioned it to your liking, then create new VMs from that template instead of rebuilding the shared base image. Sand still runs its finalize pass so the clone receives its selected identity and settings.
Why use templates
The shared base image (sandbar-base) is built once and shared across all your VMs — changing it is expensive and rare. A template lets you bake in project-specific or team-specific setup above the base: extra toolchains, development dependencies, pre-cloned repos, or secrets — anything you'd otherwise script or type into every new VM. Once that setup is saved as a template, sand create --template mytemplate gives you a fresh, isolated clone with everything already in place.
A template is faster than re-running that setup by hand, and more flexible than rebuilding the base itself — the base stays stable while your templates evolve and branch.
Concepts
What gets saved
When you snapshot a VM into a template, sand captures:
- The guest disk: everything installed or changed inside the VM — toolchains, configs, cloned repos, and any credentials written to disk. Creation finalization overwrites settings such as hostname and git identity, but authors should otherwise assume the disk is copied verbatim. Secrets propagation is detailed below.
- Sizing and settings: vCPUs, memory, disk size, locale, domain suffix, docker-proxy-host, and the clone URL (but not the token).
- Provisioning metadata: which playbook version the template was built from, and which toolsets (Claude Code, DDEV, Go, Java) were installed in its base.
Templates are per-connection-profile — a template saved under one profile never leaks into another. Lima providers store reserved stopped instances under their own ${LIMA_HOME}; Proxmox stores native PVE templates in the configured pool.
Power-state behavior
When you snapshot a running VM, sand stops it, clones it (capturing the state at that moment), then restarts it. The source VM ends up exactly as it started — running or stopped. A template's own power state is always stopped (it is a clone source, not a working VM), but the source VM's state is preserved.
Staleness
A template's status in sand template list reflects whether its playbook predates the playbook embedded in the current sand binary:
current: built with the same playbook version as this binary.stale: built with an older playbook. A stale template still works, but new VMs cloned from it miss playbook updates (new base packages, role changes, etc.). Snapshot a fresh VM to get a current template.unknown: the template lacks comparable version metadata. It can still be cloned, butsandcannot promise it contains the current playbook.
Snapshot: save a VM as a template
CLI
Capture <source-vm> (a running or stopped sand-managed VM) into a new golden template named <name>. The source VM's power state is preserved.
# Snapshot a running VM named 'dev' into a template called 'golden'
sand template snapshot dev golden
# Snapshot, specifying a connection profile
sand template snapshot dev golden --profile work
The name must be a slug — lowercase alphanumeric with hyphens (e.g., golden, next-gen, ai-tools). It cannot collide with an existing template or managed VM in the same scope.
TUI
- On the board, press
ton the tile of the VM you want to snapshot. - Type the template name and press
ctrl+sto confirm.
The snapshot runs in the background (just like a create or reset). Its progress streams into the progress pane; you can leave and reopen its retained log.
Create from a template
CLI
Create a new VM cloned from the golden template <name> instead of the shared base image. All other sand create flags work normally:
# Create a fresh VM from a template, using defaults
sand create --template golden
# Create with custom sizing
sand create --template golden --name myvm --cpus 8 --memory 16GiB
# Create on a specific connection profile
sand create --template golden --profile work
The --template flag is mutually exclusive with --rebuild (templates are already cloned, not rebuilt from base), --base-name (the template instance is the clone source), and --recreate (a recreate always uses the VM's recorded source).
TUI
- Press
n(orenteron the ghost tile) to start a create. - A "Source" field appears in the form, defaulting to the shared base image. Use left/right to cycle through the base and templates in that profile.
- Leave the base selected or choose a template name.
- Fill in the rest of the form and confirm with
ctrl+s.
List templates
CLI
List all golden templates in the current scope (or use --profile <name> to list on a specific connection profile):
NAME SIZE CREATED SOURCE STATUS
golden 5.2 GiB 2025-07-15 dev current
next-gen 6.1 GiB 2025-07-14 dev stale
Columns:
- NAME: the template's user-facing name.
- SIZE: the template's disk size (the reserved Lima instance's guest disk).
- CREATED: when the template was saved.
- SOURCE: the name of the managed VM it was snapshotted from.
- STATUS: whether the template is
current(matches this binary's playbook),stale(older playbook), orunknown(playbook could not be checked).
Delete templates
CLI
Delete a golden template. If any managed VMs were cloned from it, a warning lists them — they keep working, but can no longer be recreated from this template afterward (if you --recreate a VM cloned from a deleted template, it re-clones from whatever source its creation recorded, which is now missing). The delete proceeds anyway; there is no --force gate.
TUI
- Open the create form and focus its Source row.
- Select the template and press
d. - If there are dependents, a warning lists them. Confirm the delete.
Secrets and identity propagation
What propagates
Everything installed or configured in the guest disk propagates into clones. The normal finalize pass reapplies the clone's selected hostname and git identity, and the provider establishes access for the new VM, but those are post-clone updates rather than exclusions from the snapshot.
This matters because clones are independent VMs. A template capturing git config user.name "Alice" should not force every clone to author commits as Alice — that should be up to the person cloning it.
Secrets (tokens, API keys)
Do not put secrets into a template. If a template's guest disk contains a GitHub token, API key, or other credential, every clone copies that credential. A leaked template then leaks every VM cloned from it.
Instead:
- Snapshot the template before storing secrets in the VM's guest (or clean them out first).
- Use the host-side secrets store (
sand secrets, keyeon a tile) to manage per-VM credentials, or put them in a cloned project's.envat create time (the--clone-tokenflag).
See Secrets for how the host secrets store works and how to manage them per-VM and per-directory.
When to rebuild the base vs. snapshot a template
- Rebuild the base (
sand create --rebuild) when the playbook itself needs to change and every future VM should pick it up — a new Go version, a new Ansible role, a critical security update. - Snapshot a template when you want to preserve a specific VM's state — extra setup, team conventions, a pre-cloned project — without affecting the base or other templates.
The two are independent: you can have a current base and a stale template (the template's playbook is older but its extra setup is still valuable), or vice versa.