# NetBird GitOps Reconciler — PoC Deployment Ansible playbook that deploys a self-contained stack on VPS-A for end-to-end testing of the NetBird GitOps reconciler. ## Stack overview | Component | Purpose | | ------------ | ------------------------------------------- | | Caddy | TLS termination, reverse proxy | | NetBird | Management, Signal, Relay, Dashboard, TURN | | Reconciler | Declarative config → NetBird API reconciler | | Gitea | Git server for GitOps source-of-truth | | Gitea Runner | Executes CI workflows (Actions) | All services run as Docker containers on a single VPS, connected via a `netbird` Docker bridge network. Caddy handles ACME certificates automatically. ## Prerequisites - SSH access to `46.225.220.61` (root, key-based) - DNS A records: - `vps-a.networkmonitor.cc` → `46.225.220.61` - `gitea.vps-a.networkmonitor.cc` → `46.225.220.61` - `rsync` installed locally (used to sync reconciler source) - Ansible 2.15+ with `community.general` and `ansible.posix` collections Install collections if needed: ```bash ansible-galaxy collection install community.general ansible.posix ``` ## Deployment (multi-phase) The deployment is intentionally multi-phase because some tokens can only be obtained after services are running. ### Phase 1: Initial deploy ```bash cd poc/ansible cp group_vars/all/vault.yml.example group_vars/all/vault.yml ansible-playbook -i inventory.yml playbook.yml ``` The playbook will: 1. Generate secrets (encryption key, TURN password, relay secret, reconciler token) 2. Install Docker, configure UFW 3. Rsync the reconciler source code and build the Docker image 4. Template configs and start all services 5. Skip the Gitea Actions runner (no token yet) 6. Print a summary with generated secrets **Save the generated secrets** into `vault.yml` so subsequent runs are idempotent. ### Phase 2: Create NetBird admin + API token 1. Open `https://vps-a.networkmonitor.cc` in a browser 2. Create the first admin account (embedded IdP — no external OAuth) 3. Go to **Settings → Personal Access Tokens → Generate** 4. Copy the token into `vault.yml` as `vault_netbird_api_token` ### Phase 3: Set up Gitea 1. Open `https://gitea.vps-a.networkmonitor.cc` and complete the install wizard 2. Create an admin account (user: `blastpilot`) 3. Create org `BlastPilot` and repo `netbird-gitops` 4. Generate a Gitea API token (**Settings → Applications**) → `vault_gitea_token` 5. Go to **Site Administration → Actions → Runners** → copy runner registration token → `vault_gitea_admin_password` and `vault_gitea_runner_token` ### Phase 4: Re-deploy with all tokens ```bash ansible-playbook -i inventory.yml playbook.yml ``` This run will: - Start the reconciler with a valid NetBird API token - Register and start the Gitea Actions runner - Wire the reconciler to poll Gitea for `netbird.json` changes ### Phase 5: Push code and test CI ```bash cd /path/to/netbird-gitops git remote add poc git@gitea.vps-a.networkmonitor.cc:BlastPilot/netbird-gitops.git git push poc main ``` Then configure Gitea repo secrets (Settings → Actions → Secrets): - `RECONCILER_TOKEN` — the reconciler bearer token - `RECONCILER_URL` — `https://vps-a.networkmonitor.cc/reconciler` - `GITEA_TOKEN` — same Gitea API token Create a branch, modify `netbird.json`, open a PR — the dry-run workflow should post a plan as a PR comment. ## Testing Replace `` with `vault_reconciler_token`. ### Health check ```bash curl https://vps-a.networkmonitor.cc/reconciler/health ``` ### Dry-run reconcile ```bash curl -X POST \ -H "Authorization: Bearer " \ -H "Content-Type: application/json" \ -d @ansible/files/netbird-seed.json \ 'https://vps-a.networkmonitor.cc/reconciler/reconcile?dry_run=true' ``` ### Apply reconcile ```bash curl -X POST \ -H "Authorization: Bearer " \ -H "Content-Type: application/json" \ -d @ansible/files/netbird-seed.json \ 'https://vps-a.networkmonitor.cc/reconciler/reconcile' ``` ### Export current state ```bash curl -H "Authorization: Bearer " \ 'https://vps-a.networkmonitor.cc/reconciler/export' ``` ## Teardown Remove all containers and volumes: ```bash ssh root@46.225.220.61 "cd /opt/netbird-poc && docker compose down -v" ``` Stop the runner: ```bash ssh root@46.225.220.61 "systemctl stop gitea-runner && systemctl disable gitea-runner" ``` ## File structure ``` poc/ ansible/ inventory.yml # VPS-A host definition playbook.yml # Main deployment playbook .gitignore # Excludes vault.yml group_vars/ all/ vars.yml # Non-secret config (versions, ports, etc.) vault.yml.example # Secret template — copy to vault.yml templates/ docker-compose.yml.j2 # All services (NetBird + Gitea + Reconciler) management.json.j2 # NetBird management config Caddyfile.j2 # Caddy reverse proxy (NetBird + Gitea) dashboard.env.j2 # NetBird dashboard env relay.env.j2 # NetBird relay env turnserver.conf.j2 # TURN server config reconciler.env.j2 # Reconciler env files/ netbird-seed.json # Example desired state for testing README.md # This file ```