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 am wiring Jenkins, Gitea, SOPS, internal DNS, Caddy, and monitoring into a workflow that can eventually act like a small internal platform.
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 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. That makes the learning stick.
Lessons Learned So Far
- DNS should be boring, redundant, and documented. Mine was not always all three.
- Guest agents matter when automation waits for VM state.
- 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.
- Kubernetes is powerful, but it is also very good at making a small problem look distributed.