Self-hosting on bare metal with Ansible

The openzro-ansible repository ships idempotent roles + playbooks that install the openZro server stack (management, signal, relay, dashboard) on bare-metal Linux hosts (Debian/Ubuntu, RHEL/Rocky/Fedora). The roles wrap the native server packages from pkg.openzro.io so each daemon runs as a plain systemd unit — no container layer.

This is the third deployment path openZro supports, alongside Docker Compose and Kubernetes.

When to choose Ansible

ScenarioUse AnsibleUse ComposeUse Kubernetes
Multiple Linux VMs in one or more regions⚠️ One host⚠️ Heavy lift if K8s isn't already there
You want zero container runtime on prod hosts✅ Native systemd❌ Docker required❌ K8s required
You already manage infra with Ansible✅ Native fit⚠️ Manual playbook⚠️ Mixed paradigm
You need cloud LB integration (ALB / GCP HTTPS LB)✅ Built-in roles❌ Manual⚠️ Service LoadBalancer
You need rolling zero-downtime updatesupdate.yml drains LB targets❌ Single host✅ Helm rolling restart
You're prototyping on a laptop⚠️ Heavier than Compose✅ Single command⚠️ k3d / kind
You want declarative GitOps from CRDs✅ Operator + CRDs

What's in the repo

Roles wrap the native packages and add the operational glue:

RoleWhat it does
openzro_managementInstalls openzro-management, renders /etc/openzro/management.json, wires Postgres/SQLite, OIDC, cluster coordinator
openzro_signalInstalls openzro-signal, env file, systemd
openzro_relayInstalls openzro-relay, exposed-address config
openzro_routing_peerInstalls the openzro client as a routing peer (subnet gateway / exit node) — runs openzro up with a vault-encrypted setup key, sets v4/v6 forwarding sysctls. Exposed CIDRs are configured at the management side via Network Resources
openzro_dashboardContainer today (apt package on the openZro roadmap)
openzro_nginxReverse proxy + TLS (certbot HTTP-01 / DNS-01 / BYO / self-signed)
openzro_nats_clusterOptional standalone NATS for HA management coordinator
openzro_redis_clusterOptional standalone Redis (master/replica)
aws_lbALB + NLB + ACM + Route53 wiring (when openzro_cloud=aws)
gcp_lbHTTPS LB + NLB + managed cert + Cloud DNS (gcp)
commonapt/yum repo setup, GPG key import

Playbooks under playbooks/:

  • site.yml — full stack provisioning (run once per host)
  • update.yml — rolling update with cloud LB drain/undrain
  • management.yml / signal.yml / relay.yml / dashboard.yml — per-component, useful for component-specific upgrades or splitting deployments
  • routing_peer.yml — provisions one or more routing peers (subnet gateways / exit nodes) into an existing mesh. Targets hosts grouped under routing_peers in inventory; safe to run against an arbitrary number of replicas in different regions

Section contents

Known gaps

The repo is production-ready for its current scope; these aren't blockers but worth knowing before you commit:

  • No openzro_postgres role. Postgres is assumed managed (RDS, Cloud SQL) or installed manually. The role consumes a DSN, not a Postgres install.
  • No backup/restore role for the management datastore. SQL dumps are expected to come from your DB layer's own tooling.
  • openzro_redis_cluster ships as master/replica with manual promotion — no Sentinel-based auto-failover. For real HA Redis use a managed service (Elasticache, Memorystore).