diff --git a/.gitea/workflows/deploy.yml b/.gitea/workflows/deploy.yml index d1130cf..89286ab 100644 --- a/.gitea/workflows/deploy.yml +++ b/.gitea/workflows/deploy.yml @@ -17,6 +17,8 @@ env: TF_VAR_s3_endpoint: ${{ secrets.S3_ENDPOINT }} TF_VAR_s3_bucket: ${{ secrets.S3_BUCKET }} TF_VAR_tailscale_tailnet: ${{ secrets.TAILSCALE_TAILNET }} + TS_OAUTH_CLIENT_ID: ${{ secrets.TAILSCALE_OAUTH_CLIENT_ID }} + TS_OAUTH_CLIENT_SECRET: ${{ secrets.TAILSCALE_OAUTH_CLIENT_SECRET }} jobs: terraform: @@ -226,6 +228,8 @@ jobs: -e "hcloud_token=${{ secrets.HCLOUD_TOKEN }}" \ -e "tailscale_auth_key=${{ secrets.TAILSCALE_AUTH_KEY }}" \ -e "tailscale_tailnet=${{ secrets.TAILSCALE_TAILNET }}" \ + -e "tailscale_oauth_client_id=${{ secrets.TAILSCALE_OAUTH_CLIENT_ID }}" \ + -e "tailscale_oauth_client_secret=${{ secrets.TAILSCALE_OAUTH_CLIENT_SECRET }}" \ -e "grafana_admin_password=${{ secrets.GRAFANA_ADMIN_PASSWORD }}" \ -e "cluster_name=k8s-cluster" env: diff --git a/ansible/roles/observability/tasks/main.yml b/ansible/roles/observability/tasks/main.yml index a1ed7e8..42df453 100644 --- a/ansible/roles/observability/tasks/main.yml +++ b/ansible/roles/observability/tasks/main.yml @@ -208,7 +208,9 @@ - Tailnet FQDN: http://grafana.{{ tailscale_tailnet | default('tailnet.ts.net') }} Note: Ensure Tailscale Kubernetes Operator is installed first - when: tailscale_oauth_client_id is defined and tailscale_oauth_client_id | length > 0 + when: + - tailscale_oauth_client_id | default('') | length > 0 + - tailscale_oauth_client_secret | default('') | length > 0 - name: Show observability access details (fallback) debug: @@ -223,4 +225,5 @@ {% else %} Loki: Disabled {% endif %} - when: tailscale_oauth_client_id is not defined or tailscale_oauth_client_id | length == 0 + when: + - tailscale_oauth_client_id | default('') | length == 0 or tailscale_oauth_client_secret | default('') | length == 0 diff --git a/ansible/roles/tailscale-operator/defaults/main.yml b/ansible/roles/tailscale-operator/defaults/main.yml index 5d7ba87..5b2cb2c 100644 --- a/ansible/roles/tailscale-operator/defaults/main.yml +++ b/ansible/roles/tailscale-operator/defaults/main.yml @@ -5,4 +5,5 @@ tailscale_operator_version: "1.95.91" tailscale_oauth_client_id: "" tailscale_oauth_client_secret: "" -tailscale_operator_hostname: "" +tailscale_operator_default_tags: + - "tag:k8s-operator" diff --git a/ansible/roles/tailscale-operator/tasks/main.yml b/ansible/roles/tailscale-operator/tasks/main.yml index 2e21cdc..9ebc900 100644 --- a/ansible/roles/tailscale-operator/tasks/main.yml +++ b/ansible/roles/tailscale-operator/tasks/main.yml @@ -1,4 +1,18 @@ --- +- name: Determine if Tailscale operator is enabled + set_fact: + tailscale_operator_enabled: "{{ (tailscale_oauth_client_id | default('') | length) > 0 and (tailscale_oauth_client_secret | default('') | length) > 0 }}" + changed_when: false + +- name: Skip Tailscale operator when OAuth credentials are missing + debug: + msg: "Skipping Tailscale Kubernetes Operator: set TAILSCALE_OAUTH_CLIENT_ID and TAILSCALE_OAUTH_CLIENT_SECRET to enable it." + when: not tailscale_operator_enabled + +- name: End Tailscale operator role when disabled + meta: end_host + when: not tailscale_operator_enabled + - name: Check if Helm is installed command: helm version --short register: helm_check @@ -32,6 +46,15 @@ dest: /tmp/tailscale-operator-values.yaml mode: "0644" +- name: Create or update Tailscale operator OAuth secret + shell: >- + kubectl -n {{ tailscale_operator_namespace }} create secret generic operator-oauth + --from-literal=client_id='{{ tailscale_oauth_client_id }}' + --from-literal=client_secret='{{ tailscale_oauth_client_secret }}' + --dry-run=client -o yaml | kubectl apply -f - + register: oauth_secret_result + changed_when: "'created' in oauth_secret_result.stdout or 'configured' in oauth_secret_result.stdout" + - name: Install Tailscale Kubernetes Operator command: >- helm upgrade --install tailscale-operator tailscale/tailscale-operator @@ -39,9 +62,39 @@ --version {{ tailscale_operator_version }} --values /tmp/tailscale-operator-values.yaml --wait - --timeout 5m + --timeout 10m + register: tailscale_install + failed_when: false changed_when: true -- name: Wait for Tailscale operator to be ready - command: kubectl -n {{ tailscale_operator_namespace }} rollout status deployment/tailscale-operator --timeout=5m +- name: Show Tailscale operator pods on install failure + command: kubectl -n {{ tailscale_operator_namespace }} get pods -o wide + register: tailscale_pods + changed_when: false + failed_when: false + when: tailscale_install.rc != 0 + +- name: Show Tailscale operator events on install failure + command: kubectl -n {{ tailscale_operator_namespace }} get events --sort-by=.lastTimestamp + register: tailscale_events + changed_when: false + failed_when: false + when: tailscale_install.rc != 0 + +- name: Fail with Tailscale operator diagnostics + fail: + msg: | + Tailscale operator install failed. + Helm stderr: + {{ tailscale_install.stderr | default('') }} + + Pods: + {{ tailscale_pods.stdout | default('n/a') }} + + Events: + {{ tailscale_events.stdout | default('n/a') }} + when: tailscale_install.rc != 0 + +- name: Wait for Tailscale operator to be ready + command: kubectl -n {{ tailscale_operator_namespace }} rollout status deployment/operator --timeout=5m changed_when: false diff --git a/ansible/roles/tailscale-operator/templates/operator-values.yaml.j2 b/ansible/roles/tailscale-operator/templates/operator-values.yaml.j2 index e0579b4..af3bebb 100644 --- a/ansible/roles/tailscale-operator/templates/operator-values.yaml.j2 +++ b/ansible/roles/tailscale-operator/templates/operator-values.yaml.j2 @@ -1,12 +1,10 @@ -oauth: - clientId: "{{ tailscale_oauth_client_id }}" - clientSecret: "{{ tailscale_oauth_client_secret }}" - apiServerProxyConfig: mode: "true" operatorConfig: defaultTags: - - "tag:k8s-operator" +{% for tag in tailscale_operator_default_tags %} + - "{{ tag }}" +{% endfor %} installCRDs: true