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:
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:
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.
Using the dashboard¶
The dashboard at app.bnerd.cloud covers the full DNS workflow:
- Create a zone: Services → DNS → New Zone
- Add and edit records: Zone detail → Records tab
- Verify domain ownership: Zone detail → Verification tab
Using the CLI¶
# List DNS zones
bnerd dns zones list
# Create a zone
bnerd dns zones create example.com
# List records in a zone
bnerd dns records list --zone-id <zone-id>
# Add an A record
bnerd dns records create --zone-id <zone-id> --name www --type A --ttl 300 --content 203.0.113.10
# Delete a zone (removes all records)
bnerd dns zones delete <zone-id>
See cli.docs.bnerd.com for the full flag reference.
Using Terraform¶
resource "bnerd_dns_zone" "primary" {
name = "example.com." # trailing dot required
kind = "Native"
nameservers = ["ns1.bnerd.net.", "ns2.bnerd.net."]
}
resource "bnerd_dns_record" "www" {
zone_id = bnerd_dns_zone.primary.id
name = "www.example.com."
type = "A"
ttl = 300
records = ["203.0.113.10"]
}
See Terraform Provider reference for all DNS resource and data source attributes.
Troubleshooting¶
| Symptom | Likely cause | Fix |
|---|---|---|
| NS records not resolving after zone creation | Registrar NS records not updated yet | Update your registrar's nameservers to the platform NS records (Step 2); wait for propagation |
| DNS propagation taking > 2 hours | High upstream TTL at the registrar | Wait for the registrar's existing TTL to expire — nothing to do on the b'nerd side |
422 on record create | Invalid record content or type | Check errors[0].message in the error envelope for the specific validation failure |
| external-dns not creating records | Wrong API key or endpoint | Verify the static token has dns:write scope; check --pdns-server is https://api.bnerd.cloud/dns/external |
| Zone shows no NS records immediately after create | Zone is still propagating | Wait 30 seconds and re-fetch |
Related pages¶
- DNS Zones
- DNS Records
- Domain Verification
- Authentication — static tokens for automation