Configuring with Ansible
Ansible installs and configures the software running inside each server — Docker, application stacks, CI runners, monitoring agents — after Terraform has provisioned the underlying VM (see Provisioning with Terraform).
Inventory and access
ansible/hetzner-main/inventory.ini groups the Proxmox VMs by role (builders, synthesis_test, webserver, observability, api_gateway, services_user, services_staff), referencing the SSH aliases set up in Getting Started rather than literal IPs — ansible.cfg sets a fixed remote user (ansible-control) and disables host-key checking, relying on the ProxyJump config instead. Amergin and Puca have their own separate inventories under ansible/amergin/ and ansible/puca/, since neither is reached through the same jump host.
The pattern common to every VM
Nearly every playbook follows the same shape:
- Install Docker CE from Docker's official apt repo, and configure
/etc/docker/daemon.jsonwith an insecure-registry entry for10.0.0.2:5000(the legacyservicesVM, which hosts the shared internal registry). - Create a dedicated
deployuser, authorized with the CI runner's SSH public key, so GitHub Actions / Gitea Actions workflows cansshin directly and rundocker compose pull && up -d— rather than embedding registry or server credentials in CI secrets. - Run Grafana Alloy as a standalone container (outside any app's own Compose stack), shipping logs and metrics to the observability VM. What gets tailed differs per VM — a specific log file, the Docker socket for container discovery, or an nginx access log.
- Configure UFW: allow SSH, allow the webserver VM as the reverse-proxy ingress, deny everything else inbound by default.
Tags
Playbooks are tagged so a single run can do exactly as much as intended:
setup— full first-time bring-up of a VM (installs everything).update— safe to re-run against a live VM; re-applies idempotent configuration without disruptive steps.apps— redeploys only the application Compose stacks (pull + up), without touching base VM configuration. Used bymake deploy-services-user-apps/make deploy-services-staff-apps.- Stack-specific tags for stateful apps that shouldn't be bundled with the stateless
appstag — e.g.gitea,rocketchaton services-staff, orgitea-runneron docker-build.
See Common Operations for the full list of Make targets that wrap these tags.