Overcast is alpha — behaviour and APIs may change between releases. Pin your version and read the changelog before upgrading.

overcast

Route 53 — Amazon Route 53

Quick start, the record types the built-in resolver answers, and the routing, health-check and VPC-scoping behaviour that is stored but never acted on.

Hosted zone records really answer queries: Overcast’s own resolver is authoritative for every zone in the store. Routing policies are stored but not evaluated, and health checks never probe anything.

Status: ⚠️ Partial

Quick start

export AWS_ENDPOINT_URL=http://localhost:4566
ZONE=$(aws route53 create-hosted-zone --name example.internal --caller-reference "$RANDOM" \
  --query 'HostedZone.Id' --output text)

aws route53 change-resource-record-sets --hosted-zone-id "$ZONE" --change-batch '{
  "Changes":[{"Action":"CREATE","ResourceRecordSet":{
    "Name":"api.example.internal","Type":"A","TTL":60,
    "ResourceRecords":[{"Value":"10.0.0.9"}]}}]}'

dig +short @localhost api.example.internal

Any credentials work; with none configured, run eval "$(overcast env)" first — see Using AWS SDKs and CLI.

The resolver runs on port 53 by default (OVERCAST_DNS, OVERCAST_DNS_PORT). Failing to bind it is not fatal, so on a machine where something already owns port 53 the API still works and only DNS answers are missing.

DNS serving

A query whose name falls under a hosted zone — the apex or any subdomain — is answered from that zone’s record sets.

AspectBehaviour
Types servedA, AAAA, CNAME, MX, TXT, NS, SOA, including the apex NS/SOA every zone gets on creation
CNAMEChased across zones, up to 8 hops; a cycle terminates the chain rather than looping
WildcardsOne label, as AWS scopes them: *.example.com answers foo.example.com but not foo.bar.example.com
TTLThe record’s own stored TTL, not the split-horizon default
ALIASResolves to Overcast’s own address — the one the calling container or host can reach — since that is the only correct answer for an alias pointed at an emulated ELB, CloudFront, S3 website or API Gateway hostname
Negative answersA name in the zone with no record of that type is NODATA; a name absent from the zone is NXDOMAIN. Both carry the zone’s SOA for negative caching

Types that can be stored but are not served — a query gets NODATA or NXDOMAIN like any absent type: NAPTR, PTR, SRV, SPF, CAA, DS, TLSA, SSHFP, SVCB, HTTPS. An AAAA-typed alias answers NODATA, because Overcast has no IPv6 address to give.

A hosted zone always wins over Overcast’s split-horizon names: a name some zone claims is answered from that zone, authoritatively, and never forwarded. Only a name no zone claims falls through to the split-horizon and forwarding behaviour. A container endpoint — an RDS endpoint, an ElastiCache node — is resolved by Docker’s embedded resolver from the container’s network aliases before either authority is reached, so it is unaffected either way.

What works

AreaBehaviour
Hosted zonesCreateHostedZone requires a CallerReference and rejects a reused one with HostedZoneAlreadyExists. Each zone gets default apex NS and SOA records and a four-server delegation set derived from the zone ID, and the new zone’s URL comes back in Location
Record changesChangeResourceRecordSets validates the whole batch atomically before applying anything — InvalidChangeBatch for creating an existing record, deleting a missing one or one whose values do not match, records outside the zone, a CNAME at the apex, deleting the default apex records, and a value that does not fit its record type
ListingListResourceRecordSets returns records in DNS order (names compared with labels reversed) and paginates on name/type/identifier/maxitems
DeletionDeleteHostedZone returns HostedZoneNotEmpty while non-default records exist; a successful delete cascades the default records and the zone’s tags
IdentifiersZone and change IDs are stored and returned in AWS’s path format — /hostedzone/Z123…, /change/C123…
ErrorsRoute 53’s ErrorResponse envelope (Type/Code/Message), not S3’s bare <Error> shape
Health checksConfiguration is stored with AWS’s defaults and versioned by UpdateHealthCheck

Route 53 is a global service here, and domain and record names are canonicalised to lowercase with a trailing dot.

Differences from AWS

AreaOn AWSOvercast
Routing policiesWeighted, latency, failover, geolocation and multivalue pick one answerThe metadata is stored and returned but never evaluated — several record sets sharing a name and type are merged into one answer
Health checksEndpoints are probedNone is ever probed; GetHealthCheckStatus and GetHealthCheckLastFailureReason return 501
Private zonesResolvable only from the associated VPCsServed to every container Overcast starts, with no VPC filtering; AssociateVPCWithHostedZone, DisassociateVPCFromHostedZone and ListHostedZonesByVPC return 501
Change propagationPENDING, then INSYNCChangeResourceRecordSets applies synchronously, so a change is INSYNC immediately
Traffic policiesFull APICreateTrafficPolicy returns 501

The full list is in Route 53 limitations.

Gotchas

Note

Overcast never becomes an internet-reachable authority for a public zone’s real domain. There is no NS delegation and nothing published to the internet — the resolver answers the containers Overcast starts, and a host that has explicitly pointed its own resolution here.

Operations

19 of 25 listed operations are implemented. Per-operation status, notes and AWS API links: Route 53 operations.