Skip to content

Hetzner.DNS reference

Source: src/Hetzner/ReadDns.ts

Binding that lets runtime code read Hetzner Cloud DNS RRSets.

Authenticates with the ambient HCLOUD_TOKEN (a project-scoped Cloud API token). The zone is fixed by ReadDns(zone) so calls take no zone id. Provide ReadDnsHttp on the Action / Function Effect.

Bind the client in the Action’s Init phase and provide ReadDnsHttp. Pass the Zone resource directly (it’s an Effect), or yield* Zone for a resolved value.

import * as Alchemy from "alchemy";
import * as Hetzner from "alchemy/Hetzner";
import * as Effect from "effect/Effect";
const Check = Alchemy.Action(
"Check",
Effect.gen(function* () {
const dns = yield* Hetzner.ReadDns(zone);
return Effect.fn(function* () {
const listed = yield* dns.listRecordSets({ type: ["A"] });
const rrset = yield* dns.getRecordSet("www", "A");
return { listed, rrset };
});
}).pipe(Effect.provide(Hetzner.ReadDnsHttp)),
);

Source: src/Hetzner/ReadWriteDns.ts

Binding that lets runtime code perform the full Hetzner Cloud DNS RRSet surface (read + write).

Authenticates with the ambient HCLOUD_TOKEN. The zone is fixed by ReadWriteDns(zone) so calls take no zone id. Provide ReadWriteDnsHttp on the Action / Function Effect.

Bind the client in the Action’s Init phase and provide ReadWriteDnsHttp.

import * as Alchemy from "alchemy";
import * as Hetzner from "alchemy/Hetzner";
import * as Effect from "effect/Effect";
const Seed = Alchemy.Action(
"Seed",
Effect.gen(function* () {
const dns = yield* Hetzner.ReadWriteDns(zone);
return Effect.fn(function* () {
const created = yield* dns.createRecordSet({
name: "app",
type: "A",
records: [{ value: "192.0.2.1" }],
ttl: 300,
});
yield* Hetzner.waitForZoneAction(created.action);
const rrset = yield* dns.getRecordSet("app", "A");
yield* dns.deleteRecordSet("app", "A");
return rrset.rrset.id;
});
}).pipe(Effect.provide(Hetzner.ReadWriteDnsHttp)),
);

Source: src/Hetzner/RecordSet.ts

A Hetzner Cloud DNS resource record set (RRSet) — one (name, type) with one or more records. Two A values are a single resource, not two.

Identity is (zone, name, type): changing any of those replaces the RRSet. Records, TTL, labels, and change protection update in place. Only primary Zones accept RRSet edits.

A records on a subdomain

const zone = yield* Hetzner.Zone("example", {
name: "example.com",
});
const www = yield* Hetzner.RecordSet("www", {
zone,
name: "www",
type: "A",
records: [
{ value: "192.0.2.1" },
{ value: "192.0.2.2" },
],
ttl: 300,
});

Apex A record from a Primary IP

const ip = yield* Hetzner.PrimaryIp("web-ip", {
type: "ipv4",
location: "nbg1",
});
const apex = yield* Hetzner.RecordSet("apex", {
zone,
name: "@",
type: "A",
records: [{ value: ip.ip }],
});
const www = yield* Hetzner.RecordSet("www", {
zone,
name: "www",
type: "A",
records: [{ value: "192.0.2.10" }],
ttl: 600,
});

Source: src/Hetzner/WriteDns.ts

Binding that lets runtime code create, update, and delete Hetzner Cloud DNS RRSets.

Authenticates with the ambient HCLOUD_TOKEN. A read-only token is rejected on these methods as Forbidden. The zone is fixed by WriteDns(zone) so calls take no zone id. Provide WriteDnsHttp on the Action / Function Effect.

Mutating RRSet endpoints are asynchronous — they return an action that must reach success before a subsequent read is guaranteed to see the change. Poll with waitForZoneAction.

Bind the client in the Action’s Init phase and provide WriteDnsHttp.

import * as Alchemy from "alchemy";
import * as Hetzner from "alchemy/Hetzner";
import * as Effect from "effect/Effect";
const Seed = Alchemy.Action(
"Seed",
Effect.gen(function* () {
const dns = yield* Hetzner.WriteDns(zone);
return Effect.fn(function* () {
const created = yield* dns.createRecordSet({
name: "app",
type: "A",
records: [{ value: "192.0.2.1" }],
ttl: 300,
});
yield* Hetzner.waitForZoneAction(created.action);
yield* dns.setRecordSetRecords("app", "A", {
records: [{ value: "192.0.2.2" }],
});
yield* dns.deleteRecordSet("app", "A");
return created.rrset.id;
});
}).pipe(Effect.provide(Hetzner.WriteDnsHttp)),
);

Source: src/Hetzner/Zone.ts

A Hetzner Cloud DNS zone — an apex domain hosted on Hetzner’s authoritative nameservers.

The zone name is the identity: changing it replaces the zone. Default TTL, labels, and delete protection update in place. Resource record sets are a separate resource (RecordSet).

Primary zone with a default TTL

const zone = yield* Hetzner.Zone("example", {
name: "example.com",
ttl: 3600,
});

Zone with labels and delete protection

const zone = yield* Hetzner.Zone("example", {
name: "example.com",
labels: { env: "prod" },
deleteProtection: true,
});