# Variables — hierarchy and cheatsheet
← Back to [Architecture index](README.md)
## 3. Variable hierarchy
Ansible merges variables from multiple sources. Simplified model for
this repo (see the Ansible docs for the full precedence rules):
```mermaid
flowchart LR
classDef role fill:#fef3c7,stroke:#92400e,color:#000
classDef group fill:#dbeafe,stroke:#1e40af,color:#000
classDef host fill:#dcfce7,stroke:#166534,color:#000
classDef vault fill:#fee2e2,stroke:#991b1b,color:#000
R["role defaults
(lowest precedence)
collections/.../roles/<r>/defaults/main.yml"]:::role
GA["group_vars/all/
vault.yml, docker.yml"]:::group
GG["group_vars/<group>/
traefik_servers/, backend_servers/
(parallel groups, merged via
ansible_group_priority)"]:::group
HV["host_vars/<host>/
(highest of the three inventory sources)"]:::host
BAO["OpenBao
lookup at runtime"]:::vault
R --> |"<overridden by>"| GA
GA --> |"<overridden by>"| GG
GG --> |"<overridden by>"| HV
HV -.community.hashi_vault.-> BAO
GG -.community.hashi_vault.-> BAO
```
**Key properties:**
- Multiple `group_vars//` are **parallel**, not hierarchically
nested. `traefik_servers` and `backend_servers` are merged by
`ansible_group_priority` (default 1); on conflict the
alphabetically-later group name wins.
- `host_vars//` beats any group.
- `host_vars/reverseproxy/traefik.yml: traefik_mode: dmz` therefore
overrides the default from `group_vars/backend_servers/` — and only
because `reverseproxy` is not a member of `backend_servers` in the
first place (otherwise the override wouldn't even be needed).
**Bao lookups** are not a precedence layer but **values** inside any
variable source. See [security.md](security.md) for the pattern.
## 9. Variable cheatsheet
| Variable | Where in `demo-gymburgdorf/` | Why |
|---|---|---|
| `vault_addr`, `vault_mount` | `group_vars/all/vault.yml` | Bao endpoint applies site-wide |
| `docker_registry_mirrors` | `group_vars/all/docker.yml` | Pulls from mirror on all hosts |
| `traefik_acme_*`, `traefik_use_ssl`, `traefik_cert_mode` | `group_vars/traefik_servers/traefik.yml` | Applies to every Traefik instance (dmz + backend) |
| `traefik_mode: backend` | `group_vars/backend_servers/traefik.yml` | Default for app + storage |
| `traefik_mode: dmz` | `host_vars/reverseproxy/traefik.yml` | Host-specific override |
| `traefik_dmz_exposed_services` | `host_vars/reverseproxy/` | DMZ backend list — only meaningful here |
| `nextcloud_*`, `authentik_*`, `collabora_*`, `drawio_*` | `host_vars/application/.yml` | Service runs on `application` |
| `garage_*` | `host_vars/storage/garage.yml` | Service runs on `storage` |
| Secrets (passwords, tokens, keys) | inline variable using `lookup('community.hashi_vault.hashi_vault', …)` | Single source of truth via Bao |