# Topology — inventory and services ← Back to [Architecture index](README.md) ## 4. Inventory topology (`demo-gymburgdorf`) ```mermaid flowchart LR classDef dmz fill:#fee2e2,stroke:#991b1b,color:#000 classDef app fill:#dcfce7,stroke:#166534,color:#000 classDef stor fill:#dbeafe,stroke:#1e40af,color:#000 classDef turn fill:#fef9c3,stroke:#854d0e,color:#000 subgraph ALL["group: all_servers"] direction LR subgraph DMZ["DMZ 172.16.9.0/24"] RP["reverseproxy
172.16.9.111
traefik_mode: dmz"]:::dmz TURN["turn
172.16.9.112
(no role in site.yml yet)"]:::turn end subgraph BE["Backend 172.16.19.0/24
group: backend_servers"] APP["application
172.16.19.101
traefik_mode: backend
+ authentik, authentik_outpost_ldap,
nextcloud, collabora, drawio"]:::app ST["storage
172.16.19.102
traefik_mode: backend
+ garage (S3)"]:::stor end end RP -.HTTPS in, HTTP out.-> APP RP -.HTTPS in, HTTP out.-> ST ``` **Group memberships (from [hosts.yml](https://git.digitalboard.ch/Digitalboard/reference-ansible/src/branch/main/inventories/demo-gymburgdorf/hosts.yml)):** | Group | Members | Purpose | |---|---|---| | `all_servers` | `reverseproxy`, `application`, `storage`, `turn` | Base role for all hosts | | `traefik_servers` | `children: all_servers` (= all 4 hosts) | Traefik everywhere; DMZ/backend via `traefik_mode` | | `backend_servers` | `application`, `storage` | Sets `traefik_mode: backend` via group var | | `garage_servers` | `storage` | Single-host wrapper for the Garage role | | `nextcloud_servers`, `collabora_servers`, `drawio_servers`, `authentik_servers`, `authentik_outpost_ldap_servers` | `application` only | Single-host wrappers | > **Difference vs. the `vagrant` inventory:** `vagrant` structures > Traefik differently — via the children groups `traefik_servers_dmz` > and `traefik_servers_backend` instead of `backend_servers` + > `host_vars` override. The two topologies are **structurally > incompatible**; a 1:1 mapping is not possible. See > [operations.md](operations.md) for the recommended template. ## 5. Service layout and variable placement ```mermaid flowchart TB classDef rp fill:#fee2e2,stroke:#991b1b,color:#000 classDef ap fill:#dcfce7,stroke:#166534,color:#000 classDef st fill:#dbeafe,stroke:#1e40af,color:#000 classDef ext fill:#e9d5ff,stroke:#6b21a8,color:#000 Internet((Internet)) DNS["DNS ns1.digitalboard.ch
RFC2136 TSIG
Zone: demo-gymb._acme.digitalboard.ch
CNAME bridge: _acme-challenge.*.gymb.souveredu.ch"]:::ext BAO["OpenBao
bao.digitalboard.ch
mount: demo-gymburgdorf"]:::ext subgraph RP["reverseproxy — traefik dmz"] TRDMZ["traefik (file provider)
📍 group_vars/traefik_servers/traefik.yml
📍 host_vars/reverseproxy/traefik.yml
→ traefik_mode: dmz
→ traefik_dmz_exposed_services"]:::rp end subgraph APP["application — traefik backend"] TRA["traefik (docker provider)
📍 group_vars/backend_servers/traefik.yml"]:::ap AK["authentik (OIDC + LDAP outpost backend)
📍 host_vars/application/authentik.yml"]:::ap AKO["authentik_outpost_ldap
📍 host_vars/application/authentik_outpost_ldap.yml"]:::ap NC["nextcloud
📍 host_vars/application/nextcloud.yml"]:::ap COL["collabora
📍 host_vars/application/collabora.yml"]:::ap DRW["drawio
📍 host_vars/application/drawio.yml"]:::ap end subgraph ST["storage — traefik backend"] TRS["traefik (docker provider)"]:::st GAR["garage (S3)
📍 host_vars/storage/garage.yml"]:::st end Internet -->|HTTPS :443| TRDMZ TRDMZ -->|HTTP backend| TRA TRDMZ -->|HTTP backend| TRS TRA --> AK & AKO & NC & COL & DRW TRS --> GAR NC -. S3 .-> GAR NC -. OIDC .-> AK NC -. WOPI .-> COL NC -. LDAP .-> AKO AKO -. RPC + token .-> AK TRDMZ -. ACME DNS-01 TSIG .-> DNS TRDMZ -. hashi_vault acme-tsig .-> BAO AK -. hashi_vault secrets .-> BAO NC -. hashi_vault secrets .-> BAO GAR -. hashi_vault secrets .-> BAO ``` > **Note:** `opencloud`, `send`, `opnform`, `homarr`, and `bookstack` > are defined as plays in [playbooks/site.yml](https://git.digitalboard.ch/Digitalboard/reference-ansible/src/branch/main/playbooks/site.yml) > but currently have no matching group in > [hosts.yml](https://git.digitalboard.ch/Digitalboard/reference-ansible/src/branch/main/inventories/demo-gymburgdorf/hosts.yml) for > `demo-gymburgdorf` — those plays therefore run as no-ops. If a > tenant needs these services, add the corresponding > `_servers` group in `hosts.yml` and a > `host_vars/application/.yml` (mind the spelling — the > forms role is `opnform`, the LDAP role is `389ds`). > > The `turn` host is in `all_servers` (and therefore in > `traefik_servers`) but has **no** service group of its own — > currently only the `base` and `traefik` roles run on it.