--- - name: Prepare k3s synchronization metadata hosts: k3s_hosts gather_facts: false run_once: true tasks: - name: Initialize k3s sync source host ansible.builtin.set_fact: k3s_sync_source_host: "" delegate_to: localhost delegate_facts: true - name: Select k3s init server as sync source ansible.builtin.set_fact: k3s_sync_source_host: "{{ item }}" loop: "{{ groups['k3s_hosts'] }}" when: hostvars[item].k3s_cluster_init | default(false) | bool delegate_to: localhost delegate_facts: true - name: Require a k3s init server as sync source ansible.builtin.assert: that: - hostvars['localhost'].k3s_sync_source_host | length > 0 fail_msg: "No k3s init server found. Ensure a host has k3s_cluster_init: true." - name: Ensure sync source is included in this run ansible.builtin.assert: that: - hostvars['localhost'].k3s_sync_source_host in ansible_play_hosts_all fail_msg: "Sync source {{ hostvars['localhost'].k3s_sync_source_host }} is not in this run. Include it in --limit." - name: Create local temp directory for k3s sync ansible.builtin.tempfile: state: directory prefix: k3s-sync- register: k3s_sync_tmpdir delegate_to: localhost - name: Store k3s sync metadata on controller ansible.builtin.set_fact: k3s_sync_source_host: "{{ hostvars['localhost'].k3s_sync_source_host }}" k3s_sync_tmpdir_path: "{{ k3s_sync_tmpdir.path }}" k3s_sync_tls_bundle: "{{ k3s_sync_tmpdir.path }}/k3s-tls.tgz" delegate_to: localhost delegate_facts: true - name: Collect k3s token and certs from init server hosts: k3s_hosts become: true gather_facts: false run_once: true vars: k3s_sync_source_host: "{{ hostvars['localhost'].k3s_sync_source_host | default('') }}" k3s_sync_tls_bundle: "{{ hostvars['localhost'].k3s_sync_tls_bundle | default('') }}" tasks: - name: Require a k3s sync source ansible.builtin.assert: that: - k3s_sync_source_host | length > 0 fail_msg: "k3s sync source is empty. Ensure the init server is reachable." - name: Ensure k3s node token exists ansible.builtin.stat: path: /var/lib/rancher/k3s/server/node-token register: k3s_node_token delegate_to: "{{ k3s_sync_source_host }}" - name: Fail when k3s node token is missing ansible.builtin.fail: msg: "k3s node token not found at /var/lib/rancher/k3s/server/node-token" when: not k3s_node_token.stat.exists - name: Read k3s node token ansible.builtin.slurp: src: /var/lib/rancher/k3s/server/node-token register: k3s_node_token_raw delegate_to: "{{ k3s_sync_source_host }}" - name: Store k3s sync token on controller ansible.builtin.set_fact: k3s_sync_token: "{{ k3s_node_token_raw.content | b64decode | trim }}" delegate_to: localhost delegate_facts: true - name: Check for k3s tls directory ansible.builtin.stat: path: /var/lib/rancher/k3s/server/tls register: k3s_tls_dir delegate_to: "{{ k3s_sync_source_host }}" - name: Create k3s tls bundle ansible.builtin.archive: path: /var/lib/rancher/k3s/server/tls dest: /tmp/k3s-tls.tgz format: gz when: k3s_tls_dir.stat.exists delegate_to: "{{ k3s_sync_source_host }}" - name: Fetch k3s tls bundle ansible.builtin.fetch: src: /tmp/k3s-tls.tgz dest: "{{ k3s_sync_tls_bundle }}" flat: true when: k3s_tls_dir.stat.exists delegate_to: "{{ k3s_sync_source_host }}" - name: Mark tls bundle presence on controller ansible.builtin.set_fact: k3s_sync_tls_bundle_present: "{{ k3s_tls_dir.stat.exists }}" delegate_to: localhost delegate_facts: true - name: Remove temporary tls bundle from source ansible.builtin.file: path: /tmp/k3s-tls.tgz state: absent when: k3s_tls_dir.stat.exists delegate_to: "{{ k3s_sync_source_host }}" - name: Synchronize k3s token and certs to servers hosts: k3s_hosts become: true serial: 1 gather_facts: false vars: k3s_sync_source_host: "{{ hostvars['localhost'].k3s_sync_source_host }}" k3s_sync_token: "{{ hostvars['localhost'].k3s_sync_token | default('') }}" k3s_sync_tls_bundle: "{{ hostvars['localhost'].k3s_sync_tls_bundle | default('') }}" k3s_sync_tls_bundle_present: "{{ hostvars['localhost'].k3s_sync_tls_bundle_present | default(false) }}" pre_tasks: - name: Require k3s sync token ansible.builtin.assert: that: - k3s_sync_token | length > 0 fail_msg: "k3s sync token is empty. Check the init server token." tasks: - name: Stop k3s before syncing ansible.builtin.import_role: name: k3s tasks_from: stop when: inventory_hostname != k3s_sync_source_host - name: Sync k3s token and certs ansible.builtin.import_role: name: k3s tasks_from: sync when: inventory_hostname != k3s_sync_source_host