SV Premium

Migration guides

Migrate DNS from NS1 to Amazon Route 53

Export and convert your DNS zones, check the answers on both providers, and switch nameservers with NS1 kept ready for rollback.

From IBM NS1 Connect to Amazon Route 53 · Published 2026-10-06

Before you commit

Hands-on effort
1–3 days of hands-on work; more for traffic steering
Elapsed time
Allow DNSSEC and delegation TTLs, then keep NS1 serving for at least a week after cutover.
Examples cover
Python 3 · AWS CLI v2
Content review
2026-10-09
Integration testing
Not recorded. Rehearse the commands and rollback on staging.

Prerequisites

  • Read-only NS1 API access, Route 53 permissions, and access to the registrar and contract terms.
  • A record inventory, decisions for traffic steering and a planned DNS-change freeze.

Don’t migrate yet if…

  • You cannot replace required NS1 traffic steering or keep both providers consistent during propagation.
  • You have not planned the DNSSEC DS-record transition or cancellation notice.

NS1 (now IBM NS1 Connect) offers self-serve plans and enterprise contracts. Route 53 charges per hosted zone and per million queries, with no contract. If you mainly use plain DNS records, compare that usage-based bill with what you pay today. Try your zone count and query volume in the calculator.

Before changing nameservers, decide how to replace any NS1 filter chains, handle DNSSEC and cancel your contract. The export script cannot do those parts for you.

0. Before you start

1. Create the hosted zone

aws route53 create-hosted-zone --name example.com --caller-reference "$(date +%s)"

Note the Id (Z0123…) and the four NameServers in the output. If you have many zones and want the same four nameservers on all of them, first create a reusable delegation set (aws route53 create-reusable-delegation-set --caller-reference …) and pass its ID to create-hosted-zone with --delegation-set-id.

2. Export and convert

Download ns1-to-route53.py (Python 3 standard library only, read it first) and run it with a read-only NS1 API key:

NS1_API_KEY=... python3 ns1-to-route53.py example.com
# 214 record sets converted, 3 need manual work -> example.com-route53/
#   MANUAL api.example.com A: traffic steering: up, geotarget_country, select_first_n

The script skips SOA and apex NS records (Route 53 creates its own). It quotes and splits TXT strings at the DNS byte limit, and batches the output with headroom for Route 53’s request limits. Oversized individual record sets need manual work. It refuses to overwrite a previous export: if you repeat the export, pass a fresh directory as the second argument so stale batches cannot be imported.

It does not convert records with filter chains, linked records, or ALIAS records. It lists them in manual.txt, because translating them silently would change how they behave.

3. Rebuild the manual records

NS1 feature Route 53 equivalent
up filter + monitoring job Failover routing policy + Route 53 health check
geotarget_country / geofence_regional Geolocation or geoproximity routing policy
weighted_shuffle Weighted routing policy
Latency-based steering (pulsar etc.) Latency routing policy (AWS-region based, not RUM-based)
ALIAS at the apex Alias record if the target is in AWS (CloudFront, ELB, S3…); otherwise A/AAAA records
Linked record Alias record pointing to the target record in the same hosted zone (works at the apex), or a duplicate record

Rebuild and test each of these records before cutover. Health checks are billed per check per month, so add them to your estimate.

4. Import

for f in example.com-route53/batch-*.json; do
  aws route53 change-resource-record-sets --hosted-zone-id Z0123456789 --change-batch "file://$f"
done

5. Verify, record by record

Download dns-diff.sh. It queries every record against both providers’ authoritative nameservers and prints any differences:

./dns-diff.sh example.com-route53/records.txt dns1.p01.nsone.net ns-123.awsdns-45.com

Use one of your NS1 nameservers and one from step 1. Fix differences until it prints All records match. The script reports failed, NXDOMAIN and empty answers as errors, not matches.

records.txt also lists the records from manual.txt. Replace each ALIAS entry with the types you rebuilt (usually A and AAAA) before running it. TTLs aren’t compared, because the converter copies them unchanged. A matching answer from one resolver location says nothing about traffic-steered records, so test their routing and failover separately.

6. Cut over

  1. DNSSEC: if the zone is signed at NS1, remove the DS record at your registrar and wait at least the DS record’s TTL (one day for .com) before changing nameservers. Skipping this makes the domain unresolvable for validating resolvers. You’ll re-enable DNSSEC on Route 53 afterwards.
  2. Freeze DNS changes. Resolvers cache the old delegation for up to the parent zone’s NS TTL (two days for .com), so both providers must serve the same answers during that window. If you must change something, change it in both.
  3. Update the nameservers at your registrar to the four Route 53 nameservers.
  4. Watch it propagate: dig +trace example.com, and query volume in Route 53’s CloudWatch DNSQueries metric.

7. Rollback plan

Keep NS1 serving for at least a week and apply any record changes to both providers. To roll back, restore the NS1 nameservers at the registrar. Rollback is not instant, because resolvers keep the Route 53 delegation until their cached NS records expire, and it is only clean if both copies stayed identical. If you have already enabled DNSSEC on Route 53, fix the DS record at the registrar first: a DS record for the wrong provider makes the zone fail validation.

8. Clean up

Many zones?

GET https://api.nsone.net/v1/zones lists every zone, so you can loop the steps above over it. Cut over in batches by risk: parked and marketing domains first, the primary domain last.

Found a command or version mismatch? Report a correction with the version and steps to reproduce it. Remove secrets and customer data first.