feat: Auto-cleanup stale Tailscale devices before cluster boot
Some checks failed
Deploy Cluster / Terraform (push) Successful in 2m17s
Deploy Cluster / Ansible (push) Failing after 6m35s

Adds tailscale-cleanup Ansible role that uses the Tailscale API to
delete offline devices matching reserved hostnames (e.g. rancher).
Runs during site.yml before Finalize to prevent hostname collisions
like rancher-1 on rebuild.

Requires TAILSCALE_API_KEY (API access token) passed as extra var.
This commit is contained in:
2026-03-29 11:47:53 +00:00
parent 6e5b0518be
commit 5269884408
3 changed files with 57 additions and 0 deletions

View File

@@ -230,6 +230,7 @@ jobs:
-e "tailscale_oauth_client_id=${{ secrets.TAILSCALE_OAUTH_CLIENT_ID }}" \
-e "tailscale_oauth_client_secret=${{ secrets.TAILSCALE_OAUTH_CLIENT_SECRET }}" \
-e "doppler_hetznerterra_service_token=${{ secrets.DOPPLER_HETZNERTERRA_SERVICE_TOKEN }}" \
-e "tailscale_api_key=${{ secrets.TAILSCALE_API_KEY }}" \
-e "grafana_admin_password=${{ secrets.GRAFANA_ADMIN_PASSWORD }}" \
-e "cluster_name=k8s-cluster"
env:

View File

@@ -0,0 +1,46 @@
---
- name: Delete stale Tailscale devices with reserved hostnames
block:
- name: Get Tailscale devices from API
uri:
url: "https://api.tailscale.com/api/v2/tailnet/{{ tailscale_tailnet }}/devices"
method: GET
headers:
Authorization: "Bearer {{ tailscale_api_key }}"
return_content: true
register: ts_devices
- name: Find stale devices matching reserved hostnames
set_fact:
stale_devices: >-
{{ ts_devices.json.devices | default([])
| selectattr('hostname', 'defined')
| selectattr('hostname', 'in', tailscale_reserved_hostnames)
| rejectattr('online', 'true')
| list }}
- name: Delete stale devices
uri:
url: "https://api.tailscale.com/api/v2/device/{{ item.id }}"
method: DELETE
headers:
Authorization: "Bearer {{ tailscale_api_key }}"
status_code: 200
loop: "{{ stale_devices }}"
loop_control:
label: "{{ item.name }} ({{ item.id }})"
when: stale_devices | length > 0
- name: Report cleaned devices
debug:
msg: "Deleted stale Tailscale device: {{ item.name }}"
loop: "{{ stale_devices }}"
when: stale_devices | length > 0
- name: No stale devices found
debug:
msg: "No stale Tailscale devices found."
when: stale_devices | length == 0
when:
- tailscale_api_key is defined
- tailscale_api_key | length > 0

View File

@@ -128,6 +128,16 @@
roles:
- doppler-bootstrap
- name: Clean up stale Tailscale devices
hosts: localhost
connection: local
vars:
tailscale_reserved_hostnames:
- rancher
roles:
- tailscale-cleanup
- name: Finalize
hosts: localhost
connection: local