89

I would like to export a DNS zonefile from my Amazon Route 53 setup. Is this possible, or can zonefiles only be created manually? (e.g. through http://www.zonefile.org/?lang=en)

BenMorel
  • 34,448
  • 50
  • 182
  • 322
casparjespersen
  • 3,460
  • 5
  • 38
  • 63
  • Already answered here http://serverfault.com/questions/535631/how-to-export-a-hosted-zone-in-aws-route-53 – Gil Oct 29 '14 at 12:09
  • For YAML AWS CLI output it could be: zone["ResourceRecordSets"].collect { |r| "#{r["Name"]} #{r["TTL"]}s #{r["Type"]} #{r["ResourceRecords"].first["Value"]}" }.each { |ri| puts ri } **It's not accurate for multi-dest records like MX usually and do have SOA and NS, what is garbage** – deman_killer Aug 26 '21 at 10:57

7 Answers7

96

The following script exports zone details in bind format from Route53. Pass over the domain name as a parameter to script. (This required awscli and jq to be installed and configured.)

#!/bin/bash

zonename=$1
hostedzoneid=$(aws route53 list-hosted-zones --output json | jq -r ".HostedZones[] | select(.Name == \"$zonename.\") | .Id" | cut -d'/' -f3)
aws route53 list-resource-record-sets --hosted-zone-id $hostedzoneid --output json | jq -jr '.ResourceRecordSets[] | "\(.Name) \t\(.TTL) \t\(.Type) \t\(.ResourceRecords[]?.Value)\n"'
JacopKane
  • 824
  • 11
  • 15
Szentmarjay Tibor
  • 1,099
  • 1
  • 7
  • 4
  • 1
    Please add some explanations as well. – BlackBeard Jan 29 '18 at 10:21
  • @szentmarjay-tibor You can change the following line, since it will give error if the default output is different from json. `hostedzoneid=$(aws route53 list-hosted-zones | jq -r ".HostedZones[] | select(.Name == \"$zonename.\") | .Id" | cut -d'/' -f3) ` "' – Adriano Apr 24 '18 at 16:58
  • 1
    to avoid the null iteration: aws route53 list-resource-record-sets --hosted-zone-id $hostedzoneid --output json | jq -jr '.ResourceRecordSets[] | "\(.Name) \t\(.TTL) \t\(.Type) \t\(.ResourceRecords[]?.Value)\n"' – rpvilao Sep 29 '19 at 13:42
  • 9
    The above comment is useful but doesn't escape `(`. Instead use: `aws route53 list-resource-record-sets --hosted-zone-id $hostedzoneid --output json | jq -jr '.ResourceRecordSets[] | "\(.Name) \t\(.TTL) \t\(.Type) \t\(.ResourceRecords[]?.Value)\n"'` – Doug Thompson Oct 15 '19 at 10:56
  • how do I run this text? (sorry if this question might seem strange to someone ) – adir abargil Jul 22 '21 at 14:33
  • @adirabargil Create a shell file and copy this text. Save the file and give executable permissions to file using `chmod +x filename.sh`. Execute this file by running the command `./filename.sh yourdomaintoexport.com` – Gaurav Sharma Dec 01 '21 at 09:10
  • for some reason this script does not output all of the zone records for me omitting several latest ones – DataGreed Feb 22 '22 at 18:07
  • Anyone have a windows command prompt version? – Teddy Higgins May 02 '22 at 13:55
  • Note that for records with the same name (for example an A and a TXT) only one will be exported. – ElementalStorm Jun 24 '22 at 11:45
  • @TeddyHiggins just install Windows Subsystem for Linux by Microsoft. Then you can do all kinds of cool linux stuff on your windows machine. – Panama Jack Nov 10 '22 at 22:01
  • This worked great for me, except that there were multiple matched zone IDs for my zonename so I needed to put the final `list-resource-record-sets` into a loop. – MadScientist Jan 23 '23 at 18:27
  • 1
    At least for me, this command misses CNAME "A" records. If I instead do this: aws route53 list-resource-record-sets --hosted-zone-id $hostedzoneid --output json | jq -jr '.ResourceRecordSets[] | "\(.Name) \t\(.TTL) \t\(.Type) \t\(.AliasTarget?.DNSName)\n"' it will pick up the A records. Can't figure how to do both the AliasTarget as well as the ResourceRecords in one command though... – Mark Watkins Feb 02 '23 at 22:05
28

It's not possible yet. You'll have to use the API's ListResourceRecordSets and build the zonefile yourself.

Ioan Alexandru Cucu
  • 11,981
  • 6
  • 37
  • 39
  • 32
    See this tool: [https://github.com/barnybug/cli53](https://github.com/barnybug/cli53) It's a Command line script to administer the Amazon Route 53 dns service. Hope that helps – Thales Ceolin Feb 07 '14 at 19:07
  • 74
    *grrrr* I can't believe the developers thought of an "Import" button and forgot "Export!" – KateYoak Oct 06 '15 at 20:42
  • 13
    Makes sense that they want to bring in business, but want to make it hard to take away business. But yes very annoying! Thanks for the reference to the cli tool. – Benno Oct 18 '15 at 06:52
  • 9
    They have record values that aren't RFC compliant. They wouldn't have the ability to export without loss of data. – Mark Lopez Dec 29 '15 at 02:39
  • 2
    Good luck with that! It's simple to get the all the records with that API call into a JSON file. Unfortunately, you then have to edit that file, including editing EVERY SINGLE RECORD in that file so that it has the right format and you can then use it to import. In my case, we have 250+ records, which makes this totally unpractical. Absolute rubbish from AWS! – Kappacake Mar 16 '21 at 12:25
18

As stated in the comment, the cli53 is a great tool to interact with Route 53 using the command line interface.

First, configure your account keys in ~/.aws/config file:

[default]
aws_access_key_id = AK.....ZP
aws_secret_access_key = 8j.....M0

Then, use the export command:

$ cli53 export --full --debug example.com > example.com.zone 2> example.com.zone.log

Verify the example.com.zone file after export to make sure that everything is exported correctly.

You can import the zone lately:

$ cli53 import --file ./example.com.zone example.com

And if you want to transfer the Route53 zone from one AWS account to another, you can use the profile option. Just add two named accounts to the ~/.aws/config file and reference them with the profile property during export and import. You can even pipe these two commands.

Slava Fomin II
  • 26,865
  • 29
  • 124
  • 202
10

You can export a JSON file: aws route53 list-resource-record-sets --hosted-zone-id <zone-id-here> --output json > route53-records.json

Broshi
  • 3,334
  • 5
  • 37
  • 52
5

You can export with aws api

aws route53 list-resource-record-sets --hosted-zone-id YOUR_ZONE_ID

Yo Im
  • 84
  • 1
  • 3
4

Based on @szentmarjay's answer above, except it shows usage and supports zone_id or zone_name. This is my fave because it's standard old school bind format, so other tools can do stuff with it.

#!/bin/bash
# r53_export

usage() {
  local cmd=$(basename "$0")
  echo -e >&2 "\nUsage: $cmd {--id ZONE_ID|--domain ZONE_NAME}\n"
  exit 1
}

while [[ $1 ]]; do
  if   [[ $1 == --id ]];     then shift; zone_id="$1"
  elif [[ $1 == --domain ]]; then shift; zone_name="$1"
  else usage
  fi
  shift
done

if [[ $zone_name ]]; then
  zone_id=$(
    aws route53 list-hosted-zones --output json \
      | jq -r ".HostedZones[] | select(.Name == \"$zone_name.\") | .Id" \
      | head -n1 \
      | cut -d/ -f3
  )
  echo >&2 "+ Found zone id: '$zone_id'"
fi
[[ $zone_id ]] || usage

aws route53 list-resource-record-sets --hosted-zone-id $zone_id --output json \
  | jq -jr '.ResourceRecordSets[] | "\(.Name) \t\(.TTL) \t\(.Type) \t\(.ResourceRecords[]?.Value)\n"'
lilole
  • 322
  • 2
  • 9
3

Exporting and importing is possible with https://github.com/RisingOak/route53-transfer