For Agents
fk-devis the second VM in the levandor-infra Terraform root, provisioned on 2026-06-30 alongside the multi-VM refactor. It hosts the FaceKom dev mirror. The FaceKom team manages docker compose themselves via thevuer_dockerrepo — this infra repo only provides the base (Docker + monitoring + Tailscale). Read this entire note before touching fk-dev.
Required reading for fk-dev
If you’re an agent that has been asked to do anything touching
fk-dev, read this note first and the spec-1-multi-vm-refactor before issuing any commands.
Identity
| Property | Value |
|---|---|
| GCE name | fk-dev |
| GCP project | aerobic-tesla-490112-r3 |
| Region / zone | europe-west6 / europe-west6-a |
| Machine type | e2-standard-4 (4 vCPU / 16 GB RAM) |
| Boot disk | 100 GB pd-balanced |
| External IP | 34.158.19.122 (egress only — firewall denies all inbound) |
| Tailscale IP | 100.91.108.61 |
| Tailscale MagicDNS | fk-dev.taild4189d.ts.net |
| Tailscale tag | tag:cloud (NOT a new tag:dev — see decision below) |
| Service account | fk-dev-sa@aerobic-tesla-490112-r3.iam.gserviceaccount.com |
| VPC | fk-dev-net (custom-mode, isolated from pmv2-zurich’s VPC) |
| Subnet | fk-dev-subnet (10.2.0.0/24) |
| Inventory group | fk_dev_base (in ansible/site.yml) |
Specs rationale
- e2-standard-4 (4 vCPU / 16 GB): dev mirror for the FaceKom
vuer_*services — needs headroom forvuer_oss+vuer_css+vuer_cv+ auxiliary services running concurrently. pmv2-zurich’se2-smallwould not be enough. - 100 GB pd-balanced: FaceKom docker images are larger than pmv2’s (ML models, OCR pipelines). 100 GB gives room for 9+ services with image layers without churning.
- europe-west6-a (Zurich): kept in Switzerland for data-residency parity with the FaceKom production environment.
Network isolation
fk-dev lives in its own VPC (fk-dev-net) and subnet (10.2.0.0/24), separate from pmv2-zurich’s network. Two reasons:
- Independent firewall scoping — fk-dev’s needs (dev work, port forwarding for testing) are different from pmv2-zurich’s (production-tight).
- Easier cleanup — if fk-dev gets decommissioned, the VPC tears down with it cleanly.
Tailscale spans both VPCs at the application layer — operators reach either VM via MagicDNS.
Tailnet identity
| Aspect | Value |
|---|---|
| Tailnet | taild4189d |
| Magic DNS | fk-dev.taild4189d.ts.net |
| Tag | tag:cloud |
| Auth key | Reuses the existing pmv2 auth key (reusable + ephemeral + pre-authorized) |
Decision: tag:cloud, NOT tag:dev
The provisioning agent suggested creating a new
tag:devfor fk-dev to scope ACLs more tightly. Andras explicitly overrode this —tag:cloudis reused for simplicity. Same auth key, same ACL entry, fewer moving parts. If a future operator needs differentiated ACL rules for dev vs prod nodes, revisit this decision before adding more dev VMs.
The shared tag:cloud means fk-dev appears in the same Tailscale SSH ACL rule that already governs pmv2-zurich:
{ "action": "accept", "src": ["autogroup:member"], "dst": ["tag:cloud"], "users": ["ops", "root"] }Firewall posture
- Inbound: denied (default). Only the
tailscale_directrule allowsudp:41641for Tailscale NAT traversal. - Outbound: unrestricted (apt updates, Docker image pulls from
europe-west3-docker.pkg.dev, GitHub, Tailscale DERP). - No public SSH port — same Tailscale-only access model as pmv2-zurich.
Roles applied
fk-dev is in the fk_dev_base inventory group, which receives these roles via ansible/site.yml:
| Role | Purpose | Notes |
|---|---|---|
base | apt update/upgrade, fail2ban, unattended-upgrades, ops user, sudoers | Identical to pmv2-zurich. |
docker | Docker CE 29.6.1, compose plugin, gcloud apt repo, AR credential helper for europe-west3 | Cred helper points at the existing apps AR repo; fk-dev MAY pull pmv2 images for cross-service testing if needed, but typically pulls FaceKom-owned images. |
github_keys | (skipped) | No local deploy key — intentional for a dev box. FaceKom team will SSH-forward credentials or use HTTPS clones with PATs as needed. |
monitoring | OTel collector → ingest.eu2.signoz.cloud:443 + tailscaled Prometheus scrape on 127.0.0.1:5252 | Same SigNoz Cloud EU2 tenant as pmv2-zurich. Host metrics + tailscaled metrics ship. |
Roles NOT applied
| Role | Why excluded |
|---|---|
apps | pmv2-specific. fk-dev’s docker compose is operator-managed via the FaceKom vuer_docker repo, NOT via deploys/apps.yml. |
babylon | Babylon (Rust MCP coord) is a pmv2-fleet service. fk-dev doesn’t participate in pmv2 agent coordination. |
nats | NATS is the pmv2 event bus. fk-dev has no need to join it. |
bsc_exploit | pmv2-specific BSC exploit watcher. Irrelevant to FaceKom dev work. |
The exclusion is structural — fk-dev is in the fk_dev_base host group, and the pmv2_full play in site.yml (which loads apps + babylon + nats + bsc_exploit) doesn’t target it.
Babylon GCS write access
fk-dev’s service account is NOT in the babylon_backup_vm_writer IAM binding. The for_each on that resource filters to VMs whose ansible_groups contains pmv2_full. fk-dev’s groups are ["fk_dev_base"] — explicitly excluded.
resource "google_storage_bucket_iam_member" "babylon_backup_vm_writer" {
for_each = {
for k, v in var.vms : k => v
if contains(v.ansible_groups, "pmv2_full")
}
# …
}This is sensible scoping: a dev box has no business writing to the babylon backup bucket.
FaceKom team layering plan
The FaceKom team will deploy 9 services on top of the base provided by this repo, using the 8b multi-tailscaled sidecar pattern:
- Each service gets its own userspace tailscaled container.
- Each service gets its own MagicDNS name (e.g.
vuer-oss-dev.taild4189d.ts.net). - Each service gets its own
tailscale certfor TLS termination.
Reference patterns (managed by THIS repo, useful as templates):
- pmv2-zurich’s
babylonsidecar — see babylon-deploy-notes for the 3-service compose (babylon + litestream + babylon-tailscale). - pmv2-zurich’s
natssidecar — same Tailscale sidecar pattern.
Boundary: who owns what
This repo (
levandor/terraform) provisions and configures fk-dev’s base: VM, Docker, Tailscale node identity, OTel collector. Aftermake provision, the Ansible run stops there.The FaceKom
vuer_dockerrepo owns everything on top: docker compose, per-service tailscaled sidecars, per-service certs, per-service env files. Operators do NOT add fk-dev services todeploys/apps.yml.
How to reach fk-dev
# SSH (uses Tailscale SSH, no keypair needed)
make ssh VM=fk-dev
# or directly:
ssh ops@fk-dev.taild4189d.ts.net
# or by Tailscale IP:
ssh ops@100.91.108.61The Makefile defaults VM=pmv2-zurich for backwards compatibility — always pass VM=fk-dev for fk-dev work.
How to re-run Ansible on fk-dev
make configure # runs ALL plays (both pmv2-zurich and fk-dev)
# or limit:
ansible-playbook -i ansible/inventory/hosts.ini ansible/site.yml --limit fk-devThe site.yml split (per-host-group plays) means a make configure won’t accidentally apply pmv2-only roles to fk-dev.
Tailscaled restart drops the SSH session
The monitoring role’s “Restart tailscaled” handler will drop the ansible SSH session when fk-dev is being managed over tailnet SSH. Ansible reports
unreachable=1for fk-dev. The handler does succeed — re-runmake configureand the second run will showchanged=0, confirming convergence. See [[gcp-terraform-ansible-gotchas#39|gotcha #39]].
Cost estimate
Rough monthly steady-state:
- e2-standard-4 sustained-use: ~$98/mo
- 100 GB pd-balanced: ~$10/mo
- Ephemeral external IP: ~$3.65/mo
- Egress: variable, but dev box is low-traffic — assume ~$5/mo
**Total: ~18/mo at e2-small) but appropriate for the workload — 4 vCPU / 16 GB is what 9 concurrent services on a dev box require.
What NOT to do
- Don’t add fk-dev services to
deploys/apps.yml— that manifest is pmv2-fleet only. FaceKom team owns their own compose setup. - Don’t create a
tag:devwithout revisiting the decision above with Andras. - Don’t grant fk-dev’s SA write access to babylon backup bucket — the for_each filter is correct as-is.
- Don’t
make configurewithout checking which play limits you want — by default it runs every play. Use--limit fk-devto scope. - Don’t hand-configure docker compose on the VM — that’s FaceKom’s territory via
vuer_docker.
Related
- spec-1-multi-vm-refactor — the refactor that made fk-dev possible
- levandor-infra — project overview
- agent-guide-provision-new-vm — operator how-to for adding more VMs
- gcp-terraform-ansible-gotchas — gotcha #39 (tailscaled-restart handler drops SSH) surfaced during fk-dev provisioning
- babylon-deploy-notes — Tailscale sidecar pattern reference
- FaceKom — the project that will deploy onto fk-dev
- LOG
- TOPICS