Deploy Tailscale operator on ringtail k3s cluster (#215)

## Summary
- Extract shared Tailscale operator resources (CRDs, RBAC, Deployment, ProxyClass, DNSConfig) into `tailscale-operator-base/` so both clusters reference the same manifests
- Add `tailscale-operator-ringtail/` overlay with 1-replica ProxyGroup and ExternalSecret for the shared OAuth client
- Add ArgoCD Application targeting `ringtail.tail8d86e.ts.net:6443`
- Update `.yamllint.yaml` ignore path for the moved `operator.yaml`

## Deployment and Testing
- [ ] Sync `apps` app to pick up the new Application definition
- [ ] `argocd app sync tailscale-operator-ringtail`
- [ ] Verify ExternalSecret syncs: `kubectl --context=k3s-ringtail -n tailscale get externalsecret`
- [ ] Verify operator pod runs: `kubectl --context=k3s-ringtail -n tailscale get pods`
- [ ] Verify ProxyGroup ready: `kubectl --context=k3s-ringtail -n tailscale get proxygroups`
- [ ] Verify indri operator still works: `argocd app diff tailscale-operator`
- [ ] Check Tailscale admin for new operator device with `tag:k8s-operator`

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Reviewed-on: https://forge.ops.eblu.me/eblume/blumeops/pulls/215
This commit is contained in:
Erich Blume 2026-02-19 09:33:05 -08:00
commit 61ca1ca305
12 changed files with 95 additions and 5 deletions

View file

@ -28,4 +28,4 @@ ignore:
- .venv/
- pulumi/.venv/
# Third-party k8s manifest with non-standard formatting
- argocd/manifests/tailscale-operator/operator.yaml
- argocd/manifests/tailscale-operator-base/operator.yaml

View file

@ -0,0 +1,27 @@
---
# ArgoCD Application for Tailscale Kubernetes Operator on ringtail
# Shares operator.yaml, proxyclass, and dnsconfig with indri; ringtail-specific
# ProxyGroup (1 replica) and ExternalSecret live in the overlay directory.
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: tailscale-operator-ringtail
namespace: argocd
spec:
project: default
# Tailscale operator mutates externalName from "placeholder" to actual proxy service
ignoreDifferences:
- group: ""
kind: Service
jsonPointers:
- /spec/externalName
source:
repoURL: ssh://forgejo@forge.ops.eblu.me:2222/eblume/blumeops.git
targetRevision: main
path: argocd/manifests/tailscale-operator-ringtail
destination:
server: https://ringtail.tail8d86e.ts.net:6443
namespace: tailscale
syncPolicy:
syncOptions:
- CreateNamespace=true

View file

@ -0,0 +1,10 @@
---
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
namespace: tailscale
resources:
- operator.yaml
- proxyclass.yaml
- dnsconfig.yaml

View file

@ -0,0 +1,32 @@
---
# ExternalSecret for Tailscale Operator OAuth credentials
#
# Shares the same 1Password item as indri's operator (same OAuth client).
# Multiple operator instances can share one OAuth client; each registers
# as its own device.
#
# 1Password item: "Tailscale K8s Operator OAuth" in blumeops vault
# Fields: "client-id", "client-secret"
#
apiVersion: external-secrets.io/v1
kind: ExternalSecret
metadata:
name: operator-oauth
namespace: tailscale
spec:
refreshInterval: 1h
secretStoreRef:
kind: ClusterSecretStore
name: onepassword-blumeops
target:
name: operator-oauth
creationPolicy: Owner
data:
- secretKey: client_id
remoteRef:
key: Tailscale K8s Operator OAuth
property: client-id
- secretKey: client_secret
remoteRef:
key: Tailscale K8s Operator OAuth
property: client-secret

View file

@ -0,0 +1,10 @@
---
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
namespace: tailscale
resources:
- ../tailscale-operator-base
- proxygroup-ingress.yaml
- external-secret.yaml

View file

@ -0,0 +1,11 @@
---
apiVersion: tailscale.com/v1alpha1
kind: ProxyGroup
metadata:
name: ingress
spec:
type: ingress
replicas: 1
proxyClass: default
tags:
- tag:k8s

View file

@ -1,12 +1,11 @@
---
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
namespace: tailscale
resources:
- operator.yaml
- proxyclass.yaml
- ../tailscale-operator-base
- proxygroup-ingress.yaml
- dnsconfig.yaml
- egress-forge.yaml
- external-secret.yaml

View file

@ -0,0 +1 @@
Deploy Tailscale operator on ringtail k3s cluster

View file

@ -158,7 +158,7 @@
"tag:feed": ["autogroup:admin", "tag:blumeops"],
"tag:registry": ["autogroup:admin", "tag:blumeops"],
"tag:k8s-api": ["autogroup:admin", "tag:blumeops"],
"tag:k8s-operator": ["autogroup:admin", "tag:blumeops"],
"tag:k8s-operator": ["autogroup:admin", "tag:blumeops", "tag:k8s-operator"],
"tag:k8s": ["autogroup:admin", "tag:blumeops", "tag:k8s-operator"],
"tag:ci-gateway": ["autogroup:admin", "tag:blumeops"],
"tag:flyio-proxy": ["autogroup:admin", "tag:blumeops"],