--- - name: Build kubeconfig fetch candidates ansible.builtin.set_fact: k3s_kubeconfig_source_candidates: "{{ groups['k3s_hosts'] | default([inventory_hostname]) }}" - name: Initialize kubeconfig source host ansible.builtin.set_fact: k3s_kubeconfig_source_host: "" - name: Select k3s init server as kubeconfig source (preferred) ansible.builtin.set_fact: k3s_kubeconfig_source_host: "{{ item }}" loop: "{{ k3s_kubeconfig_source_candidates }}" when: - (k3s_kubeconfig_source_host | length) == 0 - hostvars[item].k3s_role | default('agent') == 'server' - hostvars[item].k3s_cluster_init | default(false) | bool - name: Fallback to first k3s server as kubeconfig source ansible.builtin.set_fact: k3s_kubeconfig_source_host: "{{ item }}" loop: "{{ k3s_kubeconfig_source_candidates }}" when: - (k3s_kubeconfig_source_host | length) == 0 - hostvars[item].k3s_role | default('agent') == 'server' - name: Final fallback to current host as kubeconfig source ansible.builtin.set_fact: k3s_kubeconfig_source_host: "{{ inventory_hostname }}" when: (k3s_kubeconfig_source_host | length) == 0 - name: Require kubeconfig source host ansible.builtin.assert: that: - (k3s_kubeconfig_source_host | length) > 0 fail_msg: "Unable to select a k3s kubeconfig source host." - name: Determine kubeconfig API server URL ansible.builtin.set_fact: k3s_kubeconfig_api_server: >- {{ (k3s_server_url | trim) if (k3s_server_url | default('') | trim | length) > 0 else 'https://' ~ k3s_kubeconfig_source_host ~ ':6443' }} - name: Read k3s kubeconfig from source node ansible.builtin.slurp: src: /etc/rancher/k3s/k3s.yaml register: _k3s_kubeconfig_raw delegate_to: "{{ k3s_kubeconfig_source_host }}" become: true - name: Rewrite kubeconfig server to primary endpoint ansible.builtin.set_fact: k3s_kubeconfig_rendered: >- {{ _k3s_kubeconfig_raw.content | b64decode | regex_replace('server:\s*https?://\S+', 'server: ' ~ k3s_kubeconfig_api_server) }} - name: Validate rendered kubeconfig YAML (controller-side scripts depend on this) ansible.builtin.set_fact: _k3s_kubeconfig_parsed: "{{ k3s_kubeconfig_rendered | from_yaml }}" changed_when: false - name: Require kubeconfig to contain required keys ansible.builtin.assert: that: - _k3s_kubeconfig_parsed is mapping - (_k3s_kubeconfig_parsed.clusters | default([])) | length > 0 - (_k3s_kubeconfig_parsed.contexts | default([])) | length > 0 - (_k3s_kubeconfig_parsed.users | default([])) | length > 0 - (_k3s_kubeconfig_parsed['current-context'] | default('') | length) > 0 fail_msg: >- Rendered kubeconfig is invalid or missing required keys. Refusing to save {{ playbook_dir }}/../../prole-k3s.kubeconfig. - name: Save kubeconfig locally for controller-side init scripts ansible.builtin.copy: content: "{{ k3s_kubeconfig_rendered }}" dest: "{{ playbook_dir }}/../../prole-k3s.kubeconfig" mode: "0600" delegate_to: localhost become: false