[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
|
|
@ -312,6 +312,7 @@ resource "kubernetes_service" "technitium_dns_internal" {
|
|||
|
||||
module "ingress" {
|
||||
source = "../../../../modules/kubernetes/ingress_factory"
|
||||
dns_type = "proxied"
|
||||
namespace = kubernetes_namespace.technitium.metadata[0].name
|
||||
name = "technitium"
|
||||
tls_secret_name = var.tls_secret_name
|
||||
|
|
@ -380,7 +381,7 @@ data "kubernetes_secret" "technitium_db_creds" {
|
|||
depends_on = [kubernetes_manifest.external_secret]
|
||||
}
|
||||
|
||||
# Grafana datasource for Technitium DNS query logs in MySQL
|
||||
# Grafana datasource for Technitium DNS query logs in PostgreSQL
|
||||
resource "kubernetes_config_map" "grafana_technitium_datasource" {
|
||||
metadata {
|
||||
name = "grafana-technitium-datasource"
|
||||
|
|
@ -393,13 +394,18 @@ resource "kubernetes_config_map" "grafana_technitium_datasource" {
|
|||
"technitium-datasource.yaml" = yamlencode({
|
||||
apiVersion = 1
|
||||
datasources = [{
|
||||
name = "Technitium MySQL"
|
||||
type = "mysql"
|
||||
name = "Technitium PostgreSQL"
|
||||
type = "postgres"
|
||||
access = "proxy"
|
||||
url = "${var.mysql_host}:3306"
|
||||
url = "${var.postgresql_host}:5432"
|
||||
database = "technitium"
|
||||
user = "technitium"
|
||||
uid = "technitium-mysql"
|
||||
uid = "technitium-pg"
|
||||
jsonData = {
|
||||
sslmode = "disable"
|
||||
postgresVersion = 1600
|
||||
timescaledb = false
|
||||
}
|
||||
secureJsonData = {
|
||||
password = data.kubernetes_secret.technitium_db_creds.data["db_password"]
|
||||
}
|
||||
|
|
@ -475,6 +481,11 @@ resource "kubernetes_cron_job_v1" "technitium_password_sync" {
|
|||
TOKEN=$$(curl -sf "http://technitium-web:5380/api/user/login?user=$$TECH_USER&pass=$$TECH_PASS" | grep -o '"token":"[^"]*"' | cut -d'"' -f4)
|
||||
if [ -z "$$TOKEN" ]; then echo "Login failed"; exit 1; fi
|
||||
|
||||
# Disable SQLite query logging (eliminates ~18 GB/day write amplification on encrypted PVC)
|
||||
SQLITE_CONFIG="{\"enableLogging\":false,\"maxLogDays\":0,\"maxLogRecords\":0}"
|
||||
curl -sf -X POST "http://technitium-web:5380/api/apps/config/set?token=$$TOKEN" --data-urlencode "name=Query Logs (Sqlite)" --data-urlencode "config=$$SQLITE_CONFIG"
|
||||
echo "SQLite logging disabled on primary"
|
||||
|
||||
# Disable MySQL query logging
|
||||
MYSQL_CONFIG="{\"enableLogging\":false,\"maxQueueSize\":1000000,\"maxLogDays\":30,\"maxLogRecords\":0,\"databaseName\":\"technitium\",\"connectionString\":\"Server=mysql.dbaas.svc.cluster.local; Port=3306; Uid=technitium; Pwd=$$DB_PASSWORD;\"}"
|
||||
curl -sf -X POST "http://technitium-web:5380/api/apps/config/set?token=$$TOKEN" --data-urlencode "name=Query Logs (MySQL)" --data-urlencode "config=$$MYSQL_CONFIG"
|
||||
|
|
@ -489,7 +500,17 @@ resource "kubernetes_cron_job_v1" "technitium_password_sync" {
|
|||
# Configure PG query logging
|
||||
PG_CONFIG="{\"enableLogging\":true,\"maxQueueSize\":1000000,\"maxLogDays\":90,\"maxLogRecords\":0,\"databaseName\":\"technitium\",\"connectionString\":\"Host=${var.postgresql_host}; Port=5432; Username=technitium; Password=$$DB_PASSWORD;\"}"
|
||||
curl -sf -X POST "http://technitium-web:5380/api/apps/config/set?token=$$TOKEN" --data-urlencode "name=Query Logs (Postgres)" --data-urlencode "config=$$PG_CONFIG"
|
||||
echo "PG logging configured"
|
||||
echo "PG logging configured on primary"
|
||||
|
||||
# Disable SQLite on secondary and tertiary instances
|
||||
for INST in http://technitium-secondary-web:5380 http://technitium-tertiary-web:5380; do
|
||||
echo "Configuring $$INST"
|
||||
R_TOKEN=$$(curl -sf "$$INST/api/user/login?user=$$TECH_USER&pass=$$TECH_PASS" | grep -o '"token":"[^"]*"' | cut -d'"' -f4)
|
||||
if [ -z "$$R_TOKEN" ]; then echo "Login failed for $$INST, skipping"; continue; fi
|
||||
curl -sf -X POST "$$INST/api/apps/config/set?token=$$R_TOKEN" --data-urlencode "name=Query Logs (Sqlite)" --data-urlencode "config=$$SQLITE_CONFIG" || echo "WARN: SQLite plugin not present on $$INST"
|
||||
echo "SQLite logging disabled on $$INST"
|
||||
done
|
||||
echo "Password sync complete"
|
||||
EOT
|
||||
]
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue