I had an interesting problem to solve yesterday. Essentially I needed to migrate a domain (ie. hosted zone) from one AWS account to another. This isn’t an all-together complicated act, however the biggest problem is migrating the DNS records – particularly if you have a lot of them.
Unsurprisingly, the AWS console makes no attempt at allowing you to export and import a common format of zone file (in fact there’s no export at all). I figured, surely this would be possible using the cli tools… however unfortunately that is not very straightforward.
It is possible to export DNS records for a domain using the aws cli, and it is possible to import them as well, however the structure of the 2 files is a bit different (almost like the two functions were designed by 2 entirely separate teams, who were competing or something!). So what I did was write a simple PHP cli script to convert from the export format to the import format.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
#!/usr/bin/php <?php $exportRecords = file_get_contents("php://stdin"); $exportRecords = json_decode($exportRecords, true); $newRecords = [ 'Comment' => '', 'Changes' => [] ]; foreach ($exportRecords['ResourceRecordSets'] as $record) { $newRecords['Changes'][] = [ 'Action' => 'CREATE', 'ResourceRecordSet' => $record, ]; } echo json_encode($newRecords); ?> |
To do this process, I recommend you set up profiles for both accounts in your ~/.aws/credentials file. Then follow the following steps;
Instructions
Firstly, for both accounts, get the hosted domain zone ID. You can do it using the following command:
1 2 |
aws --profile source-profile route53 list-hosted-zones aws --profile target-profile route53 list-hosted-zones |
You want the 12-16 character alphanumeric ID of the zone associated with the relevant domain name. Change the zone ID in the following examples as necessary.
Then on the source account, you want to export all DNS records with the following aws cli command, which puts them into a file called “source-records” in the current directory.
1 |
aws --profile source-profile route53 list-resource-record-sets --hosted-zone-id ZM9IS7ZHV3BSR > source-records |
Now you want to manually edit that file, and just delete the 2 entries equivilent to the default ones AWS adds for every new domain – the nameservers and root SOA record for the domain. Because these exist already in the new domain route53 setup and are different to the old ones, you do not want to import them. Since this is much simpler to do visually, I didn’t want to bother automating this in the script.
Then, run the converter script on that file.
1 |
./script.php < ./source-records > target-records |
And then, use the aws cli to import the converted file into the new zone (note this assumes again that the record file is in the current directory)
1 |
aws --profile target-profile route53 change-resource-record-sets --hosted-zone-id Z38KNOS2CJGA1H --change-batch file://./target-records |
All done! Really hope this helps someone, as I couldn’t find any guide on how to do this online.