# Fedora host provisioning This directory configures already-installed Fedora 44 hosts. Infrastructure can be created manually or by the hand-maintained Terraform configuration; both paths produce the same input: two reachable hosts in `inventory.yml`. Node 1 runs the k3s server. Node 2 runs a k3s agent. The playbook is idempotent and may be rerun to converge package, firewall, k3s, and service state. ## Automated path Copy `inventory.example.yml` to `inventory.yml`, replace the addresses and node IP values, set `k3s_node_cidr` to the network containing only cluster nodes, set `k3s_operator_cidrs` to the authorized administration networks, and set the SSH user and connection options required by those hosts. The managed machines may be physical servers, VMs from any provider, or manually installed systems; the playbook does not depend on libvirt or the local lab subnet. Then provide the existing cluster token only in the process environment: ```bash K3S_TOKEN="$(openssl rand -hex 32)" ./bootstrap.sh inventory.yml ``` The bootstrap checks for `ansible-playbook` and installs the declared Ansible collections. It does not install system packages on the operator machine. Do not save the token in the inventory or repository. Preserve it in the operator's secret manager so a replacement agent can join the same cluster. ## Manual path Use `manual-checklist.md` when configuration must be performed interactively. It describes the same end state as the playbook, so a manually prepared host can later be managed by Ansible without rebuilding it. ## Terraform path Terraform is responsible only for creating machines, networks, and addresses. After `terraform apply`, put its resulting addresses into `inventory.yml` and run this playbook. Keeping configuration out of provisioner hooks makes the same Ansible workflow usable for physical hardware, VMs, and manually created hosts. ## One-command local QEMU lab `lab.sh` is only a disposable integration harness for this workstation. Its `virbr0` interface, fixed test addresses, UFW forwarding rules, cloud image, and NetworkManager profiles are deliberately kept out of the reusable Ansible roles. Do not run it on the two production machines; put their real addresses in an inventory and run `bootstrap.sh` instead. On an x86_64 Fedora or Arch-family workstation with hardware virtualization enabled: ```bash ./lab.sh ``` To reuse an existing Fedora 44 Cloud Base Generic QCOW2 image instead of downloading another copy: ```bash FEDORA_IMAGE=/path/to/Fedora-Cloud-Base-Generic-44.x86_64.qcow2 ./lab.sh up ``` The lab intentionally supports x86_64 only. Both target Fedora hosts and the workstation used for the final project run x86_64, so maintaining a separate aarch64 image, firmware, and verification path would add an untested platform without helping the deployment demonstration. The Fedora Server Guest Generic image is not suitable for this workflow because it starts the interactive initial-setup program instead of accepting cloud-init configuration. The command installs missing host packages, enables libvirt, uses the selected local image or downloads the Fedora 44 cloud image, creates two reusable VMs, waits for ping and SSH, runs the Ansible configuration, and verifies applications, services, directories, ports, and Kubernetes node readiness. Its VM metadata and SSH key live under `${XDG_STATE_HOME:-$HOME/.local/state}/nereus-lab`, outside the repository. Subsequent operations are `./lab.sh check`, `./lab.sh stop`, and the explicitly destructive `./lab.sh destroy`. Deleting a VM also deletes any k3s local-path volumes stored on that machine. The lab recreates the host and its Kubernetes identity, but stateful demo data on the deleted disk must be recreated separately. This is acceptable for the disposable harness and is not a backup strategy. ### Tested lab capacity The complete two-node stack passed provisioning, reboot, node-disconnect recovery, workload readiness, and public API checks on 2026-08-24 with 2 vCPUs, 3 GiB RAM, and a 30 GiB virtual disk per node. These are the lowest settings tested for this project, not a production sizing recommendation. The thin QCOW2 files used approximately 2.0 GiB for node 1 and 3.3 GiB for node 2 during that verification.