[infra] Auto-create Cloudflare DNS records from ingress_factory
## Context
Deploying new services required manually adding hostnames to
cloudflare_proxied_names/cloudflare_non_proxied_names in config.tfvars —
a separate file from the service stack. This was frequently forgotten,
leaving services unreachable externally.
## This change:
- Add `dns_type` parameter to `ingress_factory` and `reverse_proxy/factory`
modules. Setting `dns_type = "proxied"` or `"non-proxied"` auto-creates
the Cloudflare DNS record (CNAME to tunnel or A/AAAA to public IP).
- Simplify cloudflared tunnel from 100 per-hostname rules to wildcard
`*.viktorbarzin.me → Traefik`. Traefik still handles host-based routing.
- Add global Cloudflare provider via terragrunt.hcl (separate
cloudflare_provider.tf with Vault-sourced API key).
- Migrate 118 hostnames from centralized config.tfvars to per-service
dns_type. 17 hostnames remain centrally managed (Helm ingresses,
special cases).
- Update docs, AGENTS.md, CLAUDE.md, dns.md runbook.
```
BEFORE AFTER
config.tfvars (manual list) stacks/<svc>/main.tf
| module "ingress" {
v dns_type = "proxied"
stacks/cloudflared/ }
for_each = list |
cloudflare_record auto-creates
tunnel per-hostname cloudflare_record + annotation
```
## What is NOT in this change:
- Uptime Kuma monitor migration (still reads from config.tfvars)
- 17 remaining centrally-managed hostnames (Helm, special cases)
- Removal of allow_overwrite (keep until migration confirmed stable)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
95d2a6abf8
commit
b1d152be1f
94 changed files with 471 additions and 34 deletions
|
|
@ -277,15 +277,31 @@ viktorbarzin.lan:53 {
|
|||
|
||||
## Cloudflare DNS — External Domains
|
||||
|
||||
All public domains are under the `viktorbarzin.me` zone, managed via Terraform in `stacks/cloudflared/modules/cloudflared/cloudflare.tf`.
|
||||
All public domains are under the `viktorbarzin.me` zone. DNS records are **auto-created per service** via the `ingress_factory` module's `dns_type` parameter. A small number of records (Helm-managed ingresses, special cases) remain centrally managed in `config.tfvars`.
|
||||
|
||||
### How DNS Records Are Created
|
||||
|
||||
```
|
||||
stacks/<service>/main.tf
|
||||
module "ingress" {
|
||||
source = ingress_factory
|
||||
dns_type = "proxied" # ← auto-creates Cloudflare DNS record
|
||||
}
|
||||
```
|
||||
|
||||
- **`dns_type = "proxied"`**: Creates CNAME → `{tunnel_id}.cfargotunnel.com` (Cloudflare CDN)
|
||||
- **`dns_type = "non-proxied"`**: Creates A → public IP + AAAA → IPv6
|
||||
- **`dns_type = "none"`** (default): No DNS record
|
||||
|
||||
The Cloudflare tunnel uses a **wildcard rule** (`*.viktorbarzin.me → Traefik`) — no per-hostname tunnel config needed. Traefik handles host-based routing via K8s Ingress resources.
|
||||
|
||||
### Record Types
|
||||
|
||||
| Type | Records | Target | Example |
|
||||
|------|---------|--------|---------|
|
||||
| Proxied CNAME | ~30 domains | `{tunnel_id}.cfargotunnel.com` | blog, hackmd, homepage, ntfy |
|
||||
| Non-proxied A | ~20 domains | `176.12.22.76` (public IP) | mail, headscale, immich, vaultwarden |
|
||||
| Non-proxied AAAA | ~20 domains | IPv6 (HE tunnel) | Same as non-proxied A |
|
||||
| Proxied CNAME | ~100 domains | `{tunnel_id}.cfargotunnel.com` | blog, hackmd, homepage, ntfy |
|
||||
| Non-proxied A | ~35 domains | `176.12.22.76` (public IP) | mail, headscale, immich |
|
||||
| Non-proxied AAAA | ~35 domains | IPv6 (HE tunnel) | Same as non-proxied A |
|
||||
| MX | 1 | `mail.viktorbarzin.me` | Inbound email |
|
||||
| TXT (SPF) | 1 | `v=spf1 include:mailgun.org -all` | Email authentication |
|
||||
| TXT (DKIM) | 4 | RSA keys (s1, mail, brevo1, brevo2) | Email signing |
|
||||
|
|
@ -393,9 +409,9 @@ For internal `.viktorbarzin.lan` records:
|
|||
3. Or add directly in Technitium web UI (`technitium.viktorbarzin.me`)
|
||||
|
||||
For external `.viktorbarzin.me` records:
|
||||
1. Add to `cloudflare_proxied_names` or `cloudflare_non_proxied_names` in `config.tfvars`
|
||||
2. Run `scripts/tg apply -target=module.kubernetes_cluster.module.cloudflared`
|
||||
3. For non-standard records (MX, TXT), add a `cloudflare_record` resource in `cloudflare.tf`
|
||||
1. Add `dns_type = "proxied"` (or `"non-proxied"`) to the `ingress_factory` module call in the service stack
|
||||
2. Run `scripts/tg apply` on the service stack — DNS record is auto-created
|
||||
3. For non-standard records (MX, TXT), add a `cloudflare_record` resource in `stacks/cloudflared/modules/cloudflared/cloudflare.tf`
|
||||
|
||||
## Incident History
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue