Three-Phase Infrastructure as Code
Bare-metal to running services with a clean tool separation and live-state handoff: Terraform provisions, Ansible configures by reading Terraform state directly, and Komodo reconciles committed TOML to running Compose stacks on every push.
View Code on GitHubProvisioning phases
The design keeps three tools in their lanes and lets state flow between them instead of being copied. Twelve LXC containers and a six-VM Talos Kubernetes cluster all come out of the same workflow.
State flows, it isnβt copied
Terraform (run through Terragrunt, state in S3-compatible object storage) provisions every host and generates a dedicated SSH key per machine. Ansibleβs inventory is a script that reads that Terraform state live β there is no generated inventory file to fall out of sync, and a freshly provisioned host is immediately configurable. Configuration follows a bootstrap-then-harden model: an initial user configures the machine, then root login and password auth are disabled behind it.
Push-to-reconcile services
Committed Komodo resource definitions (TOML) describe every Compose stack. A git push fires a webhook to the Komodo control plane, which syncs the resources and runs one batch procedure that redeploys only the stacks whose content actually changed β a deliberate choice over redeploying every service on every commit. Day-2 service changes are pure Git operations.
Resilience where it hurts most
The services this layer runs are the ones everything else depends on, so the critical ones are deployed as high-availability pairs on separate hosts β two DNS filters and two authoritative DNS servers. The DNS stack runs on custom Docker images built and cosign-signed in CI rather than pulled straight from upstream. Retired architecture generations are kept in a documented archive β including the K3s era the current Talos cluster replaced.
Key Technical Highlights
- Strict phase separation: Terraform owns provisioning (Proxmox hosts + cluster VMs via the bpg provider, state in S3-compatible object storage), Ansible owns configuration, Komodo owns service deployment β no phase leaks into another.
- Live-state handoff: Ansible's dynamic inventory reads Terraform state directly β no generated inventory YAML to drift. Terraform even emits per-host SSH keys the later phases consume.
- Push-to-reconcile services: A git push triggers a ResourceSync plus a single batch procedure that redeploys only the Compose stacks whose content actually changed β no fan-out across every host.
- Packaged as a collection: Ansible roles ship as a versioned collection (common system/users/ssh/docker, Komodo, and cluster roles) with a two-user bootstrap-then-harden model and Vault-managed secrets.