From 405a4bc30678d1c00c2d23e037029ddf2cf88652 Mon Sep 17 00:00:00 2001 From: Paul Payne Date: Mon, 5 May 2025 09:43:28 -0700 Subject: [PATCH] Add ExternalDNS configuration and setup script for Cloudflare integration --- infrastructure_setup/externaldns/README.md | 14 ++++++ ...aldns.yaml => externaldns-cloudflare.yaml} | 44 +++---------------- .../externaldns/externaldns-rbac.yaml | 35 +++++++++++++++ infrastructure_setup/setup-externaldns.sh | 14 ++++-- 4 files changed, 67 insertions(+), 40 deletions(-) create mode 100644 infrastructure_setup/externaldns/README.md rename infrastructure_setup/externaldns/{externaldns.yaml => externaldns-cloudflare.yaml} (51%) create mode 100644 infrastructure_setup/externaldns/externaldns-rbac.yaml diff --git a/infrastructure_setup/externaldns/README.md b/infrastructure_setup/externaldns/README.md new file mode 100644 index 0000000..913edd9 --- /dev/null +++ b/infrastructure_setup/externaldns/README.md @@ -0,0 +1,14 @@ +# External DNS + +See: https://github.com/kubernetes-sigs/external-dns + +ExternalDNS allows you to keep selected zones (via --domain-filter) synchronized with Ingresses and Services of type=LoadBalancer and nodes in various DNS providers. + +Currently, we are only configured to use CloudFlare. + +Docs: https://github.com/kubernetes-sigs/external-dns/blob/master/docs/tutorials/cloudflare.md + +Any Ingress that has metatdata.annotions with +external-dns.alpha.kubernetes.io/hostname: `.${DOMAIN}` + +will have Cloudflare records created by External DNS. diff --git a/infrastructure_setup/externaldns/externaldns.yaml b/infrastructure_setup/externaldns/externaldns-cloudflare.yaml similarity index 51% rename from infrastructure_setup/externaldns/externaldns.yaml rename to infrastructure_setup/externaldns/externaldns-cloudflare.yaml index 7978f32..4cdc5fa 100644 --- a/infrastructure_setup/externaldns/externaldns.yaml +++ b/infrastructure_setup/externaldns/externaldns-cloudflare.yaml @@ -1,38 +1,5 @@ --- -apiVersion: v1 -kind: ServiceAccount -metadata: - name: external-dns - namespace: externaldns ---- -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - name: external-dns -rules: - - apiGroups: [""] - resources: ["services", "endpoints", "pods"] - verbs: ["get", "watch", "list"] - - apiGroups: ["extensions", "networking.k8s.io"] - resources: ["ingresses"] - verbs: ["get", "watch", "list"] - - apiGroups: [""] - resources: ["nodes"] - verbs: ["list"] ---- -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRoleBinding -metadata: - name: external-dns-viewer -roleRef: - apiGroup: rbac.authorization.k8s.io - kind: ClusterRole - name: external-dns -subjects: - - kind: ServiceAccount - name: external-dns - namespace: externaldns ---- +# CloudFlare provider for ExternalDNS apiVersion: apps/v1 kind: Deployment metadata: @@ -56,14 +23,17 @@ spec: args: - --source=service - --source=ingress - - --provider=cloudflare - --txt-owner-id=${OWNER_ID} - - --log-level=debug + - --provider=cloudflare + - --domain-filter=${DOMAIN} + #- --exclude-domains=internal.${DOMAIN} + - --cloudflare-dns-records-per-page=5000 - --publish-internal-services - --no-cloudflare-proxied + - --log-level=debug env: - name: CF_API_TOKEN valueFrom: secretKeyRef: name: cloudflare-api-token - key: api-token + key: api-token \ No newline at end of file diff --git a/infrastructure_setup/externaldns/externaldns-rbac.yaml b/infrastructure_setup/externaldns/externaldns-rbac.yaml new file mode 100644 index 0000000..22854eb --- /dev/null +++ b/infrastructure_setup/externaldns/externaldns-rbac.yaml @@ -0,0 +1,35 @@ +--- +# Common RBAC resources for all ExternalDNS deployments +apiVersion: v1 +kind: ServiceAccount +metadata: + name: external-dns + namespace: externaldns +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: external-dns +rules: + - apiGroups: [""] + resources: ["services", "endpoints", "pods"] + verbs: ["get", "watch", "list"] + - apiGroups: ["extensions", "networking.k8s.io"] + resources: ["ingresses"] + verbs: ["get", "watch", "list"] + - apiGroups: [""] + resources: ["nodes"] + verbs: ["list"] +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: external-dns-viewer +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: external-dns +subjects: + - kind: ServiceAccount + name: external-dns + namespace: externaldns \ No newline at end of file diff --git a/infrastructure_setup/setup-externaldns.sh b/infrastructure_setup/setup-externaldns.sh index 3ba9ade..53656ac 100755 --- a/infrastructure_setup/setup-externaldns.sh +++ b/infrastructure_setup/setup-externaldns.sh @@ -28,16 +28,24 @@ else exit 1 fi +# Apply common RBAC resources +echo "Deploying ExternalDNS RBAC resources..." +cat ${SCRIPT_DIR}/externaldns/externaldns-rbac.yaml | envsubst | kubectl apply -f - + # Apply ExternalDNS manifests with environment variables -echo "Deploying ExternalDNS..." -cat ${SCRIPT_DIR}/externaldns/externaldns.yaml | envsubst | kubectl apply -f - +echo "Deploying ExternalDNS for external DNS (Cloudflare)..." +cat ${SCRIPT_DIR}/externaldns/externaldns-cloudflare.yaml | envsubst | kubectl apply -f - # Wait for ExternalDNS to be ready -echo "Waiting for ExternalDNS to be ready..." +echo "Waiting for Cloudflare ExternalDNS to be ready..." kubectl rollout status deployment/external-dns -n externaldns --timeout=60s +# echo "Waiting for CoreDNS ExternalDNS to be ready..." +# kubectl rollout status deployment/external-dns-coredns -n externaldns --timeout=60s + echo "ExternalDNS setup complete!" echo "" echo "To verify the installation:" echo " kubectl get pods -n externaldns" echo " kubectl logs -n externaldns -l app=external-dns -f" +echo " kubectl logs -n externaldns -l app=external-dns-coredns -f"