Replaces the four-task Caddy vhost block currently copy-pasted into 10
playbooks. Nothing calls it yet; this commit only adds the role.
Verified by rendering all 10 sites through the template and diffing against
what the current playbooks produce: 9 of 10 byte-identical. The tenth is
datum-gateway, where the resolvers comment is standardised, rewriting one
comment line Caddy ignores.
Then dry-run against the live hosts (--check, nothing written):
- vipy: forgejo, vaultwarden, lnbits, personal-blog, ntfy-emergency-app
all report ok/unchanged against the real files
- watchtower: ntfy renders identical via caddy_site_body, blank line and
{host}{uri} placeholders intact
- spacey: headscale renders identical when given the config that is
actually running
- memos, mempool, datum-gateway report changed - the comment, as expected
All 14 site files on all 3 hosts confirmed unchanged afterwards.
Two things the build turned up:
- Ansible does not template dict *keys*, so caddy_site_basic_auth is a list
of {user, hash}. As a dict, a Jinja username passes through literally.
The assert refuses a mapping.
- `caddy validate` does accept a single site fragment - rc=0 on a good one,
rc=1 with a line number on a broken one. This was the plan's one untested
claim. A failed validate leaves the live file untouched.
The reload is now a handler, so it fires once at end of play rather than
immediately; anything needing the new config live mid-play must
flush_handlers first.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
23 lines
1.1 KiB
YAML
23 lines
1.1 KiB
YAML
---
|
|
# Required
|
|
caddy_site_name: "" # file basename -> <name>.conf
|
|
caddy_site_domain: "" # site address line; may hold several, comma separated
|
|
|
|
# Pick exactly one shape
|
|
caddy_site_upstream: "" # "localhost:3000" -> reverse_proxy
|
|
caddy_site_root: "" # filesystem path -> root * + file_server
|
|
caddy_site_body: "" # raw escape hatch for one-off sites; wins over both
|
|
|
|
# reverse_proxy modifiers
|
|
caddy_site_resolvers: "" # "100.100.100.100" for Tailscale MagicDNS
|
|
caddy_site_headers_up: {} # {"X-Forwarded-Host": "wallet.example.com"}
|
|
# A LIST, not a dict: Ansible does not template dict *keys*, so a Jinja
|
|
# expression for the username silently passes through as literal text.
|
|
caddy_site_basic_auth: [] # [{user: "{{ x_user }}", hash: "{{ x_hash }}"}]
|
|
|
|
# Placement. caddy_sites_dir comes from services_config.yml; this is the fallback.
|
|
caddy_sites_dir: /etc/caddy/sites-enabled
|
|
|
|
# Rendered site files can carry credentials (basic_auth hashes), so --diff is
|
|
# suppressed by default. Pass -e caddy_site_reveal=true to see what moved.
|
|
caddy_site_reveal: false
|