No description
  • Python 34.8%
  • Jinja 26.5%
  • Dockerfile 23.8%
  • Shell 14.9%
Find a file
Repository files (latest commit first)
Filename Latest commit message Latest commit date
2026-11-06 18:03:07 +00:00
.github/workflows fix(ansible): remove heavy ci step 2026-07-24 22:33:10 -06:00
inventory feat(ansible): break playbooks into smaller chunks 2026-09-29 18:11:00 +00:00
playbooks feat(ansible): break playbooks into smaller chunks 2026-09-29 18:11:00 +00:00
roles feat(ansible): update playbook for resillience 2026-11-06 18:03:07 +00:00
tests feat(ansible): update playbook for resillience 2026-11-06 18:03:07 +00:00
.ansible-lint feat(ansible): summer cleanup 2026-07-24 22:30:04 -06:00
.gitignore (final): role done with otel collector and proper testing in molecule 2025-11-28 19:24:33 -06:00
AGENTS.md fix(ansible): dependencies upgrade 2026-10-05 18:38:38 +00:00
ansible.cfg feat(ansible): otel settings 2026-09-16 11:00:22 -05:00
LICENSE Initial commit 2023-12-22 16:25:04 -06:00
README.md feat(ansible): update playbook for resillience 2026-11-06 18:03:07 +00:00
requirements.txt feat(ansible): otel settings 2026-09-16 11:00:22 -05:00
requirements.yml fix(deps): add ansible.posix collection to requirements 2026-01-18 06:38:42 +00:00
Taskfile.yml fix(ansible): dependencies upgrade 2026-10-05 18:38:38 +00:00

Overview

Repo used to install and normalize some of the common tasks done in new machines.

Playbooks

Playbook Purpose
bootstrap.yaml Linux baseline, SSH/Tailscale/MOTD, shell dependencies and dotfiles links
k8s-node.yaml CNI path integration for explicitly inventoried k8s_nodes; does not install k3s
remote-work.yaml Agent/dev tooling and work repositories; run after bootstrap
maintenance.yaml Serial package upgrades and required reboots; no bootstrap or repository updates
demo.yaml Scratch playbook used for recordings
task bootstrap LIMIT=eva01
task k8s-node LIMIT=eva01
task remote-work LIMIT=eva01
task maintenance LIMIT=eva01 -- --check  # preflight only, not an upgrade simulation
task maintenance LIMIT=homelab_nodes

Run bootstrap, Kubernetes integration (cluster nodes only), then remote work in sequence when provisioning. Maintenance runs independently afterward.

Task wrappers require an explicit LIMIT; arguments after -- pass to Ansible. Direct playbook runs still require ANSIBLE_ROLES_PATH=$PWD/roles when not using Task. Use task deps to provide the controller's Kubernetes Python client at .venv/bin/python. Override node_maintenance_python if using another controller interpreter. Kubernetes control-plane calls fail closed if the client hangs: read/health checks use node_maintenance_kubernetes_read_timeout (default 60s), while drain uses node_maintenance_kubernetes_action_timeout (default drain timeout + 60s). Cluster reads retry three times. Drain retries transient API failures using node_maintenance_drain_retries (default 4) and node_maintenance_drain_retry_delay (default 15s) before stopping the rollout.

Rolling Maintenance

All six current homelab nodes are explicitly listed in k8s_nodes. Keep this group accurate: other homelab_nodes receive OS maintenance without Kubernetes calls. Override node_maintenance_node_name when Kubernetes and inventory names differ. The controller needs a readable kubeconfig and permission to inspect nodes, cordon/uncordon and evict pods. Set KUBECONFIG or override node_maintenance_kubeconfig; do not rely on k3s' root-only /etc/rancher/k3s/k3s.yaml when running Ansible as an unprivileged user.

For each node: require all cluster nodes Ready → drain → safe apt upgrades → reboot if /var/run/reboot-required exists → wait for Node Ready → restore schedulability → verify cluster readiness. Non-Kubernetes hosts skip the cluster operations. serial: 1 and any_errors_fatal: true stop rollout on failure. Previously cordoned nodes remain cordoned. Failure does not automatically uncordon unhealthy nodes; inspect the failure and node before manual recovery. Cluster readiness checks do not guarantee application health; monitor workloads during a maintenance window.

Drain respects PodDisruptionBudgets and refuses unmanaged pods. EmptyDir/local ephemeral data deletion is enabled by default so common controllers such as Flux, metrics-server and StatefulSet config scratch space do not block planned node maintenance. Override node_maintenance_delete_emptydir_data: false for a stricter preflight. Do not bypass a failed drain to continue updates. node_maintenance_force_reboot: true reboots even without the Debian/Ubuntu reboot marker.

The maintenance tag selects the entire maintenance sequence; individual steps have no separate tags. Do not use --start-at-task or custom skip-tags to bypass safety steps. Check mode performs cluster preflight only and makes no maintenance changes.

Schedule from one controller, using its scheduler's no-overlap/concurrency control, captured logs and failure notifications. For example, a monthly job can run task maintenance LIMIT=homelab_nodes from this repository with the controller's kubeconfig available. Provisioning/agent installers are deliberately excluded. No schedule is installed by this repository.

Testing

Since this is ansible we use molecule to test the various scenarios done by the roles/playbooks.

Everything is driven from Taskfile.yml at the repo root via Task — no need to cd into a role or export ANSIBLE_ROLES_PATH by hand.

task               # list every task and the roles that have a scenario
task test          # full molecule run for node_setup
task converge      # apply the role, leave the container up for poking at
task login         # shell into that container
task destroy       # clean up
task lint          # ansible-lint over the repo

task test ROLE=<role>   # pick a different role

Needs a running Docker daemon. If molecule isn't available, task deps rebuilds .venv from requirements.txt.