Problem
plugins/cozystack/skills/ubuntu-bootstrap/SKILL.md describes Phase 6 (prepare-sudo.yml), Phase 7 (prepare-ubuntu.yml), and Phase 8 (k3s.orchestration.site) as three independent ansible-playbook invocations. Following the SKILL.md literally produces a misconfigured k3s — upstream-default behaviour rather than the cozystack-tuned one.
Upstream root cause is filed at cozystack/ansible-cozystack#43. Short version: prepare-ubuntu.yml passes cozystack_k3s_server_args and the k3s_cluster group to k3s.orchestration.site through set_fact and add_host, both of which only survive inside one ansible-playbook process. Split invocations silently drop them.
Observed behaviour
Running through the skill end-to-end on a fresh Ubuntu 24.04 single-node target:
- Phase 8 first fails with
'ansible_hostname' is undefined because k3s_cluster is empty in the new process.
- Patching the inventory with an explicit
k3s_cluster group makes Phase 8 succeed, but the resulting k3s has no cozystack flags — traefik, servicelb, metrics-server, local-path-provisioner, flannel, and kube-proxy are all running, --cluster-domain is cluster.local instead of cozy.local, and cluster-cidr / service-cidr are k3s defaults.
- This breaks the subsequent
cluster-install skill: KubeOVN / Cilium fight with flannel, the cozystack-provided ingress collides with traefik, and the operator either has to k3s-uninstall.sh and redo, or hand-patch the systemd unit.
Suggested fix
Phases 6-8 should be one ansible-playbook invocation taking all three playbooks as positional arguments. Multiple playbooks in one invocation share the playbook executor — set_fact and add_host survive between them, mirroring what upstream site.yml does with import_playbook.
# Current (broken):
ansible-playbook --inventory "$CONFIG_DIR/inventory.yml" prepare-sudo.yml # Phase 6
ansible-playbook --inventory "$CONFIG_DIR/inventory.yml" prepare-ubuntu.yml # Phase 7
ansible-playbook --inventory "$CONFIG_DIR/inventory.yml" k3s.orchestration.site # Phase 8
# Correct:
ansible-playbook --inventory "$CONFIG_DIR/inventory.yml" \
prepare-sudo.yml \
prepare-ubuntu.yml \
k3s.orchestration.site
prepare-sudo.yml can stay in the argument list always — it's a no-op on Ubuntu < 26.04, so the existing Phase 6 skip condition is unnecessary.
The phase boundaries remain useful for narrative — the operator should still see "starting OS prep / starting k3s install" — but all three must run in one ansible process. SKILL.md should state this explicitly: Pass all three playbooks to a single ansible-playbook invocation. Splitting them across separate invocations silently drops cozystack-tuned k3s flags.
Cross-reference
Problem
plugins/cozystack/skills/ubuntu-bootstrap/SKILL.mddescribes Phase 6 (prepare-sudo.yml), Phase 7 (prepare-ubuntu.yml), and Phase 8 (k3s.orchestration.site) as three independentansible-playbookinvocations. Following the SKILL.md literally produces a misconfigured k3s — upstream-default behaviour rather than the cozystack-tuned one.Upstream root cause is filed at cozystack/ansible-cozystack#43. Short version:
prepare-ubuntu.ymlpassescozystack_k3s_server_argsand thek3s_clustergroup tok3s.orchestration.sitethroughset_factandadd_host, both of which only survive inside oneansible-playbookprocess. Split invocations silently drop them.Observed behaviour
Running through the skill end-to-end on a fresh Ubuntu 24.04 single-node target:
'ansible_hostname' is undefinedbecausek3s_clusteris empty in the new process.k3s_clustergroup makes Phase 8 succeed, but the resulting k3s has no cozystack flags — traefik, servicelb, metrics-server, local-path-provisioner, flannel, and kube-proxy are all running,--cluster-domainiscluster.localinstead ofcozy.local, andcluster-cidr/service-cidrare k3s defaults.cluster-installskill: KubeOVN / Cilium fight with flannel, the cozystack-provided ingress collides with traefik, and the operator either has tok3s-uninstall.shand redo, or hand-patch the systemd unit.Suggested fix
Phases 6-8 should be one
ansible-playbookinvocation taking all three playbooks as positional arguments. Multiple playbooks in one invocation share the playbook executor —set_factandadd_hostsurvive between them, mirroring what upstreamsite.ymldoes withimport_playbook.prepare-sudo.ymlcan stay in the argument list always — it's a no-op on Ubuntu < 26.04, so the existing Phase 6 skip condition is unnecessary.The phase boundaries remain useful for narrative — the operator should still see "starting OS prep / starting k3s install" — but all three must run in one ansible process. SKILL.md should state this explicitly: Pass all three playbooks to a single
ansible-playbookinvocation. Splitting them across separate invocations silently drops cozystack-tuned k3s flags.Cross-reference
/etc/systemd/system/k3s.servicemissing every cozystack-tuned--disable=*and--flannel-backend=noneafter Phase 8 reported success.