headscale: dns.extra_records from a role variable (tailnet aliases) #241

Open
opened 2026-10-16 17:14:44 -04:00 by jfraeys · 0 comments
Owner

Follow-up to the research issue #213. Implementation, small.

Where we are (read from the repo, 2026-10-16)

  • roles/headscale/templates/config.yaml.j2 already has dns.magic_dns: true and base_domain: ts.jfraeys.com (headscale_base_domain, derived from base_domain).
    Every node already resolves as <node>.ts.jfraeys.com for clients that accept tailnet DNS (e.g. the operator's Mac).
  • extra_records: [] is hardcoded in the template, so there is no way to add an alias without editing the template.
  • override_local_dns: true, global nameservers 1.1.1.1 / 1.0.0.1.
  • Server nodes join with tailscale up --accept-dns=false (roles/tailscale), so they do not use these names themselves.
  • Headscale 0.29.5. Validation: base_domain must not be contained in the server_url host (vpn.jfraeys.com), which ts.jfraeys.com satisfies.

To do

  1. Add a role variable headscale_extra_records (list of {name, type, value}) and render it into dns.extra_records; default [], so nothing changes until used.
  2. A render test (like the other template tests): list in, valid YAML out, empty list renders [].
  3. First records, once #B decides the names: aliases for the services that are only reachable over the tailnet (for example Forgejo on its tailnet address, LLDAP admin, Alertmanager).
  4. Deploy with ./infra deploy --tags headscale --limit services. This recreates the Headscale container (short control-plane blip; existing tunnels keep running). Check manage vpn status and a name lookup afterwards.

Not in scope

Making servers use tailnet DNS (--accept-dns), a separate resolver, public DNS changes.

Follow-up to the research issue #213. Implementation, small. ## Where we are (read from the repo, 2026-10-16) - `roles/headscale/templates/config.yaml.j2` already has `dns.magic_dns: true` and `base_domain: ts.jfraeys.com` (`headscale_base_domain`, derived from `base_domain`). Every node already resolves as `<node>.ts.jfraeys.com` for clients that accept tailnet DNS (e.g. the operator's Mac). - `extra_records: []` is hardcoded in the template, so there is no way to add an alias without editing the template. - `override_local_dns: true`, global nameservers 1.1.1.1 / 1.0.0.1. - Server nodes join with `tailscale up --accept-dns=false` (roles/tailscale), so they do not use these names themselves. - Headscale 0.29.5. Validation: `base_domain` must not be contained in the `server_url` host (`vpn.jfraeys.com`), which `ts.jfraeys.com` satisfies. ## To do 1. Add a role variable `headscale_extra_records` (list of `{name, type, value}`) and render it into `dns.extra_records`; default `[]`, so nothing changes until used. 2. A render test (like the other template tests): list in, valid YAML out, empty list renders `[]`. 3. First records, once #B decides the names: aliases for the services that are only reachable over the tailnet (for example Forgejo on its tailnet address, LLDAP admin, Alertmanager). 4. Deploy with `./infra deploy --tags headscale --limit services`. This recreates the Headscale container (short control-plane blip; existing tunnels keep running). Check `manage vpn status` and a name lookup afterwards. ## Not in scope Making servers use tailnet DNS (`--accept-dns`), a separate resolver, public DNS changes.
Sign in to join this conversation.
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
jfraeys/infra#241
No description provided.