--- - name: Create K3s config directory ansible.builtin.file: path: /etc/rancher/k3s state: directory mode: "0755" - name: Write K3s server config ansible.builtin.copy: dest: /etc/rancher/k3s/config.yaml content: "{{ k3s_server_config | to_nice_yaml }}" mode: "0644" - name: Download and install K3s ansible.builtin.shell: cmd: > curl -sfL https://get.k3s.io | INSTALL_K3S_VERSION={{ k3s_version }} sh - creates: /usr/local/bin/k3s # skip if already installed - name: Wait for K3s to be ready ansible.builtin.wait_for: path: /etc/rancher/k3s/k3s.yaml timeout: 60 - name: Ensure K3s service is running ansible.builtin.service: name: k3s state: started enabled: true - name: Read node token ansible.builtin.slurp: src: /var/lib/rancher/k3s/server/node-token register: k3s_token_raw - name: Save node token as fact ansible.builtin.set_fact: k3s_node_token: "{{ k3s_token_raw['content'] | b64decode | trim }}" - name: Print node token (needed for Phase 2 agent join) ansible.builtin.debug: msg: "K3s node token: {{ k3s_node_token }}" - name: Fetch kubeconfig to workstation ansible.builtin.fetch: src: /etc/rancher/k3s/k3s.yaml dest: ~/.kube/config flat: true - name: Fix kubeconfig server address ansible.builtin.replace: path: /tmp/k3s-minisforum.yaml regexp: 'https://127\.0\.0\.1:6443' replace: "https://{{ k3s_server_ip }}:6443" delegate_to: localhost become: false - name: Install Helm ansible.builtin.shell: cmd: curl -fsSL https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3 | bash creates: /usr/local/bin/helm - name: Label server node as primary ansible.builtin.shell: cmd: k3s kubectl label node minisforum node-role=primary --overwrite changed_when: false # label is idempotent but shell module always reports changed