CloudflareDNSRecord Crossplane Template
Real DNS record management for Cloudflare using External-DNS.
Overview​
This template provides real DNS record creation in Cloudflare via External-DNS, enabling namespaced DNS management without requiring cluster-scoped resources.
Migration from Provider-Based Approach​
Previous: Used Crossplane's provider-cloudflare which required cluster-scoped resources Current: Uses External-DNS with DNSEndpoint CRDs for namespace-isolated DNS management
Prerequisites​
- External-DNS installed and configured
- Cloudflare API Token configured in External-DNS
- dns-config EnvironmentConfig (provides zone name)
Installation​
1. Ensure External-DNS is Running​
# Check External-DNS status
kubectl get deployment -n external-dns external-dns
# Verify DNSEndpoint CRD exists
kubectl get crd dnsendpoints.externaldns.openportal.dev
2. Configure DNS Zone​
# Edit dns-config EnvironmentConfig with your zone
kubectl edit environmentconfig dns-config
# Set the zone field (e.g., "openportal.dev")
3. Install Template​
kubectl apply -k .
Usage​
Create A Record​
apiVersion: openportal.dev/v1alpha1
kind: CloudflareDNSRecord
metadata:
name: myapp-dns
namespace: my-team
spec:
type: A
name: myapp
value: "50.56.157.82"
proxied: true
comment: "My application DNS"
Create CNAME​
apiVersion: openportal.dev/v1alpha1
kind: CloudflareDNSRecord
metadata:
name: www-dns
namespace: my-team
spec:
type: CNAME
name: www
value: "openportal.dev"
Create MX Record​
apiVersion: openportal.dev/v1alpha1
kind: CloudflareDNSRecord
metadata:
name: mail-dns
namespace: my-team
spec:
type: MX
name: "@"
value: "mail.openportal.dev"
priority: 10
How It Works​
- You create a CloudflareDNSRecord XR in your namespace
- Crossplane Composition transforms it into a DNSEndpoint resource
- External-DNS watches DNSEndpoint resources and syncs them to Cloudflare
- Cloudflare creates/updates the actual DNS records
Configuration​
The template requires:
- dns-config EnvironmentConfig with
zonefield - External-DNS with Cloudflare credentials configured
Features​
- ✅ Real DNS record creation in Cloudflare
- ✅ Support for A, AAAA, CNAME, TXT, MX records
- ✅ Cloudflare proxy (orange cloud) support
- ✅ TTL management
- ✅ Comment support for record documentation
- ✅ Namespace isolation - teams manage their own DNS records
- ✅ No cluster-scoped resources required
Restaurant Analogy​
- Menu (XRD): CloudflareDNSRecord - what DNS records can be ordered
- Recipe (Composition): How to create DNSEndpoint resources
- Waiter (External-DNS): Takes DNSEndpoint orders to Cloudflare
- Order (XR): Your DNS record request
- Kitchen (Cloudflare): Where the actual DNS records are created
Architecture Benefits​
Previous (Provider-Based)​
- Required cluster-scoped Cloudflare provider
- Namespaced XRs couldn't create cluster-scoped resources
- Limited multi-tenancy support
Current (External-DNS)​
- Namespaced DNSEndpoint resources
- External-DNS handles provider interaction
- Full namespace isolation for teams
- Better security and multi-tenancy
Troubleshooting​
DNS Record Not Created​
- Check XR status:
kubectl get cloudflarednsrecord -n your-namespace
kubectl describe cloudflarednsrecord <name> -n your-namespace
- Check DNSEndpoint:
kubectl get dnsendpoint -n your-namespace
kubectl describe dnsendpoint <name> -n your-namespace
- Check External-DNS logs:
kubectl logs -n external-dns deployment/external-dns
External-DNS Not Processing Records​
- Verify External-DNS is running:
kubectl get pods -n external-dns
- Check External-DNS configuration:
kubectl get deployment -n external-dns external-dns -o yaml | grep args -A 10
- Ensure it's watching the correct CRD:
- Should include:
--crd-source-apiversion=externaldns.openportal.dev/v1alpha1
TODO​
- Support for SRV records
- Integration with WhoAmIApp for automatic DNS
- Support for wildcard records
- DNS record validation webhook