Baseline Setup, Part 6 – Automating the Rebuild with Git and Ansible
The final piece of the rebuild: how I use Ansible and Git to automate service deployment, node setup, and config management across my homelab—so I can rebuild fast when it matters.
This is where it all comes together.
I’ve rebuilt my homelab more times than I care to admit. Power outages, OS corruption, config drift, “let me just try this real quick”—they all have a way of spiraling. That’s why this time, I set out to make the rebuild rebuildable.
In this final post of the Baseline Setup series, I’ll walk through how I use Ansible and Git to make sure I can tear everything down and be back online in minutes—with services deployed, config in place, and secrets managed securely.
🧠 The Goal
I wanted to be able to:
- Stand up new nodes in <30 minutes
- Deploy core services without clicking around
- Keep infrastructure and config versioned and documented
- Make changes in Git and push, instead of SSH-ing and hoping
It’s not full-blown GitOps, but it’s close enough for a one-man homelab.
🧑✈️ Overseer: The Orchestration Node
All automation runs from Overseer, my out-of-cluster admin box that handles:
- Running Ansible playbooks
- Holding secure secrets in
.env
and vaults - Keeping repo clones of all service configs and manifests
It’s not a part of the Kubernetes cluster, which means I can nuke a node and reprovision it without breaking the system that provisions it.
📁 Repo Structure
Here’s how I organize the Git repo:
sundarideploy/
├── ansible/
│ ├── hosts
│ ├── playbooks/
│ └── roles/
├── services/
│ ├── Homepage/
│ ├── traefik/
│ └── Authentik/
├── k8s/
│ ├── manifests/
│ └── kustomize/
└── .env
Each service folder has its own Docker Compose (for non-K8s stuff) or K8s manifests, plus the Ansible logic to deploy them if needed.
⚙️ Provisioning New Nodes
When I get a new bare metal node, I:
- Flash Ubuntu Server
- Assign it a static IP on the network
SSH in and run the prep_instance.sh
script:
!/bin/bash
adduser ansibleadmin
usermod -aG sudo ansibleadmin
curl https://github.com/warpapaya.keys >> /home/ansibleadmin/.ssh/authorized_keys
apt update && apt install -y docker.io git curl
Then from Overseer, I run:
ansible-playbook -i ansible/hosts ansible/playbooks/setup.yml
This installs MicroK8s, joins the cluster, enables required add-ons, and verifies status.
🛠️ Service Deployment
Each service has:
- A Git-tracked config folder
- A Kustomize overlay for Kubernetes
- A
deploy.sh
orkubectl apply
command baked into the Ansible role
If I want to change something—like a route in Traefik or a service env var—I change the YAML in Git, push, and reapply from Overseer.
🔐 Secrets Management
Secrets are:
- Pulled from a local
.env
file for Compose - Injected into K8s via sealed secrets or pre-rendered manifests
- Never committed in plain text
Still room for improvement here (considering Bitwarden CLI or Vault), but for now it’s controlled and reproducible.
🧠 Lessons Learned
- Automate your rebuild before you need it
- Keep orchestration out-of-band—it’s your recovery plan
- Version everything, even your YAML
- Git isn’t just for devs—it’s for ops too
🏁 Series Wrap-Up
That’s the full baseline.
From bare metal to bootstrapped cluster, routed apps, SSO, and a dashboard I actually use—plus automation to do it again if (when) something breaks.
Thanks for following along. Now it’s time to start building on top of this.