Overview
Purpose
Section titled “Purpose”Many environments still run legacy BIND that cannot realistically migrate — it stays the DNS authority on-prem. Cloud workloads still need those same private names.
This walkthrough shows how to leave BIND in place and mirror it into a Route 53 private hosted zone
Route 53 private hosted zone for corp.internal associated with Workload_VPC only (not OnPrem_VPC). so VPC consumers resolve via AmazonProvidedDNS. A scheduled Sync_Lambda
Lambda in Workload_VPC that AXFRs from BIND_EC2, diffs against the Route 53 PHZ, and applies ChangeResourceRecordSets batches. pulls the zone from BIND (AXFR), diffs Route 53, and applies changes.
The lab simulates on-prem and cloud with two AWS accounts. Hybrid reachability for the zone transfer uses Site-to-Site VPN
Lab connectivity only — how Sync_Lambda reaches BIND for AXFR in this demo. Not the product focus; real estates may use Direct Connect or other private paths. in this demo.
Infrastructure and sync code live in the upstream demo repository
jajera/bind-to-route53-mirror-demo — Terraform, Lambda sync code, and operator docs; this site is the companion walkthrough only.. Use this site to run the path end to end; use the demo repo as the source of truth for Terraform and Lambda.
What you prove
Section titled “What you prove”| Step | Proof |
|---|---|
| Connectivity | Sync Lambda can reach BIND (lab: at least one VPN tunnel UP) |
| BIND authority | Record answers immediately on BIND after rndc reload |
| Mirror | Lambda returns "status": "success"; CloudWatch shows axfr_complete / sync_success |
| Cloud DNS | dig on the test instanceEC2 in Workload_VPC used to validate resolution via AmazonProvidedDNS against the Route 53 mirror — never queries BIND directly. returns the mirrored A record via AmazonProvidedDNS VPC resolver at the base of the VPC CIDR + 2 (also reachable as 169.254.169.253) — Test_Instance queries this to hit the Route 53 mirror. |
Target audience
Section titled “Target audience”Platform and network engineers who need cloud DNS from a BIND estate that must remain on-prem, and who are comfortable with AWS CLI profiles, Terraform, and Session Manager
AWS Systems Manager Session Manager — interactive shell on private EC2 without SSH keys; all demo hosts use SSM..
Non-goals
Section titled “Non-goals”- Replacing or migrating off BIND
- Production DNS HA, IXFR
Incremental zone transfer. Out of scope — this demo uses full AXFR only., or bi-directional sync (Route 53 → BIND) - Public delegation of
corp.internal - Replacing the upstream demo as the code source of truth
What this is / What this is not
Section titled “What this is / What this is not”| What this is | What this is not |
|---|---|
| A walkthrough for mirroring legacy BIND into Route 53 | A BIND migration or cutover guide |
| Operational path: deploy → edit BIND → sync → resolve in cloud | A live managed lab |
Companion docs with upstream links pinned to main | The Terraform / Lambda source of truth |
View on GitHub: jajera/bind-to-route53-mirror-demo
Story to keep in mind
Section titled “Story to keep in mind”- BIND stays authoritative — it holds corp.internal
Demo private zone name (`corp.internal`). BIND is authoritative; Route 53 holds a read-only mirror in the workload VPC.; day-to-day cloud queries do not talk to BIND. - Route 53 is the cloud mirror — workloads resolve private names through AmazonProvidedDNS against the PHZ.
- Mirror, not dual-write — change BIND → sync → Route 53 catches up.
- Reachability is required for sync — the Lambda must reach BIND private IP for AXFR (this lab uses a VPN tunnel
Encrypted IPsec path carrying traffic (including AXFR) between Workload_VPC and OnPrem_VPC. This demo expects at least one tunnel UP.); the Route 53 API uses NAT
NAT gateway in Workload_VPC — Sync_Lambda reaches the Route 53 API over HTTPS via NAT (not over the VPN). → HTTPS, not that path. - Stale is expected on failure — if AXFR or API fails, Route 53 keeps the last good snapshot
On sync failure, Route 53 keeps the last successfully mirrored records until the next successful run. until sync succeeds again.