# CRD Source CRD source provides a generic mechanism to manage DNS records in your favorite DNS provider supported by external-dns. ## Details CRD source watches for a user specified CRD to extract [Endpoints](https://github.com/kubernetes-sigs/external-dns/blob/HEAD/endpoint/endpoint.go) from its `Spec`. So users need to create such a CRD and register it to the kubernetes cluster and then create new object(s) of the CRD specifying the Endpoints. ## Registering CRD Here is typical example of [CRD API type](https://github.com/kubernetes-sigs/external-dns/blob/HEAD/endpoint/endpoint.go) which provides Endpoints to `CRD source`: ```go type TTL int64 type Targets []string type ProviderSpecificProperty struct { Name string `json:"name,omitempty"` Value string `json:"value,omitempty"` } type ProviderSpecific []ProviderSpecificProperty type Labels map[string]string type Endpoint struct { // The hostname of the DNS record DNSName string `json:"dnsName,omitempty"` // The targets the DNS record points to Targets Targets `json:"targets,omitempty"` // RecordType type of record, e.g. CNAME, A, SRV, TXT etc RecordType string `json:"recordType,omitempty"` // TTL for the record RecordTTL TTL `json:"recordTTL,omitempty"` // Labels stores labels defined for the Endpoint // +optional Labels Labels `json:"labels,omitempty"` // ProviderSpecific stores provider specific config // +optional ProviderSpecific ProviderSpecific `json:"providerSpecific,omitempty"` } type DNSEndpointSpec struct { Endpoints []*Endpoint `json:"endpoints,omitempty"` } type DNSEndpointStatus struct { // The generation observed by the external-dns controller. // +optional ObservedGeneration int64 `json:"observedGeneration,omitempty"` } // +genclient // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object // DNSEndpoint is the CRD wrapper for Endpoint // +k8s:openapi-gen=true // +kubebuilder:resource:path=dnsendpoints // +kubebuilder:subresource:status type DNSEndpoint struct { metav1.TypeMeta `json:",inline"` metav1.ObjectMeta `json:"metadata,omitempty"` Spec DNSEndpointSpec `json:"spec,omitempty"` Status DNSEndpointStatus `json:"status,omitempty"` } ``` Refer to [kubebuilder](https://github.com/kubernetes-sigs/kubebuilder) to create and register the CRD. ## Usage One can use CRD source by specifying `--source` flag with `crd` and specifying the ApiVersion and Kind of the CRD with `--crd-source-apiversion` and `crd-source-kind` respectively. for e.g: ```sh build/external-dns --source crd --crd-source-apiversion externaldns.k8s.io/v1alpha1 --crd-source-kind DNSEndpoint --provider inmemory --once --dry-run ``` ## Creating DNS Records Create the objects of CRD type by filling in the fields of CRD and DNS record would be created accordingly. ### Example Here is an example [CRD manifest](https://github.com/kubernetes-sigs/external-dns/blob/HEAD/charts/external-dns/crds/dnsendpoints.externaldns.k8s.io.yaml) generated by kubebuilder. Apply this to register the CRD ```sh $ kubectl apply --server-side=true -f "https://raw.githubusercontent.com/kubernetes-sigs/external-dns/master/config/crd/standard/dnsendpoints.externaldns.k8s.io.yaml" customresourcedefinition.apiextensions.k8s.io "dnsendpoints.externaldns.k8s.io" created ``` Then you can create the dns-endpoint yaml similar to [dnsendpoint-example](crd/dnsendpoint-example.yaml) ```sh $ kubectl apply -f docs/sources/crd/dnsendpoint-example.yaml dnsendpoint.externaldns.k8s.io "examplednsrecord" created ``` Run external-dns in dry-mode to see whether external-dns picks up the DNS record from CRD. ```sh $ build/external-dns --source crd --crd-source-apiversion externaldns.k8s.io/v1alpha1 --crd-source-kind DNSEndpoint --provider inmemory --once --dry-run INFO[0000] running in dry-run mode. No changes to DNS records will be made. INFO[0000] Connected to cluster at https://192.168.99.100:8443 INFO[0000] CREATE: foo.bar.com 180 IN A 192.168.99.216 INFO[0000] CREATE: foo.bar.com 0 IN TXT "heritage=external-dns,external-dns/owner=default" ``` ### Using CRD source to manage DNS records in different DNS providers [CRD source](https://github.com/kubernetes-sigs/external-dns/blob/master/docs/sources/crd.md) provides a generic mechanism and declarative way to manage DNS records in different DNS providers using external-dns. **Not all the record types are enabled by default so the required record types must be enabled by using `--managed-record-types`.** ```bash external-dns --source=crd \ --domain-filter=example.com \ --managed-record-types=A \ --managed-record-types=CNAME \ --managed-record-types=NS ``` * Example for record type `A` ```yaml apiVersion: externaldns.k8s.io/v1alpha1 kind: DNSEndpoint metadata: name: examplearecord spec: endpoints: - dnsName: example.com recordTTL: 60 recordType: A targets: - 10.0.0.1 ``` * Example for record type `CNAME` ```yaml apiVersion: externaldns.k8s.io/v1alpha1 kind: DNSEndpoint metadata: name: examplecnamerecord spec: endpoints: - dnsName: test-a.example.com recordTTL: 300 recordType: CNAME targets: - example.com ``` * Example for record type `NS` ```yaml apiVersion: externaldns.k8s.io/v1alpha1 kind: DNSEndpoint metadata: name: ns-record spec: endpoints: - dnsName: zone.example.com recordTTL: 300 recordType: NS targets: - ns1.example.com - ns2.example.com ``` ## RBAC configuration If you use RBAC, extend the `external-dns` ClusterRole with: ```yaml - apiGroups: ["externaldns.k8s.io"] resources: ["dnsendpoints"] verbs: ["get","watch","list"] - apiGroups: ["externaldns.k8s.io"] resources: ["dnsendpoints/status"] verbs: ["*"] ```