add ingress-dns-sync CronJob to auto-create Technitium CNAME records
Discovers all *.viktorbarzin.me ingress hosts every 15 minutes and creates matching CNAME records in Technitium if missing. Prevents the desync where Cloudflare has the DNS record (via ingress_factory) but internal DNS returns NXDOMAIN because Technitium was never updated. Includes ServiceAccount + ClusterRole for ingress list permissions.
This commit is contained in:
parent
58cced5dab
commit
5ac8d625b9
1 changed files with 117 additions and 0 deletions
|
|
@ -799,3 +799,120 @@ sys.exit(0 if correct else 1)
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
# ServiceAccount + RBAC for the ingress-dns-sync CronJob to list ingresses cluster-wide.
|
||||
resource "kubernetes_service_account" "ingress_dns_sync" {
|
||||
metadata {
|
||||
name = "ingress-dns-sync"
|
||||
namespace = kubernetes_namespace.technitium.metadata[0].name
|
||||
}
|
||||
}
|
||||
|
||||
resource "kubernetes_cluster_role" "ingress_dns_sync" {
|
||||
metadata {
|
||||
name = "ingress-dns-sync"
|
||||
}
|
||||
rule {
|
||||
api_groups = ["networking.k8s.io"]
|
||||
resources = ["ingresses"]
|
||||
verbs = ["list"]
|
||||
}
|
||||
}
|
||||
|
||||
resource "kubernetes_cluster_role_binding" "ingress_dns_sync" {
|
||||
metadata {
|
||||
name = "ingress-dns-sync"
|
||||
}
|
||||
role_ref {
|
||||
api_group = "rbac.authorization.k8s.io"
|
||||
kind = "ClusterRole"
|
||||
name = kubernetes_cluster_role.ingress_dns_sync.metadata[0].name
|
||||
}
|
||||
subject {
|
||||
kind = "ServiceAccount"
|
||||
name = kubernetes_service_account.ingress_dns_sync.metadata[0].name
|
||||
namespace = kubernetes_namespace.technitium.metadata[0].name
|
||||
}
|
||||
}
|
||||
|
||||
# CronJob to sync K8s Ingress hosts -> Technitium CNAME records.
|
||||
# Discovers all *.viktorbarzin.me ingress hosts, ensures each has a CNAME
|
||||
# pointing to viktorbarzin.me in Technitium's authoritative zone.
|
||||
# Prevents the desync where Cloudflare has the record but internal DNS doesn't.
|
||||
resource "kubernetes_cron_job_v1" "technitium_ingress_dns_sync" {
|
||||
metadata {
|
||||
name = "technitium-ingress-dns-sync"
|
||||
namespace = kubernetes_namespace.technitium.metadata[0].name
|
||||
}
|
||||
spec {
|
||||
schedule = "*/15 * * * *"
|
||||
successful_jobs_history_limit = 1
|
||||
failed_jobs_history_limit = 3
|
||||
job_template {
|
||||
metadata {}
|
||||
spec {
|
||||
template {
|
||||
metadata {}
|
||||
spec {
|
||||
service_account_name = kubernetes_service_account.ingress_dns_sync.metadata[0].name
|
||||
container {
|
||||
name = "sync"
|
||||
image = "bitnami/kubectl:latest"
|
||||
resources {
|
||||
requests = {
|
||||
cpu = "10m"
|
||||
memory = "32Mi"
|
||||
}
|
||||
limits = {
|
||||
memory = "64Mi"
|
||||
}
|
||||
}
|
||||
env {
|
||||
name = "TECH_USER"
|
||||
value = var.technitium_username
|
||||
}
|
||||
env {
|
||||
name = "TECH_PASS"
|
||||
value = var.technitium_password
|
||||
}
|
||||
command = ["/bin/sh", "-c", <<-EOT
|
||||
set -e
|
||||
ZONE="viktorbarzin.me"
|
||||
TECH_API="http://technitium-web:5380"
|
||||
|
||||
TOKEN=$$(curl -sf "$$TECH_API/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
|
||||
|
||||
EXISTING=$$(curl -sf "$$TECH_API/api/zones/records/get?token=$$TOKEN&zone=$$ZONE&domain=$$ZONE&listZone=true" | grep -o '"name":"[^"]*\.viktorbarzin\.me"' | sed 's/"name":"//;s/"//' | sort -u)
|
||||
|
||||
HOSTS=$$(kubectl get ingress -A -o jsonpath='{range .items[*]}{range .spec.rules[*]}{.host}{"\n"}{end}{end}' | grep "\.$$ZONE$$" | grep -v "^$$ZONE$$" | sort -u)
|
||||
|
||||
CREATED=0
|
||||
for HOST in $$HOSTS; do
|
||||
if echo "$$EXISTING" | grep -qx "$$HOST"; then
|
||||
continue
|
||||
fi
|
||||
RESULT=$$(curl -sf "$$TECH_API/api/zones/records/add?token=$$TOKEN&zone=$$ZONE&domain=$$HOST&type=CNAME&cname=$$ZONE&ttl=86400" 2>&1) || true
|
||||
if echo "$$RESULT" | grep -q '"status":"ok"'; then
|
||||
echo "Created CNAME: $$HOST -> $$ZONE"
|
||||
CREATED=$$((CREATED + 1))
|
||||
elif echo "$$RESULT" | grep -q 'already exists'; then
|
||||
echo "Already exists: $$HOST"
|
||||
else
|
||||
echo "Failed: $$HOST -- $$RESULT"
|
||||
fi
|
||||
done
|
||||
echo "Sync complete. Created $$CREATED new records."
|
||||
EOT
|
||||
]
|
||||
}
|
||||
restart_policy = "OnFailure"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
lifecycle {
|
||||
ignore_changes = [spec[0].job_template[0].spec[0].template[0].spec[0].dns_config] # KYVERNO_LIFECYCLE_V1
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue