From c87dd1c6d7a0edcc3b236fc6ff3993ffa52f1681 Mon Sep 17 00:00:00 2001 From: Erich Blume Date: Wed, 18 Feb 2026 21:38:10 -0800 Subject: [PATCH] Add ringtail DeviceTags and homelab-to-homelab SSH rule MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Ringtail is already on the tailnet but had no DeviceTags resource — add one matching the indri/sifaka pattern. Remove the bootstrap auth key since ringtail is fully provisioned. Add an SSH ACL rule so tag:homelab devices can SSH to each other, which unblocks ansible/cross-host management from ringtail to indri. Co-Authored-By: Claude Opus 4.6 --- .../fix-tailscale-ssh-ringtail.infra.md | 1 + pulumi/tailscale/__main__.py | 28 ++++++++++--------- pulumi/tailscale/policy.hujson | 8 ++++++ 3 files changed, 24 insertions(+), 13 deletions(-) create mode 100644 docs/changelog.d/fix-tailscale-ssh-ringtail.infra.md diff --git a/docs/changelog.d/fix-tailscale-ssh-ringtail.infra.md b/docs/changelog.d/fix-tailscale-ssh-ringtail.infra.md new file mode 100644 index 0000000..a371962 --- /dev/null +++ b/docs/changelog.d/fix-tailscale-ssh-ringtail.infra.md @@ -0,0 +1 @@ +Add ringtail DeviceTags to Pulumi and allow homelab-to-homelab Tailscale SSH for cross-host ansible/management. diff --git a/pulumi/tailscale/__main__.py b/pulumi/tailscale/__main__.py index 6d3dbf0..2bbecfd 100644 --- a/pulumi/tailscale/__main__.py +++ b/pulumi/tailscale/__main__.py @@ -70,6 +70,18 @@ sifaka_tags = tailscale.DeviceTags( ], ) +# ringtail - NixOS gaming/compute workstation +# Managed by this IaC after initial bootstrap via auth key. +ringtail = tailscale.get_device(name="ringtail.tail8d86e.ts.net") +ringtail_tags = tailscale.DeviceTags( + "ringtail-tags", + device_id=ringtail.node_id, + tags=[ + "tag:homelab", # Server role - allows SSH from workstations and homelab peers + "tag:blumeops", # Managed by this IaC + ], +) + # ============== Auth Keys ============== # Auth key for Fly.io proxy container (public reverse proxy) @@ -82,26 +94,16 @@ flyio_key = tailscale.TailnetKey( expiry=7776000, # 90 days ) -# Auth key for ringtail (gaming/compute workstation, NixOS) -# Used during bootstrap: `tailscale up --auth-key=` -# Once ringtail is on the tailnet, add DeviceTags resource for ongoing management. -ringtail_key = tailscale.TailnetKey( - "ringtail-key", - reusable=False, - ephemeral=False, - preauthorized=True, - tags=["tag:homelab", "tag:blumeops"], - expiry=86400, # 24 hours - single use for bootstrap -) - # ============== Exports ============== pulumi.export("acl_id", acl.id) pulumi.export("policy_hash", policy_hash) pulumi.export("flyio_authkey", flyio_key.key) -pulumi.export("ringtail_authkey", ringtail_key.key) pulumi.export("indri_device_id", indri.node_id) pulumi.export("indri_tags", indri_tags.tags) pulumi.export("sifaka_device_id", sifaka.node_id) pulumi.export("sifaka_tags", sifaka_tags.tags) + +pulumi.export("ringtail_device_id", ringtail.node_id) +pulumi.export("ringtail_tags", ringtail_tags.tags) diff --git a/pulumi/tailscale/policy.hujson b/pulumi/tailscale/policy.hujson index 0703353..417c1fa 100644 --- a/pulumi/tailscale/policy.hujson +++ b/pulumi/tailscale/policy.hujson @@ -124,6 +124,14 @@ "users": ["autogroup:nonroot"], "checkPeriod": "12h0m0s", }, + // Homelab can SSH to homelab (for ansible, cross-host management) + { + "action": "check", + "src": ["tag:homelab"], + "dst": ["tag:homelab"], + "users": ["autogroup:nonroot"], + "checkPeriod": "12h0m0s", + }, ], // ============== Auto Approvers ==============