--- - name: Bootstrap Kubernetes cluster hosts: cluster become: true gather_facts: true pre_tasks: - name: Wait for SSH wait_for_connection: delay: 10 timeout: 300 roles: - common - name: Setup primary control plane hosts: control_plane[0] become: true vars: k3s_primary: true k3s_token: "{{ lookup('password', '/dev/null length=32 chars=ascii_letters,digits') }}" k3s_primary_private_ip: "{{ k3s_private_ip }}" k3s_primary_public_ip: "{{ ansible_host }}" k3s_primary_ip: "{{ k3s_private_ip }}" k3s_node_ip: "{{ k3s_private_ip }}" roles: - k3s-server - name: Get join info from primary hosts: control_plane[0] become: true tasks: - name: Fetch node token command: cat /var/lib/rancher/k3s/server/node-token register: node_token changed_when: false - name: Set join token fact set_fact: k3s_token: "{{ node_token.stdout }}" k3s_primary_private_ip: "{{ k3s_private_ip }}" k3s_primary_public_ip: "{{ ansible_host }}" - name: Fetch kubeconfig fetch: src: /etc/rancher/k3s/k3s.yaml dest: ../outputs/kubeconfig flat: true - name: Setup secondary control planes hosts: control_plane[1:] become: true vars: k3s_primary: false k3s_token: "{{ hostvars[groups['control_plane'][0]]['k3s_token'] }}" k3s_primary_ip: "{{ hostvars[groups['control_plane'][0]]['k3s_primary_private_ip'] }}" k3s_primary_public_ip: "{{ hostvars[groups['control_plane'][0]]['k3s_primary_public_ip'] }}" k3s_node_ip: "{{ k3s_private_ip }}" roles: - k3s-server - name: Setup workers hosts: workers become: true vars: k3s_token: "{{ hostvars[groups['control_plane'][0]]['k3s_token'] }}" k3s_server_url: "https://{{ hostvars[groups['control_plane'][0]]['k3s_primary_private_ip'] }}:6443" k3s_node_ip: "{{ k3s_private_ip }}" roles: - k3s-agent - name: Deploy Hetzner CCM hosts: control_plane[0] become: true roles: - ccm - name: Deploy Hetzner CSI hosts: control_plane[0] become: true roles: - csi - name: Deploy observability stack hosts: control_plane[0] become: true roles: - observability - name: Finalize hosts: localhost connection: local tasks: - name: Update kubeconfig server address command: | sed -i 's/127.0.0.1/{{ groups["control_plane"][0] }}.{{ tailscale_tailnet }}/g' ../outputs/kubeconfig changed_when: true - name: Display success message debug: msg: | Cluster setup complete! Control planes: {{ groups['control_plane'] | length }} Workers: {{ groups['workers'] | length }} To access the cluster: export KUBECONFIG={{ playbook_dir }}/../outputs/kubeconfig kubectl get nodes