diff --git a/.taskfiles/talos/Taskfile.yaml b/.taskfiles/talos/Taskfile.yaml new file mode 100644 index 00000000..62ea4659 --- /dev/null +++ b/.taskfiles/talos/Taskfile.yaml @@ -0,0 +1,166 @@ +--- +# yaml-language-server: $schema=https://taskfile.dev/schema.json +version: "3" + +tasks: + bootstrap: + desc: Bootstrap Talos + summary: | + Args: + cluster: Cluster to run command against (default: homelab) + controller: Controller node to run command against (required) (IP/DNS) + prompt: Bootstrap Talos on the cluster... continue? + cmds: + - task: bootstrap-etcd + vars: &vars + cluster: '{{.cluster | default "homelab"}}' + controller: "{{.controller}}" + - task: fetch-kubeconfig + vars: *vars + - task: bootstrap-integrations + vars: *vars + requires: + vars: + - controller + + bootstrap-etcd: + desc: Bootstrap Etcd + cmd: until talosctl --context {{.cluster}} --nodes {{.controller}} bootstrap; do sleep 10; done + requires: + vars: + - cluster + - controller + + bootstrap-integrations: + desc: Bootstrap core integrations needed for Talos + cmds: + - until kubectl --context {{.cluster}} wait --for=condition=Ready=False nodes --all --timeout=600s; do sleep 10; done + - helmfile --kube-context {{.cluster}} --file {{.KUBERNETES_DIR}}/bootstrap/helmfile.yaml apply --skip-diff-on-install --suppress-diff + - until kubectl --context {{.cluster}} wait --for=condition=Ready nodes --all --timeout=600s; do sleep 10; done + requires: + vars: + - cluster + preconditions: + - which helmfile + - sh: kubectl config get-contexts {{.cluster}} + msg: "Kubectl context {{.cluster}} not found" + - test -f {{.KUBERNETES_DIR}}/bootstrap/helmfile.yaml + + fetch-kubeconfig: + desc: Fetch kubeconfig from Talos controllers + cmd: | + talosctl --context {{.cluster}} kubeconfig --nodes {{.controller}} \ + --force --force-context-name {{.cluster}} {{.ROOT_DIR}}/kubeconfig + requires: + vars: + - cluster + preconditions: + - talosctl config get-contexts | grep {{.cluster}} + + generate-clusterconfig: + desc: Generate clusterconfig for Talos + cmds: + - talhelper genconfig + --env-file {{.KUBERNETES_DIR}}/bootstrap/talos/talenv.sops.yaml + --secret-file {{.KUBERNETES_DIR}}/bootstrap/talos/talsecret.sops.yaml + --config-file {{.KUBERNETES_DIR}}/bootstrap/talos/talconfig.yaml + --out-dir {{.KUBERNETES_DIR}}/bootstrap/talos/clusterconfig + requires: + vars: + - cluster + preconditions: + - which talhelper + - test -f {{.KUBERNETES_DIR}}/bootstrap/talos/talenv.sops.yaml + - test -f {{.KUBERNETES_DIR}}/bootstrap/talos/talsecret.sops.yaml + - test -f {{.KUBERNETES_DIR}}/bootstrap/talos/talconfig.yaml + + upgrade: + desc: Upgrade Talos version for a node + vars: + TALOS_VERSION: + sh: | + yq -r ".talosVersion" {{.KUBERNETES_DIR}}/bootstrap/talos/talconfig.yaml + TALOS_IMAGE: + sh: | + talhelper genurl installer \ + --env-file {{.KUBERNETES_DIR}}/bootstrap/talos/talenv.sops.yaml \ + --config-file {{.KUBERNETES_DIR}}/bootstrap/talos/talconfig.yaml + cmds: + - talosctl --context {{.cluster}} upgrade -n {{.node}} --image {{.TALOS_IMAGE }} + requires: + vars: + - cluster + - node + preconditions: + - which talhelper + - talosctl config get-contexts | grep {{.cluster}} + - test -f {{.KUBERNETES_DIR}}/bootstrap/talos/talenv.sops.yaml + - test -f {{.KUBERNETES_DIR}}/bootstrap/talos/talconfig.yaml + - msg: "Talos image could not be determined for {{.node}}" + sh: 'test -n "{{.TALOS_IMAGE}}"' + + upgrade-k8s: + desc: Upgrade Kubernetes version for a Talos cluster + vars: + KUBERNETES_VERSION: + sh: | + yq -r ".kubernetesVersion" {{.KUBERNETES_DIR}}/bootstrap/talos/talconfig.yaml + CONTROLPLANE_NODE: + sh: | + talosctl --context {{.cluster}} config info \ + | grep Endpoints: \ + | awk '{split($0,u," "); print u[2]}' \ + | sed -E 's/,//' + cmds: + - talosctl upgrade-k8s -n {{.CONTROLPLANE_NODE}} --to {{.KUBERNETES_VERSION}} + requires: + vars: + - cluster + preconditions: + - which talhelper + - talosctl config get-contexts | grep {{.cluster}} + - test -f {{.KUBERNETES_DIR}}/bootstrap/talos/talenv.sops.yaml + - test -f {{.KUBERNETES_DIR}}/bootstrap/talos/talconfig.yaml + - msg: "Kubernetes version could not be determined for cluster {{.cluster}}" + sh: 'test -n "{{.KUBERNETES_VERSION}}"' + - msg: "Control plane node could not be determined for cluster {{.cluster}}" + sh: 'test -n "{{.CONTROLPLANE_NODE}}"' + + apply-clusterconfig: + desc: Apply clusterconfig for a Talos cluster + vars: + CLUSTERCONFIG_FILES: + sh: find {{.KUBERNETES_DIR}}/bootstrap/talos/clusterconfig -type f -name '*.yaml' -printf '%f\n' + cmds: + - for: + var: CLUSTERCONFIG_FILES + task: _apply-machineconfig + vars: + cluster: "{{ .cluster }}" + filename: "{{.ITEM}}" + hostname: |- + {{ trimPrefix (printf "%s-" .cluster) .ITEM | trimSuffix ".yaml" }} + dry_run: "{{ .dry_run }}" + requires: + vars: + - cluster + preconditions: + - talosctl config get-contexts | grep {{.cluster}} + - test -d {{.KUBERNETES_DIR}}/bootstrap/talos/clusterconfig + + _apply-machineconfig: + internal: true + desc: Apply a single Talos machineConfig to a Talos node + cmds: + - talosctl --context {{.cluster}} apply-config + --nodes "{{.hostname}}" + --file "{{.KUBERNETES_DIR}}/bootstrap/talos/clusterconfig/{{.filename}}" + {{ if eq "true" .dry_run }}--dry-run{{ end }} + requires: + vars: + - cluster + - hostname + - filename + preconditions: + - talosctl config get-contexts | grep {{.cluster}} + - test -f {{.KUBERNETES_DIR}}/bootstrap/talos/clusterconfig/{{.filename}} diff --git a/Taskfile.yaml b/Taskfile.yaml index 88e9110e..7bcc27a0 100644 --- a/Taskfile.yaml +++ b/Taskfile.yaml @@ -22,6 +22,9 @@ includes: flux: dir: .taskfiles/flux taskfile: .taskfiles/flux + talos: + taskfile: ".taskfiles/talos" + dir: .taskfiles/talos tasks: default: