From d6c1806e39a59e43fbc2ff6850919f9d4fb9f4a2 Mon Sep 17 00:00:00 2001 From: Erich Blume Date: Thu, 19 Feb 2026 09:18:43 -0800 Subject: [PATCH 1/2] Deploy Tailscale operator on ringtail k3s cluster Extract shared operator resources (CRDs, RBAC, Deployment, ProxyClass, DNSConfig) into tailscale-operator-base/ so both indri and ringtail reference the same base without duplication. Ringtail overlay adds a 1-replica ProxyGroup and ExternalSecret for the shared OAuth client. Co-Authored-By: Claude Opus 4.6 --- .yamllint.yaml | 2 +- argocd/apps/tailscale-operator-ringtail.yaml | 27 ++++++++++++++++ .../dnsconfig.yaml | 0 .../kustomization.yaml | 10 ++++++ .../operator.yaml | 0 .../proxyclass.yaml | 0 .../external-secret.yaml | 32 +++++++++++++++++++ .../kustomization.yaml | 10 ++++++ .../proxygroup-ingress.yaml | 11 +++++++ .../tailscale-operator/kustomization.yaml | 5 ++- .../tailscale-operator-ringtail.infra.md | 1 + 11 files changed, 94 insertions(+), 4 deletions(-) create mode 100644 argocd/apps/tailscale-operator-ringtail.yaml rename argocd/manifests/{tailscale-operator => tailscale-operator-base}/dnsconfig.yaml (100%) create mode 100644 argocd/manifests/tailscale-operator-base/kustomization.yaml rename argocd/manifests/{tailscale-operator => tailscale-operator-base}/operator.yaml (100%) rename argocd/manifests/{tailscale-operator => tailscale-operator-base}/proxyclass.yaml (100%) create mode 100644 argocd/manifests/tailscale-operator-ringtail/external-secret.yaml create mode 100644 argocd/manifests/tailscale-operator-ringtail/kustomization.yaml create mode 100644 argocd/manifests/tailscale-operator-ringtail/proxygroup-ingress.yaml create mode 100644 docs/changelog.d/tailscale-operator-ringtail.infra.md diff --git a/.yamllint.yaml b/.yamllint.yaml index 15b4de5..452c7fe 100644 --- a/.yamllint.yaml +++ b/.yamllint.yaml @@ -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 diff --git a/argocd/apps/tailscale-operator-ringtail.yaml b/argocd/apps/tailscale-operator-ringtail.yaml new file mode 100644 index 0000000..a261354 --- /dev/null +++ b/argocd/apps/tailscale-operator-ringtail.yaml @@ -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 diff --git a/argocd/manifests/tailscale-operator/dnsconfig.yaml b/argocd/manifests/tailscale-operator-base/dnsconfig.yaml similarity index 100% rename from argocd/manifests/tailscale-operator/dnsconfig.yaml rename to argocd/manifests/tailscale-operator-base/dnsconfig.yaml diff --git a/argocd/manifests/tailscale-operator-base/kustomization.yaml b/argocd/manifests/tailscale-operator-base/kustomization.yaml new file mode 100644 index 0000000..980b8e3 --- /dev/null +++ b/argocd/manifests/tailscale-operator-base/kustomization.yaml @@ -0,0 +1,10 @@ +--- +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization + +namespace: tailscale + +resources: + - operator.yaml + - proxyclass.yaml + - dnsconfig.yaml diff --git a/argocd/manifests/tailscale-operator/operator.yaml b/argocd/manifests/tailscale-operator-base/operator.yaml similarity index 100% rename from argocd/manifests/tailscale-operator/operator.yaml rename to argocd/manifests/tailscale-operator-base/operator.yaml diff --git a/argocd/manifests/tailscale-operator/proxyclass.yaml b/argocd/manifests/tailscale-operator-base/proxyclass.yaml similarity index 100% rename from argocd/manifests/tailscale-operator/proxyclass.yaml rename to argocd/manifests/tailscale-operator-base/proxyclass.yaml diff --git a/argocd/manifests/tailscale-operator-ringtail/external-secret.yaml b/argocd/manifests/tailscale-operator-ringtail/external-secret.yaml new file mode 100644 index 0000000..0776420 --- /dev/null +++ b/argocd/manifests/tailscale-operator-ringtail/external-secret.yaml @@ -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 diff --git a/argocd/manifests/tailscale-operator-ringtail/kustomization.yaml b/argocd/manifests/tailscale-operator-ringtail/kustomization.yaml new file mode 100644 index 0000000..a14ca81 --- /dev/null +++ b/argocd/manifests/tailscale-operator-ringtail/kustomization.yaml @@ -0,0 +1,10 @@ +--- +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization + +namespace: tailscale + +resources: + - ../tailscale-operator-base + - proxygroup-ingress.yaml + - external-secret.yaml diff --git a/argocd/manifests/tailscale-operator-ringtail/proxygroup-ingress.yaml b/argocd/manifests/tailscale-operator-ringtail/proxygroup-ingress.yaml new file mode 100644 index 0000000..9433da9 --- /dev/null +++ b/argocd/manifests/tailscale-operator-ringtail/proxygroup-ingress.yaml @@ -0,0 +1,11 @@ +--- +apiVersion: tailscale.com/v1alpha1 +kind: ProxyGroup +metadata: + name: ingress +spec: + type: ingress + replicas: 1 + proxyClass: default + tags: + - tag:k8s diff --git a/argocd/manifests/tailscale-operator/kustomization.yaml b/argocd/manifests/tailscale-operator/kustomization.yaml index dec1bbc..09fa1b8 100644 --- a/argocd/manifests/tailscale-operator/kustomization.yaml +++ b/argocd/manifests/tailscale-operator/kustomization.yaml @@ -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 diff --git a/docs/changelog.d/tailscale-operator-ringtail.infra.md b/docs/changelog.d/tailscale-operator-ringtail.infra.md new file mode 100644 index 0000000..c5442dc --- /dev/null +++ b/docs/changelog.d/tailscale-operator-ringtail.infra.md @@ -0,0 +1 @@ +Deploy Tailscale operator on ringtail k3s cluster -- 2.50.1 (Apple Git-155) From f028efbdf9ee3a3a80761911ee4b57058efd66d3 Mon Sep 17 00:00:00 2001 From: Erich Blume Date: Thu, 19 Feb 2026 09:32:13 -0800 Subject: [PATCH 2/2] Allow k8s-operator OAuth client to self-assign tag:k8s-operator The tagOwners for tag:k8s-operator didn't include tag:k8s-operator itself, so the OAuth client (tagged tag:k8s-operator) couldn't create auth keys for its own tag. Indri worked only due to cached login state. Co-Authored-By: Claude Opus 4.6 --- pulumi/tailscale/policy.hujson | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pulumi/tailscale/policy.hujson b/pulumi/tailscale/policy.hujson index e24ca48..e6ddb85 100644 --- a/pulumi/tailscale/policy.hujson +++ b/pulumi/tailscale/policy.hujson @@ -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"], -- 2.50.1 (Apple Git-155)