# 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 |