homelab/build/config/ansible/roles/k3s_node/tasks/server.yml
Russell Seymour 1250c9cef6
Some checks are pending
deploy / deploy (push) Waiting to run
Initial checkin of code for managing homelab
2026-08-24 20:52:36 +01:00

103 lines
4.3 KiB
YAML

---
# Bootstraps this node as the (single) k3s control plane. playbooks/k3s.yml
# runs the k3s_control_plane play before k3s_workers, so by the time
# agent.yml runs anywhere, K3S_URL below already points at something live.
#
# The token comes from Vault as a fixed, pre-shared value rather than letting
# k3s generate one on first install — see docs/vault-secrets.md
# (homelab/k3s-homelab-utils). That's what makes a full rebuild (wipe both SD
# cards, reinstall) reproduce the same cluster identity instead of needing the
# new token hunted down and re-distributed by hand.
#
# --node-name pins the k8s node object to the Ansible inventory_hostname
# rather than whatever the OS hostname happens to be — roles/k3s_maintenance
# addresses nodes by inventory_hostname when draining/uncordoning, and that
# only works if the two names are guaranteed to match.
- name: Bootstrap the k3s server
no_log: true # K3S_TOKEN passes through this block
block:
- name: Look up the k3s cluster secrets
ansible.builtin.set_fact:
k3s_secrets: >-
{{ lookup('community.hashi_vault.vault_kv2_get',
k3s_vault_path,
engine_mount_point=vault_kv_mount,
url=vault_addr,
auth_method=vault_auth_method,
role_id=vault_role_id | default(omit),
secret_id=vault_secret_id | default(omit)).secret }}
- name: Compute the desired k3s server exec line
ansible.builtin.set_fact:
k3s_server_exec: >-
server --node-name {{ inventory_hostname }} --tls-san {{ k3s_api_tls_san }}
--write-kubeconfig-mode 644 {{ (k3s_extra_args + k3s_server_extra_args) | join(' ') }}
# Compared against what k3s was last installed with (see the copy task
# below) so a change to k3s_extra_args/k3s_server_extra_args — or
# k3s_api_tls_san — gets applied on the next run instead of silently
# sitting unused: the version check below has no way to notice an
# exec-line-only change. Missing file (first install) counts as changed.
- name: Read the exec line k3s was last installed with
ansible.builtin.slurp:
src: /etc/rancher/k3s/.ansible_install_exec
register: k3s_installed_exec_raw
failed_when: false
check_mode: false
- name: Determine whether the exec line has changed
ansible.builtin.set_fact:
k3s_exec_changed: >-
{{ k3s_installed_exec_raw.content is not defined
or (k3s_installed_exec_raw.content | b64decode) != k3s_server_exec }}
- name: Check the installed k3s version
ansible.builtin.command: k3s --version
register: k3s_installed_version
changed_when: false
failed_when: false
check_mode: false
# The installer is safe to re-run — it's a no-op if the requested version
# and exec line are already active — but skipping it when neither changed
# avoids restarting the service (and briefly dropping the API) on every
# playbook run. Restarting the k3s process itself (as opposed to
# rebooting the node, which roles/k3s_maintenance handles separately) is
# a brief control-plane/kubelet blip, not a pod outage — containerd keeps
# every already-running pod up underneath it.
- name: Install/upgrade k3s server
ansible.builtin.shell: curl -sfL https://get.k3s.io | sh -
environment:
INSTALL_K3S_VERSION: "{{ k3s_version }}"
INSTALL_K3S_EXEC: "{{ k3s_server_exec }}"
K3S_TOKEN: "{{ k3s_secrets.K3S_TOKEN }}"
when: >-
k3s_installed_version.rc != 0
or k3s_version not in k3s_installed_version.stdout
or k3s_exec_changed
- name: Ensure the k3s service is enabled and running
ansible.builtin.systemd_service:
name: k3s
enabled: true
state: started
# k3s creates /etc/rancher/k3s itself once it has something to put there
# (the generated kubeconfig, on the server) — defensive rather than relied
# on, so this marker doesn't assume the directory already exists.
- name: Ensure /etc/rancher/k3s exists
ansible.builtin.file:
path: /etc/rancher/k3s
state: directory
owner: root
group: root
mode: "0755"
- name: Record the exec line k3s was installed with
ansible.builtin.copy:
dest: /etc/rancher/k3s/.ansible_install_exec
content: "{{ k3s_server_exec }}"
owner: root
group: root
mode: "0600"