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.

Baseline Setup, Part 6 – Automating the Rebuild with Git and Ansible
Photo by Roman Synkevych / Unsplash

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:

  1. Flash Ubuntu Server
  2. 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 or kubectl 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.