Skip to content

Record

Source: src/Cloudflare/DNS/Record.ts

A single DNS record on a Cloudflare-managed zone.

Safety: when there is no prior state, read scans the zone for an existing (name, type) match. DNS records carry no ownership markers we can inspect, so an existing match is reported as Unowned and the engine refuses to take it over unless --adopt (or adopt(true)) is set. This protects hand-edited records (especially the apex A/AAAA and email DKIM/SPF records that the dashboard often manages) from being clobbered.

Several records may legitimately share (name, type) — MX fallbacks, multiple TXT records, round-robin A records. When the scan finds more than one candidate, the declared content (and priority) must match exactly one record; a record with no exact match is treated as missing (a new sibling record is created), and a still-ambiguous match fails with an error listing the candidates. To adopt one record out of such a set, declare its current content/priority verbatim first, then change them in a follow-up deploy.

yield* Cloudflare.DNS.Record("AdminCname", {
zoneId: zone.zoneId,
name: "cluster-admin.example.com",
type: "CNAME",
content: `${tunnel.tunnelId}.cfargotunnel.com`,
proxied: true,
comment: "research admin UI",
});
yield* Cloudflare.DNS.Record("ApiA", {
zoneId: zone.zoneId,
name: "api.example.com",
type: "A",
content: "203.0.113.42",
ttl: 300,
});

SVCB record

yield* Cloudflare.DNS.Record("McpSvcb", {
zoneId: zone.zoneId,
name: "_mcp._agents.example.com",
type: "SVCB",
content: {
priority: 1,
target: "mcp.example.com.",
value: 'mandatory="alpn,port" alpn="h2,h3" port="443"',
},
});

HTTPS record

yield* Cloudflare.DNS.Record("WebsiteHttps", {
zoneId: zone.zoneId,
name: "example.com",
type: "HTTPS",
content: {
priority: 1,
target: ".",
value: 'alpn="h2,h3"',
},
});