Skip to content

Setting Up DNS

This guide walks through creating a DNS zone on the b'nerd platform, adding records, and configuring external-dns for automatic record management from Kubernetes.

Time to complete: ~15 minutes
Prerequisites: An organization and a bearer token. For external-dns, a static API token is recommended.


Step 1 — Create a DNS zone

POST /dns/zones
Authorization: Bearer <token>
Content-Type: application/json

{
  "zone": {
    "name": "example.com",
    "organization_id": "<org-uuid>"
  }
}

Note the id from the response — you'll use it in subsequent calls.


Step 2 — Update your registrar's NS records

The platform assigns authoritative nameservers when a zone is created. Retrieve them:

GET /dns/zones/<zone-id>/records
Authorization: Bearer <token>

Look for the NS records in the response. Update your domain registrar to delegate to the b'nerd nameservers. DNS propagation typically takes a few minutes to a few hours depending on your registrar's TTL.


Step 3 — Add DNS records

Add an A record

POST /dns/zones/<zone-id>/records
Authorization: Bearer <token>
Content-Type: application/json

{
  "record": {
    "name": "www",
    "type": "A",
    "ttl": 300,
    "content": "203.0.113.10"
  }
}

Add a CNAME

POST /dns/zones/<zone-id>/records
Authorization: Bearer <token>
Content-Type: application/json

{
  "record": {
    "name": "blog",
    "type": "CNAME",
    "ttl": 300,
    "content": "myblog.netlify.app."
  }
}

Add MX records (email)

POST /dns/zones/<zone-id>/records
Authorization: Bearer <token>
Content-Type: application/json

{
  "record": {
    "name": "@",
    "type": "MX",
    "ttl": 3600,
    "content": "10 mail.example.com."
  }
}

Step 4 — Update a record

PATCH /dns/zones/<zone-id>/records/www/A
Authorization: Bearer <token>
Content-Type: application/json

{
  "record": {
    "content": "203.0.113.20",
    "ttl": 60
  }
}

Step 5 — Verify domain ownership (optional)

If you plan to use this domain with platform services that require verified ownership (e.g. automatic TLS), verify it:

POST /dns/domains
Authorization: Bearer <token>
Content-Type: application/json

{
  "domain": {
    "name": "example.com",
    "organization_id": "<org-uuid>"
  }
}

Add the TXT record the API provides, then trigger verification:

POST /dns/domains/<domain-id>/verify
Authorization: Bearer <token>

See Domain Verification for full details.


Configure external-dns (Kubernetes)

external-dns can manage DNS records automatically based on Kubernetes Service and Ingress annotations. The b'nerd API exposes a PowerDNS-compatible proxy that external-dns understands natively.

Create a static API token

Generate a static token with dns:read and dns:write scopes through the dashboard. Static tokens are preferred over JWT for long-running automations.

Deploy external-dns

apiVersion: apps/v1
kind: Deployment
metadata:
  name: external-dns
  namespace: external-dns
spec:
  template:
    spec:
      containers:
      - name: external-dns
        image: registry.k8s.io/external-dns/external-dns:v0.14.0
        args:
        - --provider=pdns
        - --pdns-server=https://api.bnerd.cloud/dns/external
        - --pdns-api-key=$(PDNS_API_KEY)
        - --source=ingress
        - --source=service
        - --domain-filter=example.com
        - --txt-owner-id=my-cluster
        env:
        - name: PDNS_API_KEY
          valueFrom:
            secretKeyRef:
              name: external-dns-token
              key: token

Create the secret:

kubectl create secret generic external-dns-token \
  --namespace external-dns \
  --from-literal=token=<your-static-token>

external-dns will now create and update DNS records automatically when you annotate services or ingresses with external-dns.alpha.kubernetes.io/hostname.