🛈 NOTE: This Webhook was forked and modified from the IONOS Webhook to work with Hetzner. It also contains huge parts from DrBu7cher's Hetzner provider.
ExternalDNS is a Kubernetes add-on for automatically managing Domain Name System (DNS) records for Kubernetes services by using different DNS providers. By default, Kubernetes manages DNS records internally, but ExternalDNS takes this functionality a step further by delegating the management of DNS records to an external DNS provider such as this one. Therefore, the Hetzner webhook allows to manage your Hetzner domains inside your kubernetes cluster with ExternalDNS.
To use ExternalDNS with Hetzner, you need your Hetzner API token of the account managing your domains. For detailed technical instructions on how the Hetzner webhook is deployed using the Bitnami Helm charts for ExternalDNS, seedeployment instructions.
The Hetzner webhook is provided as a regular Open Container Initiative (OCI) image released in the GitHub container registry. The deployment can be performed in every way Kubernetes supports. The following example shows the deployment as a sidecar container in the ExternalDNS pod using the Bitnami Helm charts for ExternalDNS.
The webhook can be installed using either the Bitnami chart or the ExternalDNS one.
First, create the Hetzner secret:
kubectl create secret generic hetzner-credentials --from-literal=api-key='<EXAMPLE_PLEASE_REPLACE>' -n external-dns
Skip this if you already have the Bitnami repository added:
helm repo add bitnami https://charts.bitnami.com/bitnami
You can then create the helm values file, for example
external-dns-hetzner-values.yaml
:
image:
registry: registry.k8s.io
repository: external-dns/external-dns
tag: v0.14.0
provider: webhook
extraArgs:
webhook-provider-url: http://localhost:8888
txt-prefix: reg-
sidecars:
- name: hetzner-webhook
image: ghcr.io/mconfalonieri/external-dns-hetzner-webhook:v0.6.0
ports:
- containerPort: 8888
name: webhook
- containerPort: 8080
name: http
livenessProbe:
httpGet:
path: /health
port: http
initialDelaySeconds: 10
timeoutSeconds: 5
readinessProbe:
httpGet:
path: /ready
port: http
initialDelaySeconds: 10
timeoutSeconds: 5
env:
- name: HETZNER_API_KEY
valueFrom:
secretKeyRef:
name: hetzner-credentials
key: api-key
And then:
# install external-dns with helm
helm install external-dns-hetzner bitnami/external-dns -f external-dns-hetzner-values.yaml -n external-dns
Skip this if you already have the ExternalDNS repository added:
helm repo add external-dns https://kubernetes-sigs.github.io/external-dns/
You can then create the helm values file, for example
external-dns-hetzner-values.yaml
:
namespace: external-dns
policy: sync
provider:
name: webhook
webhook:
image:
repository: ghcr.io/mconfalonieri/external-dns-hetzner-webhook
tag: v0.6.0
env:
- name: HETZNER_API_KEY
valueFrom:
secretKeyRef:
name: hetzner-credentials
key: api-key
livenessProbe:
httpGet:
path: /health
port: http-wh-metrics
initialDelaySeconds: 10
timeoutSeconds: 5
readinessProbe:
httpGet:
path: /ready
port: http-wh-metrics
initialDelaySeconds: 10
timeoutSeconds: 5
extraArgs:
- --txt-prefix=reg-
And then:
# install external-dns with helm
helm install external-dns-hetzner external-dns/external-dns -f external-dns-hetzner-values.yaml --version 1.14.3 -n external-dns
The following environment variables are available:
Variable | Description | Notes |
---|---|---|
HETZNER_API_KEY | Hetzner API token | Mandatory |
DRY_RUN | If set, changes won't be applied | Default: false |
HETZNER_DEBUG | Enables debugging messages | Default: false |
BATCH_SIZE | Number of zones per call | Default: 100 , max: 100 |
DEFAULT_TTL | Default TTL if not specified | Default: 7200 |
WEBHOOK_HOST | Webhook hostname or IP address | Default: localhost |
WEBHOOK_PORT | Webhook port | Default: 8888 |
HEALTH_HOST | Liveness and readiness hostname | Default: 0.0.0.0 |
HEALTH_PORT | Liveness and readiness port | Default: 8080 |
READ_TIMEOUT | Servers' read timeout in ms | Default: 60000 |
WRITE_TIMEOUT | Servers' write timeout in ms | Default: 60000 |
Additional environment variables for domain filtering:
Environment variable | Description |
---|---|
DOMAIN_FILTER | Filtered domains |
EXCLUDE_DOMAIN_FILTER | Excluded domains |
REGEXP_DOMAIN_FILTER | Regex for filtered domains |
REGEXP_DOMAIN_FILTER_EXCLUSION | Regex for excluded domains |
If the REGEXP_DOMAIN_FILTER
is set, the following variables will be used to
build the filter:
- REGEXP_DOMAIN_FILTER
- REGEXP_DOMAIN_FILTER_EXCLUSION
otherwise, the filter will be built using:
- DOMAIN_FILTER
- EXCLUDE_DOMAIN_FILTER
While tweaking the configuration, there are some points to take into consideration:
-
if
WEBHOOK_HOST
andHEALTH_HOST
are set to the same address/hostname or one of them is set to0.0.0.0
remember to use different ports. -
if your records don't get deleted when applications are uninstalled, you might want to verify the policy in use for ExternalDNS: if it's
upsert-only
no deletion will occur. It must be set tosync
for deletions to be processed. Please add the following toexternal-dns-hetzner-values.yaml
if you want this strategy:policy: sync
The basic development tasks are provided by make. Run make help
to see the
available targets.