Skip to content

AWS.Route53 reference

Source: src/AWS/Route53/ChangeResourceRecordSets.ts

Runtime binding for the ChangeResourceRecordSets operation (IAM action route53:ChangeResourceRecordSets on the hosted zone ARN).

Creates, upserts, and deletes DNS record sets in the bound HostedZone at runtime — the core dynamic-DNS primitive (ACME dns-01 challenges, service discovery, failover flips). Pair with GetChange to wait until the change is INSYNC. Provide the implementation with Effect.provide(AWS.Route53.ChangeResourceRecordSetsHttp).

ChangeResourceRecordSets: Managing Records at Runtime

Section titled “ChangeResourceRecordSets: Managing Records at Runtime”
const changeRecordSets = yield* AWS.Route53.ChangeResourceRecordSets(zone);
const { ChangeInfo } = yield* changeRecordSets({
ChangeBatch: {
Changes: [{
Action: "UPSERT",
ResourceRecordSet: {
Name: "_acme-challenge.example.com.",
Type: "TXT",
TTL: 60,
ResourceRecords: [{ Value: '"token"' }],
},
}],
},
});

Source: src/AWS/Route53/GetChange.ts

Runtime binding for the GetChange operation (IAM action route53:GetChange on arn:aws:route53:::change/*).

Polls the status of a record change submitted via ChangeResourceRecordSetsPENDING until the change has propagated to all authoritative name servers, then INSYNC. Pass the bare change id (strip a leading /change/ from ChangeInfo.Id). Provide the implementation with Effect.provide(AWS.Route53.GetChangeHttp).

const getChange = yield* AWS.Route53.GetChange();
const status = yield* getChange({
Id: changeId.replace(/^\/change\//, ""),
}).pipe(
Effect.map((r) => r.ChangeInfo.Status),
Effect.repeat({
schedule: Schedule.fixed("2 seconds"),
until: (status) => status === "INSYNC",
times: 30,
}),
);

Source: src/AWS/Route53/GetHealthCheckLastFailureReason.ts

Runtime binding for the GetHealthCheckLastFailureReason operation (IAM action route53:GetHealthCheckLastFailureReason on the health check ARN).

Reads the reason each Route 53 checker last reported the bound HealthCheck unhealthy — the diagnostic companion to GetHealthCheckStatus for alerting and incident tooling. Endpoint checks only (not CALCULATED / RECOVERY_CONTROL). Provide the implementation with Effect.provide(AWS.Route53.GetHealthCheckLastFailureReasonHttp).

GetHealthCheckLastFailureReason: Observing Health Checks

Section titled “GetHealthCheckLastFailureReason: Observing Health Checks”
const getLastFailureReason =
yield* AWS.Route53.GetHealthCheckLastFailureReason(check);
const { HealthCheckObservations } = yield* getLastFailureReason();

Source: src/AWS/Route53/GetHealthCheckStatus.ts

Runtime binding for the GetHealthCheckStatus operation (IAM action route53:GetHealthCheckStatus on the health check ARN).

Reads the bound HealthCheck’s current status as reported by each Route 53 checker — drive dashboards or failover decisions from the same signal Route 53 routes on. Endpoint checks only (not CALCULATED / RECOVERY_CONTROL). Provide the implementation with Effect.provide(AWS.Route53.GetHealthCheckStatusHttp).

GetHealthCheckStatus: Observing Health Checks

Section titled “GetHealthCheckStatus: Observing Health Checks”
const getHealthCheckStatus = yield* AWS.Route53.GetHealthCheckStatus(check);
const { HealthCheckObservations } = yield* getHealthCheckStatus();
for (const observation of HealthCheckObservations) {
yield* Effect.log(
`${observation.Region}: ${observation.StatusReport?.Status}`,
);
}

Source: src/AWS/Route53/GetHostedZone.ts

Runtime binding for the GetHostedZone operation (IAM action route53:GetHostedZone on the hosted zone ARN).

Reads the bound HostedZone’s detail — the authoritative name servers (delegation set), record count, and associated VPCs. Useful for compute that hands out NS records or verifies delegation at runtime. Provide the implementation with Effect.provide(AWS.Route53.GetHostedZoneHttp).

const getHostedZone = yield* AWS.Route53.GetHostedZone(zone);
const { DelegationSet } = yield* getHostedZone();
yield* Effect.log(DelegationSet?.NameServers);

Source: src/AWS/Route53/HealthCheck.ts

A Route 53 health check.

HealthCheck monitors the health of an endpoint and can gate failover and other routing policies on a Record via record.healthCheckId.

const check = yield* HealthCheck("ApiHealth", {
type: "HTTP",
fullyQualifiedDomainName: "api.example.com",
resourcePath: "/health",
port: 80,
requestInterval: "30 seconds",
failureThreshold: 3,
});
const check = yield* HealthCheck("PrimaryHealth", {
type: "HTTPS",
fullyQualifiedDomainName: "primary.example.com",
resourcePath: "/health",
port: 443,
});
// Route 53 answers with the PRIMARY record only while the check passes;
// see `Record` for the matching SECONDARY record.
const primary = yield* Record("Primary", {
hostedZoneId: zone.id,
name: "app.example.com",
type: "A",
ttl: "60 seconds",
records: ["1.2.3.4"],
setIdentifier: "primary",
failover: "PRIMARY",
healthCheckId: check.id,
});

Source: src/AWS/Route53/HostedZone.ts

A Route 53 hosted zone.

HostedZone manages the lifecycle of a public or private hosted zone, including its comment and tags. For public zones, the four authoritative name servers are exposed as nameServers.

Public Hosted Zone

const zone = yield* HostedZone("MyZone", {
name: "example.com",
comment: "Primary zone",
});
// zone.nameServers -> the 4 NS records to set at your registrar

Force Destroy

const zone = yield* HostedZone("MyZone", {
name: "example.com",
forceDestroy: true, // delete leftover records on destroy
});

Source: src/AWS/Route53/ListHostedZones.ts

Runtime binding for the ListHostedZones operation (IAM action route53:ListHostedZones; list actions do not support resource-level permissions, so it is granted on *).

Pages through the account’s hosted zones — zone discovery for multi-tenant DNS automation that resolves a zone id before editing records. Provide the implementation with Effect.provide(AWS.Route53.ListHostedZonesHttp).

const listHostedZones = yield* AWS.Route53.ListHostedZones();
const { HostedZones } = yield* listHostedZones({ MaxItems: 100 });

Source: src/AWS/Route53/ListHostedZonesByName.ts

Runtime binding for the ListHostedZonesByName operation (IAM action route53:ListHostedZonesByName; list actions do not support resource-level permissions, so it is granted on *).

Looks hosted zones up by DNS name in lexicographic order — the direct way to resolve “which zone owns example.com?” at runtime. Provide the implementation with Effect.provide(AWS.Route53.ListHostedZonesByNameHttp).

const listByName = yield* AWS.Route53.ListHostedZonesByName();
const { HostedZones } = yield* listByName({
DNSName: "example.com.",
MaxItems: 1,
});

Source: src/AWS/Route53/ListHostedZonesByVPC.ts

Runtime binding for the ListHostedZonesByVPC operation (IAM actions route53:ListHostedZonesByVPC + ec2:DescribeVpcs — Route 53 verifies the VPC on the caller’s behalf; list actions do not support resource-level permissions, so both are granted on *).

Lists the private hosted zones associated with a VPC — discovery for compute that audits or wires up split-horizon DNS at runtime. Provide the implementation with Effect.provide(AWS.Route53.ListHostedZonesByVPCHttp).

const listByVpc = yield* AWS.Route53.ListHostedZonesByVPC();
const { HostedZoneSummaries } = yield* listByVpc({
VPCId: "vpc-0123456789abcdef0",
VPCRegion: "us-east-1",
});

Source: src/AWS/Route53/ListResourceRecordSets.ts

Runtime binding for the ListResourceRecordSets operation (IAM action route53:ListResourceRecordSets on the hosted zone ARN).

Pages through the bound HostedZone’s record sets — read the current DNS state before computing a change batch, or audit what a dynamic-DNS workflow has written. Provide the implementation with Effect.provide(AWS.Route53.ListResourceRecordSetsHttp).

ListResourceRecordSets: Managing Records at Runtime

Section titled “ListResourceRecordSets: Managing Records at Runtime”
const listRecordSets = yield* AWS.Route53.ListResourceRecordSets(zone);
const { ResourceRecordSets } = yield* listRecordSets({
StartRecordName: "www.example.com.",
MaxItems: 10,
});

Source: src/AWS/Route53/QueryLoggingConfig.ts

DNS query logging for a Route 53 public hosted zone.

Route 53 publishes query logs to a CloudWatch Logs log group in us-east-1. The log group needs a CloudWatch Logs resource policy (also in us-east-1) that allows the route53.amazonaws.com service principal to create log streams and put log events — model it with AWS.Logs.ResourcePolicy.

A hosted zone can have at most one query logging configuration, and the configuration is immutable — changing either property replaces it.

QueryLoggingConfig: Enabling Query Logging

Section titled “QueryLoggingConfig: Enabling Query Logging”
// Both the log group and the resource policy must live in us-east-1.
const policy = yield* Logs.ResourcePolicy("Route53QueryLogging", {
policyName: "route53-query-logging",
policyDocument: {
Version: "2012-10-17",
Statement: [
{
Effect: "Allow",
Principal: { Service: "route53.amazonaws.com" },
Action: ["logs:CreateLogStream", "logs:PutLogEvents"],
Resource: `arn:aws:logs:us-east-1:${accountId}:log-group:/aws/route53/*`,
},
],
},
});
const logging = yield* QueryLoggingConfig("ZoneQueryLogging", {
hostedZoneId: zone.id,
cloudWatchLogsLogGroupArn: logGroup.logGroupArn,
});

Source: src/AWS/Route53/Record.ts

A Route 53 DNS record set.

Record manages a single Route 53 record set using UPSERT for create and update operations, and waits for Route 53 change propagation before returning.

A Record Alias To CloudFront

const record = yield* Record("WebsiteAlias", {
hostedZoneId: "Z1234567890",
name: "www.example.com",
type: "A",
aliasTarget: {
hostedZoneId: distribution.hostedZoneId,
dnsName: distribution.domainName,
},
});

TXT Record

const record = yield* Record("VerificationRecord", {
hostedZoneId: "Z1234567890",
name: "_acme-challenge.example.com",
type: "TXT",
ttl: "60 seconds",
records: ["\"value\""],
});

Weighted Routing

const blue = yield* Record("Blue", {
hostedZoneId: zone.id,
name: "api.example.com",
type: "A",
ttl: "60 seconds",
records: ["1.2.3.4"],
setIdentifier: "blue",
weight: 90,
});
const green = yield* Record("Green", {
hostedZoneId: zone.id,
name: "api.example.com",
type: "A",
ttl: "60 seconds",
records: ["5.6.7.8"],
setIdentifier: "green",
weight: 10,
});

Failover Routing With Health Check

const primary = yield* Record("Primary", {
hostedZoneId: zone.id,
name: "app.example.com",
type: "A",
ttl: "60 seconds",
records: ["1.2.3.4"],
setIdentifier: "primary",
failover: "PRIMARY",
healthCheckId: healthCheck.id,
});
const secondary = yield* Record("Secondary", {
hostedZoneId: zone.id,
name: "app.example.com",
type: "A",
ttl: "60 seconds",
records: ["5.6.7.8"],
setIdentifier: "secondary",
failover: "SECONDARY",
});

Latency Routing

const record = yield* Record("UsEast", {
hostedZoneId: zone.id,
name: "api.example.com",
type: "A",
ttl: "60 seconds",
records: ["1.2.3.4"],
setIdentifier: "us-east-1",
region: "us-east-1",
});

Geolocation Routing

const record = yield* Record("Default", {
hostedZoneId: zone.id,
name: "www.example.com",
type: "A",
ttl: "60 seconds",
records: ["1.2.3.4"],
setIdentifier: "default",
geoLocation: { countryCode: "*" },
});

Source: src/AWS/Route53/Records.ts

A dynamic set of identically-configured Route 53 records that differ only by name.

Unlike Record (one resource per record), Records reconciles a whole name set against the hosted zone — names added to the set are upserted, names removed from the set are deleted. The set is the union of the declared names prop and names contributed through the RecordsBinding binding contract, which is how composites (e.g. a site attached to an AWS.Website.Router) register hostnames on a distribution’s DNS without a circular input prop.

Alias Records For Several Hostnames

const records = yield* Records("AliasRecords", {
hostedZoneId: "Z1234567890",
type: "A",
names: ["www.example.com", "docs.example.com"],
aliasTarget: {
hostedZoneId: distribution.hostedZoneId,
dnsName: distribution.domainName,
},
});

Binding Target For Composite-Contributed Names

// Names may also arrive through the binding contract — an
// `AWS.Website.Router` declares an empty set and attached sites bind
// their hostnames onto it:
const records = yield* Records("SiteAliasRecords", {
hostedZoneId: "Z1234567890",
type: "A",
aliasTarget: {
hostedZoneId: distribution.hostedZoneId,
dnsName: distribution.domainName,
},
});
// elsewhere:
yield* records.bind`MySite`({ names: ["docs.example.com"] });

Source: src/AWS/Route53/TestDNSAnswer.ts

Runtime binding for the TestDNSAnswer operation (IAM action route53:TestDNSAnswer; the action does not support resource-level permissions, so it is granted on *).

Asks Route 53’s authoritative servers what they would answer for a record in the bound HostedZone — works before (and without) delegation, so it verifies records written via ChangeResourceRecordSets without waiting for public DNS. Public zones only. Provide the implementation with Effect.provide(AWS.Route53.TestDNSAnswerHttp).

const testDnsAnswer = yield* AWS.Route53.TestDNSAnswer(zone);
const answer = yield* testDnsAnswer({
RecordName: "www.example.com",
RecordType: "A",
});
// answer.ResponseCode -> "NOERROR", answer.RecordData -> the values

Source: src/AWS/Route53/VpcAssociationAuthorization.ts

Authorization for a VPC (usually in another AWS account) to be associated with a private hosted zone.

Cross-account private-zone association is a two-step handshake: the zone-owning account creates a VpcAssociationAuthorization for the foreign VPC, then the VPC-owning account submits the association (see ZoneVpcAssociation). Same-account associations don’t need an authorization.

VpcAssociationAuthorization: Authorizing Cross-Account Association

Section titled “VpcAssociationAuthorization: Authorizing Cross-Account Association”
const authorization = yield* VpcAssociationAuthorization("PeerVpcAuth", {
hostedZoneId: zone.id,
vpcId: "vpc-0123456789abcdef0", // VPC in the other account
vpcRegion: "us-west-2",
});

Source: src/AWS/Route53/ZoneVpcAssociation.ts

An association between an additional VPC and a private hosted zone.

A private hosted zone is created with one initial VPC (see HostedZone.vpc); ZoneVpcAssociation attaches further VPCs so their DNS resolvers can answer from the zone. For a VPC in a different account, the zone owner must first create a VpcAssociationAuthorization for it.

The initial VPC of a private zone cannot be modeled with this resource — Route 53 refuses to disassociate the last VPC from a private zone.

const zone = yield* HostedZone("InternalZone", {
name: "internal.example.com",
privateZone: true,
vpc: { vpcId: primary.vpcId, vpcRegion: "us-west-2" },
});
const association = yield* ZoneVpcAssociation("SecondaryVpc", {
hostedZoneId: zone.id,
vpcId: secondary.vpcId,
vpcRegion: "us-west-2",
});