# Complete Tailscale Operator Setup # This includes all necessary RBAC, ServiceAccounts, and CRDs --- # ServiceAccount for operator apiVersion: v1 kind: ServiceAccount metadata: name: operator namespace: tailscale --- # ServiceAccount for proxies apiVersion: v1 kind: ServiceAccount metadata: name: proxies namespace: tailscale --- # ClusterRole with all required permissions apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: name: tailscale-operator rules: # Core resources - apiGroups: [""] resources: - nodes - pods - services - endpoints - persistentvolumeclaims - configmaps - secrets - serviceaccounts verbs: ["*"] # Apps resources - apiGroups: ["apps"] resources: - statefulsets - deployments - replicasets verbs: ["*"] # RBAC resources - apiGroups: ["rbac.authorization.k8s.io"] resources: - roles - rolebindings - clusterroles - clusterrolebindings verbs: ["*"] # Tailscale CRDs - apiGroups: ["tailscale.com"] resources: - connectors - proxyclasses - dnsconfigs - recorders - proxygroups verbs: ["*"] # API extensions - apiGroups: ["apiextensions.k8s.io"] resources: - customresourcedefinitions verbs: ["get", "list", "watch"] # Discovery - apiGroups: ["discovery.k8s.io"] resources: - endpointslices verbs: ["get", "list", "watch"] # Networking - apiGroups: ["networking.k8s.io"] resources: - ingresses - ingressclasses verbs: ["*"] --- # ClusterRoleBinding for operator apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: name: tailscale-operator roleRef: apiGroup: rbac.authorization.k8s.io kind: ClusterRole name: tailscale-operator subjects: - kind: ServiceAccount name: operator namespace: tailscale --- # Role for proxies apiVersion: rbac.authorization.k8s.io/v1 kind: Role metadata: name: proxies namespace: tailscale rules: - apiGroups: [""] resources: ["secrets"] verbs: ["create", "get", "update", "patch"] - apiGroups: [""] resources: ["events"] verbs: ["create", "get", "list", "watch"] --- # RoleBinding for proxies apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding metadata: name: proxies namespace: tailscale roleRef: apiGroup: rbac.authorization.k8s.io kind: Role name: proxies subjects: - kind: ServiceAccount name: proxies namespace: tailscale --- # OAuth Secret - REPLACE WITH YOUR CREDENTIALS apiVersion: v1 kind: Secret metadata: name: operator-oauth namespace: tailscale stringData: client_id: "YOUR_CLIENT_ID" client_secret: "YOUR_CLIENT_SECRET" --- # Tailscale Operator Deployment apiVersion: apps/v1 kind: Deployment metadata: name: operator namespace: tailscale spec: replicas: 1 selector: matchLabels: app: tailscale-operator template: metadata: labels: app: tailscale-operator spec: serviceAccountName: operator containers: - name: operator image: tailscale/k8s-operator:stable env: - name: OPERATOR_HOSTNAME value: tailscale-operator - name: OPERATOR_SECRET value: operator - name: OPERATOR_LOGGING value: info - name: OPERATOR_NAMESPACE valueFrom: fieldRef: fieldPath: metadata.namespace - name: CLIENT_ID_FILE value: /oauth/client_id - name: CLIENT_SECRET_FILE value: /oauth/client_secret - name: PROXY_IMAGE value: tailscale/tailscale:stable - name: APISERVER_PROXY value: "false" - name: PROXY_FIREWALL_MODE value: auto volumeMounts: - name: oauth mountPath: /oauth readOnly: true volumes: - name: oauth secret: secretName: operator-oauth --- # ProxyClass for managing proxy configurations apiVersion: tailscale.com/v1alpha1 kind: ProxyClass metadata: name: default spec: statefulSet: pod: tailscale: containerBoot: # Additional Tailscale container configurations if needed --- # IngressClass for Tailscale (if using Ingress) apiVersion: networking.k8s.io/v1 kind: IngressClass metadata: name: tailscale spec: controller: tailscale.com/ingress-controller