Episode ini membahas REST API PowerDNS: mengaktifkan webserver dengan API key, mengelola zone, records, TSIG, dan crypto keys lewat /api/v1/servers/localhost/zones, provisioning dengan curl dan Python, serta integrasi Terraform provider dan ExternalDNS di Kubernetes.

Semua kemampuan yang sudah kalian bangun — zone, transfer, DNSSEC, dynamic update — bisa diotomatiskan penuh lewat REST API PowerDNS. Inilah yang membuat database-driven DNS begitu berharga: infrastruktur DNS dikelola sebagai kode, bukan lewat panel.
Episode 20 membuka API PowerDNS: mengaktifkannya, operasi dasar dengan curl, scripting Python, lalu integrasi dengan Terraform dan ExternalDNS di Kubernetes. Setelah episode ini, kalian bisa menghapus zona secara otomatis, membuat record dalam hitungan detik, dan mengelola DNS sebagai bagian dari pipeline CI/CD.
API hidup di webserver Authoritative. Aktifkan di pdns.conf:
api=yes
api-key=sekret-api-key-panjang
webserver=yes
webserver-address=127.0.0.1
webserver-port=8081api=yes mengaktifkan endpoint REST; api-key menjadi otentikasi setiap panggilan. webserver-address=127.0.0.1 menjaga API hanya bisa diakses dari mesin itu sendiri — proxikan lewat reverse proxy bila perlu.
Semua operasi berjalan di atas base path /api/v1/servers/localhost:
curl -s -H 'X-API-Key: sekret-api-key-panjang' \
http://127.0.0.1:8081/api/v1/servers
curl -s -H 'X-API-Key: sekret-api-key-panjang' \
http://127.0.0.1:8081/api/v1/servers/localhost/zonescurl -H 'X-API-Key: ...' adalah pola semua permintaan API. Respon JSON berisi daftar server untuk panggilan pertama, dan seluruh zone untuk panggilan kedua.
Zone dibuat dengan POST berformat JSON:
curl -s -X POST -H 'X-API-Key: sekret-api-key-panjang' \
-H 'Content-Type: application/json' \
http://127.0.0.1:8081/api/v1/servers/localhost/zones \
-d '{"name":"api-demo.example.com","kind":"Primary","masters":[],"nameservers":["ns1.example.com."]}'Perhatikan format nama zone diakhiri titik. kind menentukan tipe zone: Primary, Secondary, atau Native. Respon membalas dengan representasi zone lengkap yang baru saja dibuat.
Tambah record dengan PATCH pada endpoint zone:
curl -s -X PATCH -H 'X-API-Key: sekret-api-key-panjang' \
-H 'Content-Type: application/json' \
http://127.0.0.1:8081/api/v1/servers/localhost/zones/api-demo.example.com \
-d '{"rrsets":[{"name":"app.api-demo.example.com","type":"A","ttl":300,"records":[{"content":"192.0.2.40","disabled":false}]}]}'Payload rrsets berisi RRset yang ditambah atau diganti. Pola ini dipakai untuk semua record: A, AAAA, MX, TXT, hingga record DNSSEC seperti DNSKEY.
TSIG key dan kunci DNSSEC juga dikelola via API — endpoint /zones/{zone}/metadata dan /zones/{zone}/cryptokeys:
curl -s -H 'X-API-Key: sekret-api-key-panjang' \
http://127.0.0.1:8081/api/v1/servers/localhost/zones/api-demo.example.com/cryptokeysDengan library requests, provisioning menjadi fungsi yang bisa dipanggil dari pipeline mana pun:
import requests
BASE = "http://127.0.0.1:8081/api/v1/servers/localhost"
HEADERS = {"X-API-Key": "sekret-api-key-panjang"}
def create_a_record(zone, name, ip, ttl=300):
payload = {"rrsets": [{
"name": f"{name}.{zone}",
"type": "A",
"ttl": ttl,
"records": [{"content": ip, "disabled": False}],
}]}
r = requests.patch(f"{BASE}/zones/{zone}", json=payload, headers=HEADERS)
r.raise_for_status()
create_a_record("api-demo.example.com", "web", "192.0.2.41")Fungsi create_a_record di atas menambah record A lewat satu panggilan API. Dari fungsi sederhana ini, kalian bisa membangun tooling lengkap: sync otomatis, audit, hingga self-service portal internal.
Terraform resmi memakai provider powerdns/pdns. Dengan provider ini, seluruh zone dan record dinyatakan sebagai kode:
provider "pdns" {
api_url = "http://127.0.0.1:8081"
api_key = "sekret-api-key-panjang"
}
resource "powerdns_zone" "app" {
name = "app.example.com."
type = "Primary"
nameservers = ["ns1.example.com.", "ns2.example.com."]
}
resource "powerdns_record" "www" {
zone = powerdns_zone.app.name
name = "www.app.example.com"
type = "A"
ttl = 300
records = ["192.0.2.42"]
}Dengan Terraform, terraform apply membuat zone dan record, dan terraform destroy menghapusnya — DNS menjadi bagian dari infrastruktur-as-kode yang berversi dan direview.
ExternalDNS menyinkronkan Service dan Ingress Kubernetes ke DNS secara otomatis:
kind: Deployment
metadata:
name: external-dns
spec:
template:
spec:
containers:
- name: external-dns
image: registry.k8s.io/external-dns/external-dns:v0.15.1
args:
- --source=service
- --source=ingress
- --provider=powerdns
- --pdns-server=http://pdns-api:8081
- --pdns-api-key=sekret-api-key-panjang
- --domain-filter=app.example.comSetiap Service ber-annotation di-kluster langsung terdaftar di DNS PowerDNS tanpa campur tangan manusia — contoh sempurna autoprovisioning yang menjadi alasan utama PowerDNS didesain database-driven.
Episode 20 mengubah kalian menjadi operator DNS yang terotomasi penuh: mengaktifkan REST API, melakukan operasi zone dan record dengan curl, memprovisioning lewat Python, dan menyatakan seluruh DNS sebagai kode dengan Terraform dan ExternalDNS.
Inti yang harus dibawa pulang:
api=yes dan diotentikasi dengan api-key./api/v1/servers/localhost.rrsets.powerdns/pdns menjadikan DNS sebagai kode.Di episode 21 selanjutnya kita akan membahas production-ready stack dan deployment — merakit arsitektur lengkap klien menuju dnsdist, recursor, dan authoritative via database backend, deployment dengan Docker dan Kubernetes, manajemen sertifikat TLS dengan ACME, serta upgrade mengikuti kebijakan EOL PowerDNS.