#cloud-config hostname: ${hostname} manage_etc_hosts: true users: - name: k3s groups: sudo shell: /bin/bash sudo: ALL=(ALL) NOPASSWD:ALL ssh_authorized_keys: - ${ssh_public_key} package_update: true packages: - curl # A script instead of a plain runcmd line for one reason: Terraform (see # main.tf's closing comment) brings all VMs up in parallel, with no # ordering guarantee that the server finishes installing k3s before an # agent tries to join it. Baking the retry loop into a script keeps that # concern out of runcmd, which just calls it once. write_files: - path: /usr/local/bin/join-k3s.sh permissions: '0755' content: | #!/bin/sh # Server may still be booting; retry the join until it answers. # /ping is k3s's own unauthenticated liveness endpoint — this only # confirms the API server is accepting connections yet, it's not a # credential check (K3S_TOKEN below is what actually authorizes the # join once it happens). until curl -sk https://${server_ip}:6443/ping >/dev/null 2>&1; do echo "waiting for k3s server at ${server_ip}..." sleep 5 done # Agents pass the token via environment variables to the installer # rather than a config.yaml file (contrast server.yaml.tpl) because # get.k3s.io's own install script reads K3S_URL/K3S_TOKEN directly # for the "join an existing cluster" path — there's no separate # agent config file it looks for the way the server has one. curl -sfL https://get.k3s.io | \ K3S_URL="https://${server_ip}:6443" \ K3S_TOKEN="${k3s_token}" \ sh -s - agent runcmd: - /usr/local/bin/join-k3s.sh