About the Project
This is the infrastructure-as-code side of my homelab. The goal is to make the lab reproducible enough that spinning up a service is not a ritual involving screenshots, forgotten commands, and me trying to remember which VM I edited by hand three weeks ago.
The current stack uses Terraform for Proxmox VM creation and Ansible for OS/service configuration. On top of that, I have wired up Jenkins, Gitea, SOPS, internal DNS, Caddy, and monitoring to make serving services more automated and state based. (A pretty good way of keeping track of stuff, and minimal effort needed to make changes if I do it right)
Scope
- Terraform: Proxmox VM definitions, clone/template flow, VLAN assignment, CPU/RAM/disk sizing, cloud-init.
- Ansible: bootstrap, users, SSH, packages, chrony, Caddy, BIND9, AdGuard/Unbound, Gitea, Jenkins, monitoring, K3s, and media roles.
- Secrets: SOPS for encrypted environment/secrets handling.
- CI/CD: Jenkins controller + agent path for linting, validation, Terraform plan/apply, and playbook/script execution.
- Source of truth: Gitea as the internal git home/mirror for homelab repos.
Current State
The current version can create and configure many of the core VMs: DNS resolvers, authoritative DNS, Caddy, Vaultwarden, Gitea, Jenkins, monitoring, Terraform controller, media VMs, and K3s nodes. It is not perfect, but it is already much better than rebuilding everything manually.
- Working: Debian cloud-init template with qemu-guest-agent.
- Working: Terraform VM creation for the main homelab VM groups.
- Working: Ansible bootstrap and several service roles.
- In progress: Jenkins integration with Terraform controller and SOPS secrets.
- In progress: AWX/Rancher/K3s cleanup after discovering that Kubernetes finalizers can be very funny when they are not happening to you.
- Next: better documentation, idempotence checks, monitoring checks, and restore testing.
Why I Care
This project is basically where my interests in Linux, networking, DevOps, SRE, and systems administration meet. It turns abstract ideas like idempotence, failure domains, DNS dependency chains, access control, and "source of truth" into things that can actually break my evening. (Big word farming)
Lessons Learned So Far
- DNS should be boring, redundant, and documented. Mine was not always all three.
- One big Docker Compose file is fun until the service count crosses the cognitive load limit.
- Internal CAs are nice, but every client still needs to trust them eventually.