Executed tasks — from-scratch.sh end-to-end run

Date: 2026-10-27 Working directory: content/opentofu Result: success — ./from-scratch.sh --yes exits 0; the Talos cluster, Forgejo, Argo CD, Traefik and the nginx demo are all deployed and reachable.


1. Environment

ItemValue
Proxmox APIhttps://192.168.0.141:8006/ (node proxmox)
Router LXC106 / k8s-router / eth0 192.168.0.250, eth1 10.10.50.1
Management LXC105 / k8s-management / eth0 192.168.0.201, eth1 10.10.50.5
Talos VMs103 talos-node-1 10.10.50.10, 102 talos-node-2 10.10.50.21, 101 talos-node-3 10.10.50.22
Talos OSv1.8.1 (boot ISO + installer image)
Kubernetesv1.31.1
OpenTofu1.13.0
Providersbpg/proxmox 0.115.x, siderolabs/talos 0.6.1, hashicorp/helm 2.x
Helm chartsargo-cd 10.11.6 (app v3.5.6), traefik 42.1.3, forgejo 15.0.11
Ansiblecore 2.21.5, collection ansible.posix

The physical control host has no route to 10.10.50.0/24, so all Talos / Kubernetes work runs inside the dual-homed management container. The Proxmox resources are created from the control host.


2. Summary

StageCommandResult
Prerequisitestofu, ansible-playbook, ssh, rsync, python3, Proxmox API authOK
Base infrastructuretofu init + targeted plan/apply (router, management, Talos VMs)OK, no changes on re-run
Management discoveryProxmox API lxc/105/interfaces → 192.168.0.201OK
Talos config applytofu apply -target=talos_machine_configuration_apply.nodes (remote)OK
Talos bootstraptofu apply -target=talos_machine_bootstrap.this (remote)OK
Cluster + Argo CDtofu apply -auto-approve (remote)OK
State syncremote terraform.tfstate → local (serial 32)OK
Management configansible-playbook site.ymlOK, failed=0
Forgejoansible-playbook forgejo.ymlOK, failed=0
Argo CD + GitOps + demoansible-playbook argocd.ymlOK, failed=0
Traefikansible-playbook traefik.ymlOK, failed=0
Full script re-run./from-scratch.sh --yesOK, exit 0, all playbooks failed=0

State serial progression: 24 (stale local) → 26 (config apply) → 28 (bootstrap + kubeconfig) → 31 (Argo CD Helm release) → 32 (final re-run, local and remote in sync).


3. Problems found and corrections applied

3.1 Provider versions did not match the lock file

3.2 Talos nodes stuck in booting / bootstrap connection refused

3.3 Health check timed out during first boot

3.4 All workloads Pending — control-plane taint

3.5 talos_version cannot be bumped on a live cluster

3.6 Tool version pinning had no effect

3.7 talosctl kubeconfig stdout syntax incompatible with v1.8.x

3.8 Hard-coded management IP

3.9 Script robustness (from-scratch.sh)

The orchestration script was rewritten to make the run repeatable:


4. Key commands executed

# Base infrastructure (control host)
cd content/opentofu
tofu init -input=false
tofu plan -input=false -out=tfplan \
  -target=proxmox_virtual_environment_container.router \
  -target=proxmox_virtual_environment_container.management \
  -target=proxmox_virtual_environment_vm.talos_nodes
tofu apply -input=false tfplan

# Cluster work (management container, reachable at 192.168.0.201)
ssh root@192.168.0.201
cd /root/opentofu
tofu init -input=false
tofu apply -target=talos_machine_configuration_apply.nodes -auto-approve
tofu apply -target=talos_machine_bootstrap.this -auto-approve
tofu apply -auto-approve

# Verification
export KUBECONFIG=/root/.kube/config
kubectl get nodes
kubectl get pods -A
kubectl -n argocd get applications
helm list -A

# Ansible (control host, inventory ansible_host=192.168.0.201)
cd ansible2
ansible-galaxy collection install -r requirements.yml
ansible-playbook site.yml
ansible-playbook forgejo.yml
ansible-playbook argocd.yml
ansible-playbook traefik.yml

# Full orchestration re-run
cd ..
./from-scratch.sh --yes

5. Final verification

$Nttt$Nnr$Na$HAaaaAgoArTkMlllkMiohMgcTuEooouEnteEouPbsssbxlcre---e-mdl2cnnncd0toootel-0ldddlmiHeeeosNa—g----tAr'e123nMgH"t-EoonaSSSnScsgnrYyyPdtioSRRRgNnnaA:ndTeeeoCccrCxeAaaaceegEnsTddddSddogdUyyyTcieSgAdnmeTR1xotUE-SVd—RcccaIeOooopSmALnnnpIorEtttlHHHO.gSrrriEeeNkoooocAaauClllaLllbD---tTtte"pppiHhhSdrllloyyTenaaanSApennnsTTlteeeAUoeTSysUe.SdlA555oG000cEmmmaCalHr'AgVvvvRohE111T-tR...ctS333dpI111-:O...1/N1110/.11912..616Av8P3.P.05.V.2E60R1S/ION

No pods outside Running/Completed. Local and remote state both at serial 32; tofu plan reports No changes.

Access:


6. Files changed

FileChange
main.tfProvider pins: Proxmox ~> 0.115.0, Talos ~> 0.6.0, Helm >= 2.0.0
talos.tfcluster.allowSchedulingOnControlPlanes; 30 min health timeout; talos_nodes/cluster_endpoint outputs; comment on the secrets/PKI pin
from-scratch.sh--yes/--skip-ansible, always init, targeted base apply, remote apply, state serial sync, dynamic management IP, inventory refresh, summary
ansible2/group_vars/all.ymlPinned talosctl 1.8.1, kubectl v1.31.1, helm 3.16.3
ansible2/roles/tools/tasks/main.ymlforce: true so version pins actually replace existing binaries
ansible2/roles/kubeconfig/tasks/main.ymlDownload kubeconfig to a temp file (--merge=false --force), slurp, remove; compatible with talosctl 1.8.x
ansible2/roles/kubeconfig/defaults/main.ymlkubeconfig_download_path
ansible2/hosts.ymlansible_host: 192.168.0.201 (rewritten by the script)
ansible2/traefik.ymlDynamic ansible_host/talos_endpoint_ip, ingress endpoint via --set-string
ansible2/argocd.ymlDynamic management IP in the final output
terraform.tfstate / .backup / .terraform.lock.hclSynced with the live cluster (serial 32)

7. Known caveats