- Caddy ersetzt den Hetzner-LB: terminiert TLS (Portal-Domain automatisch) und load-balanced per reverse_proxy über die App-Nodes. Für Custom-Domains (§11) On-Demand-TLS, autorisiert über GET /internal/tls-allowed. - TlsCheckController + DomainRepository::findVerifiedByHostname: erlaubt Zertifikate nur für Portal-Domain oder verifizierte Domains (Schutz vor Cert-Flooding). - Terraform: hcloud_load_balancer entfernt, Caddy-Server + Firewall (80/443) + cloud-init-caddy (Caddyfile templated mit Upstreams/Domain/ACME). - Optional Hetzner DNS via API (manage_dns): A-Record Portal + Wildcard → Caddy. - nginx.prod: /internal zu Symfony geroutet; APP_PORTAL_DOMAIN-Env. Validiert: Caddyfile (caddy validate), Terraform (validate), /internal/tls-allowed (200/403/400). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
33 lines
1000 B
HCL
33 lines
1000 B
HCL
# Optional: DNS-Records über die Hetzner DNS API anlegen (manage_dns = true).
|
|
# Voraussetzung: Zone liegt bei Hetzner DNS, separater DNS-API-Token.
|
|
|
|
data "hetznerdns_zone" "zone" {
|
|
count = var.manage_dns ? 1 : 0
|
|
name = var.dns_zone_name
|
|
}
|
|
|
|
locals {
|
|
# Relativer Record-Name: "@" wenn Portal == Zone, sonst der Subdomain-Teil
|
|
portal_record_name = var.domain == var.dns_zone_name ? "@" : replace(var.domain, ".${var.dns_zone_name}", "")
|
|
}
|
|
|
|
# Portal-Domain → Caddy
|
|
resource "hetznerdns_record" "portal" {
|
|
count = var.manage_dns ? 1 : 0
|
|
zone_id = data.hetznerdns_zone.zone[0].id
|
|
name = local.portal_record_name
|
|
type = "A"
|
|
value = hcloud_server.caddy.ipv4_address
|
|
ttl = 300
|
|
}
|
|
|
|
# Wildcard für Firmen-Subdomains (KONZEPT §11) → Caddy (On-Demand-TLS)
|
|
resource "hetznerdns_record" "wildcard" {
|
|
count = var.manage_dns ? 1 : 0
|
|
zone_id = data.hetznerdns_zone.zone[0].id
|
|
name = "*"
|
|
type = "A"
|
|
value = hcloud_server.caddy.ipv4_address
|
|
ttl = 300
|
|
}
|