Hosts Configuration
Hosts can be managed in two ways depending on your use case.
XDG Config (Recommended for end users)
Section titled “XDG Config (Recommended for end users)”For users installing via cargo install, hosts are managed in ~/.config/auberge/hosts.toml:
# Add a host interactivelyauberge host add my-vps
# Or non-interactivelyauberge host add my-vps 203.0.113.10 --user admin --port 22
# List hostsauberge host list
# Show host detailsauberge host show my-vps
# Edit hostauberge host edit my-vps
# Remove hostauberge host remove my-vpsThe hosts.toml format:
[[hosts]]name = "auberge"address = "203.0.113.10"user = "sripwoud"port = 22tags = ["production"]description = "Main VPS"ssh_key = "~/.ssh/identities/auberge/sripwoud"tailscale_ip = "100.99.62.26" # optional, see belowtailnet_tag = "data" # optional, see belowprefer_tailnet = true # optional, see belowOptional fields
Section titled “Optional fields”tailscale_ip— cached Tailscale CGNAT IPv4 of the host. Populated byauberge host detect-tailscale-ip <name>and consumed byauberge dns set-allto auto-fill DNS records for tailnet-only apps without per-app overrides.prefer_tailnet— reach this host at itstailscale_ipinstead of its publicaddress, for SSH, scp, rsync and Ansible alike. A policy, wheretailscale_ipis a fact: caching the address never implies routing over it. Requirestailscale_ip, refused at every write without one. Set byauberge host editand shown as theROUTEcolumn inauberge host list. Strict — no fallback to the public address — with--via publicas the per-command escape. See Tailnet Transport.tailnet_tag— the host’s tailnet trust tier:trusted,data,agent, orstandby. One of exactly those four; anything else fails to parse, naming the legal values. Set byauberge host add --tailnet-tagorauberge host editand shown as theTIERcolumn inauberge host list. Never reaches Ansible; its consumer is the per-run pre-auth mint, which stamps it on the key it mints so a host lands in its tier at enrollment.
[!IMPORTANT]
tagsandtailnet_tagare different axes and must stay that way.tagsbecome Ansible inventory groups (all.children.<tag>), read bywhen: "'hermes' in group_names"guards — they decide which roles run.tailnet_tagis the host’s ACL trust tier — it decides what the host may reach on the tailnet. Deriving one from the other would mean adding an Ansible group silently moved a host’s network trust. See ADR-0062.
The legal tiers are the ones the shipped ACL policy declares under
tagOwners (ansible/roles/headscale/files/policy.hujson), not the ones the
running server currently has loaded — a test holds the file and the CLI’s type
equal, so a tier the CLI accepts is one the policy names. Whether headscale
accepts it is a separate, later question, answered when the tag is applied:
its TagExists gate reads the loaded policy and refuses everything while none
is loaded, so it cannot validate a declaration. See ADR-0062.
Ansible Inventory (Recommended for developers)
Section titled “Ansible Inventory (Recommended for developers)”For development, keep using ansible/inventory.yml in the repository:
all: children: vps: hosts: auberge: ansible_host: "{{ lookup('env', 'AUBERGE_HOST') }}" ansible_port: 22 bootstrap_user: rootPriority Order
Section titled “Priority Order”The CLI checks hosts in this order:
~/.config/auberge/hosts.toml(if exists and not empty)ansible/inventory.yml(fallback for developers)- Environment variables (legacy support)
hosts.toml vs inventory.yml
Section titled “hosts.toml vs inventory.yml”-
hosts.toml: User-specific hosts (backup operations)
- Location:
~/.config/auberge/hosts.toml - Not version controlled
- Managed via
auberge hostcommands
- Location:
-
inventory.yml: Ansible playbooks (shared infrastructure)
- Location:
ansible/inventory.yml - Version controlled
- Used by
auberge ansiblecommands
- Location: