Route 53
Route 53 control plane — hosted zones, RRsets, health checks, traffic policies, DNSSEC + KSK, query logging, CIDR collections.
fakecloud implements Amazon Route 53's REST-XML control plane focused on the operations real applications and Terraform stacks rely on for DNS management: hosted zone lifecycle, resource record sets with the full ChangeResourceRecordSets semantics (CREATE/UPSERT/DELETE), change tracking, hosted zone limits, list-by-name pagination, TestDNSAnswer synthesis, the full health-check lifecycle, versioned traffic policies with policy instances, DNSSEC signing + key-signing keys, query logging configs, and CIDR collections. 54 operations.
Status: Batches 1–4 shipped. VPC associations + reusable delegation sets, geo location lookups, account limits, and tags land in subsequent batches.
Supported today
- Hosted Zones —
CreateHostedZone,GetHostedZone,DeleteHostedZone,ListHostedZones,ListHostedZonesByName,GetHostedZoneCount,UpdateHostedZoneComment,UpdateHostedZoneFeatures,GetHostedZoneLimit.CreateHostedZoneseeds defaultSOA+NSrecords at the zone apex matching real Route 53 behavior, returns synthesized AWS name servers (ns-2048.awsdns-64.com+ 3 siblings) in aDelegationSet, and rejects duplicateCallerReferencewithHostedZoneAlreadyExists. Private zones require aVPC.DeleteHostedZoneenforces theHostedZoneNotEmptyrule when user-managed records exist. Comment and features are updatable in place. - Resource Record Sets —
ChangeResourceRecordSetsaccepts the fullChangeBatchshape with multipleChangeentries and supportsCREATE(rejects existing),UPSERT(replace-or-insert), andDELETE(errors on the default SOA/NS apex records).ListResourceRecordSetsreturns all record types with optionalSetIdentifierfor weighted/latency/failover routing. Each successful change emits a trackedChangeInfowhose status is reported asINSYNCimmediately for deterministic tests. - Change tracking —
GetChangereturns per-batchChangeInfowith theINSYNCstatus, submitted timestamp, and the comment from the originating batch. - DNS test —
TestDNSAnswersynthesizes an answer from the in-memory record set: it looks up the named record/type in the supplied hosted zone and returns the recorded values inside<RecordData>withResponseCode = NOERROR. Resolver IP and EDNS0 client subnet IP are echoed back into the response. - Health Checks —
CreateHealthCheck,GetHealthCheck,UpdateHealthCheck,DeleteHealthCheck,ListHealthChecks,GetHealthCheckCount,GetHealthCheckStatus,GetHealthCheckLastFailureReason,GetCheckerIpRanges. Full lifecycle for HTTP/HTTPS/TCP/HTTP_STR_MATCH/HTTPS_STR_MATCH/CALCULATED/CLOUDWATCH_METRIC/RECOVERY_CONTROL types with the documentedHealthCheckConfigshape (port, path, FQDN, search string, request interval, failure threshold, regions, alarm identifier, child checks, routing-control ARN, etc.).CreateHealthCheckrejects duplicateCallerReferencewithHealthCheckAlreadyExists.UpdateHealthCheckenforces optimistic concurrency viaHealthCheckVersion(mismatch ->HealthCheckVersionMismatch), bumps the version on success, and honors theResetElementslist to clearChildHealthChecks/FullyQualifiedDomainName/Regions/ResourcePath.DeleteHealthCheckrejects withHealthCheckInUsewhile any record set still references the check viaHealthCheckId.GetHealthCheckStatusreturns synthetic per-region observations (no real prober runs).GetHealthCheckLastFailureReasonreturns an empty observations list (fakecloud has no live checker).GetCheckerIpRangesreturns the documented Route 53 health checker CIDRs. - Traffic Policies —
CreateTrafficPolicy,GetTrafficPolicy,CreateTrafficPolicyVersion,UpdateTrafficPolicyComment,DeleteTrafficPolicy,ListTrafficPolicies,ListTrafficPolicyVersions. Each policy carries an immutableIdand a monotonically increasingVersion;CreateTrafficPolicyVersionkeeps every prior version queryable viaGetTrafficPolicy(Id, Version).CreateTrafficPolicyrejects a duplicateNamewithTrafficPolicyAlreadyExists.DeleteTrafficPolicyrejects withTrafficPolicyInUsewhile any traffic policy instance still references that(Id, Version). TheTypefield is inferred from the policy document'sRecordTypeJSON key and defaults toAwhen absent. - Traffic Policy Instances —
CreateTrafficPolicyInstance,GetTrafficPolicyInstance,UpdateTrafficPolicyInstance,DeleteTrafficPolicyInstance,ListTrafficPolicyInstances,ListTrafficPolicyInstancesByHostedZone,ListTrafficPolicyInstancesByPolicy,GetTrafficPolicyInstanceCount.CreateTrafficPolicyInstancevalidates the target hosted zone exists, validates the(TrafficPolicyId, TrafficPolicyVersion)resolves to a real policy, and rejects a duplicate(HostedZoneId, Name, Type)instance withTrafficPolicyInstanceAlreadyExists. The instanceStateis reported asAppliedimmediately for deterministic tests — fakecloud does not emulate the realCreating -> Appliedpropagation window. - DNSSEC + Key Signing Keys —
GetDNSSEC,EnableHostedZoneDNSSEC,DisableHostedZoneDNSSEC,CreateKeySigningKey,DeleteKeySigningKey,ActivateKeySigningKey,DeactivateKeySigningKey.GetDNSSECreturns the per-zoneServeSignature(SIGNING/NOT_SIGNING, defaultNOT_SIGNING) plus every KSK attached to the zone.CreateKeySigningKeyrequiresCallerReference,HostedZoneId,KeyManagementServiceArn,Name, andStatus; rejects a duplicateNameper zone withKeySigningKeyAlreadyExists; synthesizes theKeyTag/Flag/SigningAlgorithm/DigestAlgorithmfields with the documentedECDSAP256SHA256/SHA-256 defaults.DeleteKeySigningKeyreturnsInvalidKeySigningKeyStatuswhen the KSK is stillACTIVE— flip toINACTIVEviaDeactivateKeySigningKeyfirst.Enable/Disable/Activate/Deactivateeach emit a trackedChangeInfo(INSYNC). - Query Logging —
CreateQueryLoggingConfig,GetQueryLoggingConfig,DeleteQueryLoggingConfig,ListQueryLoggingConfigs. One config per zone; private zones are rejected withInvalidInput; duplicate per zone returnsQueryLoggingConfigAlreadyExists. Configs persist theCloudWatchLogsLogGroupArnround-trip but fakecloud doesn't actually publish DNS query logs (no real DNS resolver runs). - CIDR Collections —
CreateCidrCollection,ChangeCidrCollection,DeleteCidrCollection,ListCidrCollections,ListCidrLocations,ListCidrBlocks.CreateCidrCollectionrejects duplicateNamewithCidrCollectionAlreadyExistsExceptionand synthesizes a real Route 53 ARN.ChangeCidrCollectionhonorsPUTandDELETE_IF_EXISTSchange actions, applies the entire batch atomically (any unknown action rolls back), and enforces optimistic concurrency viaCollectionVersion(CidrCollectionVersionMismatchException).DeleteCidrCollectionreturnsCidrCollectionInUseExceptionwhile any location still has CIDR blocks.
Concurrency semantics
Route 53's wire protocol is REST-XML. There is no If-Match / ETag enforcement at the wire level for hosted zones — Route 53 itself does not require optimistic concurrency control here, and fakecloud follows the same model.
Idempotency
CreateHostedZone rejects a duplicate CallerReference with HostedZoneAlreadyExists (matches real Route 53). The error response carries the existing zone's resource record set count.
ChangeBatch semantics
The full action set is honored:
CREATE: rejected withInvalidChangeBatchif(Name, Type, SetIdentifier)already exists.UPSERT: replaces an existing record set with the same(Name, Type, SetIdentifier)tuple, otherwise inserts.DELETE: rejected withInvalidChangeBatchif the target is not found, or if it would remove the defaultSOA/NSrecords at the zone apex.
The default SOA/NS records seeded by CreateHostedZone carry the AWS-shaped awsdns-hostmaster.amazon.com. mailbox and the synthesized name servers from the delegation set. DeleteHostedZone ignores them when checking emptiness.
Smoke test
fakecloud &
# Create a hosted zone
ZONE=$(aws --endpoint-url http://localhost:4566 route53 create-hosted-zone \
--name example.com \
--caller-reference "$(date +%s)")
ID=$(echo "$ZONE" | jq -r '.HostedZone.Id')
# Add an A record
aws --endpoint-url http://localhost:4566 route53 change-resource-record-sets \
--hosted-zone-id "$ID" \
--change-batch '{
"Changes": [
{
"Action": "UPSERT",
"ResourceRecordSet": {
"Name": "api.example.com.",
"Type": "A",
"TTL": 60,
"ResourceRecords": [{"Value": "203.0.113.1"}]
}
}
]
}'
# List records
aws --endpoint-url http://localhost:4566 route53 list-resource-record-sets --hosted-zone-id "$ID"
# Test DNS resolution
aws --endpoint-url http://localhost:4566 route53 test-dns-answer \
--hosted-zone-id "${ID#/hostedzone/}" \
--record-name api.example.com \
--record-type ANot yet implemented (planned)
| Surface | Status |
|---|---|
| VPC Associations + Delegation Sets | next batch |
| Geo Location lookups | next batch |
| Tags | next batch |
There is no actual DNS server: requests against the synthesized name servers don't return live responses. TestDNSAnswer looks up records from the in-memory state and returns them; treat it as a record-set lookup, not a real DNS resolver. Likewise, fakecloud does not run real health probes: GetHealthCheckStatus returns synthesized observations and GetHealthCheckLastFailureReason is always empty. The data is structurally valid but never reflects a real endpoint outage.