Add Pulumi for tailnet IaC management #15

Merged
eblume merged 2 commits from feature/pulumi-tailnet-iac into main 2026-01-15 20:55:26 -08:00
4 changed files with 60 additions and 0 deletions
Showing only changes of commit 6f244e6f4f - Show all commits

Add tailscale_serve ansible role for Layer 2 IaC

- Manage tailscale serve configuration declaratively via ansible
- Define services in defaults/main.yml (grafana, forge, kiwix, pypi)
- Role depends on service roles to ensure correct execution order
- Incremental idempotency: only apply if service missing

Two-layer tailnet IaC is now complete:
- Layer 1 (Pulumi): ACLs, tags, DNS
- Layer 2 (Ansible): tailscale serve config

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Erich Blume 2026-01-15 20:53:24 -08:00

View file

@ -26,3 +26,5 @@
tags: devpi_metrics
- role: plex_metrics
tags: plex_metrics
- role: tailscale_serve
tags: tailscale-serve

View file

@ -0,0 +1,27 @@
---
# Tailscale serve configuration for this host
# Each service maps a Tailscale service name to local endpoints
tailscale_services:
- name: svc:grafana
https:
port: 443
upstream: http://localhost:3000
- name: svc:forge
https:
port: 443
upstream: http://localhost:3001
tcp:
port: 22
upstream: tcp://localhost:2200
- name: svc:kiwix
https:
port: 443
upstream: http://localhost:5501
- name: svc:pypi
https:
port: 443
upstream: http://127.0.0.1:3141

View file

@ -0,0 +1,6 @@
---
dependencies:
- role: grafana
- role: forgejo
- role: kiwix
- role: devpi

View file

@ -0,0 +1,25 @@
---
- name: Get current tailscale serve status
ansible.builtin.command: tailscale serve status --json
register: serve_status
changed_when: false
- name: Configure HTTPS services
ansible.builtin.command: >
tailscale serve --service="{{ item.name }}"
--https={{ item.https.port }} {{ item.https.upstream }}
loop: "{{ tailscale_services }}"
when: item.https is defined
register: https_result
changed_when: "'already serving' not in https_result.stderr | default('')"
failed_when: false
- name: Configure TCP services
ansible.builtin.command: >
tailscale serve --service="{{ item.name }}"
--tcp={{ item.tcp.port }} {{ item.tcp.upstream }}
loop: "{{ tailscale_services }}"
when: item.tcp is defined
register: tcp_result
changed_when: "'already serving' not in tcp_result.stderr | default('')"
failed_when: false