Automate Multiple Domains Migration to Route53 using Nodejs

Route53 is a scalable Domain Name System (DNS) web service by AWS which allows you to create and manage your public DNS records. But how many records / Hosted zones you can create manually: 5, 10, 20? What if you need to create 100s of records / hosted zones at once? So, here is a post on how you can achieve this just by executing a simple nodejs script.
Refer to this link → https://github.com/powerupcloud/Route53.git for the scripts that we have used to automate the creation of hosted zones and importing the records into them.

Prerequisites

  • A text file which contains the hosted zone names, lets say - domains.txt which contains a zone name in each line:
zone1.com  
zone2.com  
zone3.com  
……….
  • resource records files in a single directory, lets say, …/dns/ contains the zone files as:
zone1.com.zone  
zone2.com.zone  
zone3.com.zone  
………..

Each of the zone file will have its DNS record sets, for example zone1.com.dns will have the contents as:

@   IN  SOA ns1.xxx.com. hostmaster.xxx.com. (
      14           ; serial number
      900          ; refresh
      600          ; retry
      86400        ; expire
      3600       ) ; default TTL
;
;  Zone NS records
;
@                       NS      ns2.example.com.
@                       NS      ns1.example.com.
;
;  Zone records
;
@                       A       xxx.xxx.xx.x
www                     A       xxx.xxx.xx.x  

Create Hosted Zones

To automate the creation of hosted zones in Route53, here’s a snippet of the script:

lineReader.eachLine('………/domains.txt',  /*<location of domanis.txt file>*/  
function(line, last)  
 var params = {
        CallerReference: line,
        Name: line
    };
    route53.createHostedZone(params, function(err, data) {
        if (err) console.log(err, err.stack);
        else console.log(data);
    })
    sleep.sleep(5);
});

Using lineReader module of nodejs, we can read the domains.txt file line by line and for each line (i.e. for each domain name), we are calling createHostedZone API to create the hosted zone with that respective domain name. Since there is a limit on requesting this API ( 5 requests per second), we are using the ‘sleep’ module of nodejs which will wait for 5 seconds after each request.

Import Resource Record Sets

To automate the importing of the resource record sets in each zone(created using above script), here’s a snippet of the nodejs code:

var dirname = '../dns/'  ;   /*<full directory path of zone fles>*/  
route53.listHostedZones({}, function(err, data) {  
 if (err) console.log(err, err.stack); 
  else     {
    console.log(data.NextMarker);
    marker = data.NextMarker;
    var nextparams = {
        Marker: marker
    }
    fs.readdir(dirname, function(err, filenames) {
      if (err) console.log(err)
      filenames.forEach(function(filename) {
      fs.readFile(dirname + filename, 'utf-8', function(err, content) {
         if (err) console.log(err)
         file = filename.replace(/\.[^/.]+$/, "")+"."
         for (var i in data.HostedZones){
             zone = data.HostedZones[i].Name
             if(file == zone){
                var dns = file+"dns"
                console.log("Name matched. Importing into zone: ", zone);
                execsync("cli53 import --file "+ dirname + dns +  " "+zone);
              }
          }
        });
      });
   });
  route53.listHostedZones(nextparams, function(err, data){
  ……

dirname variable is defining the directory in which all the zone files are available. listHostedZones() API is being used to list all the zones in which we are going to import the records. Since this API returns only 100 zones per request, and if we are having more than 100 hosted zones, we have defined a variable nextparams which is having NextMarker pointing to the next zone after 100 zones being listed in the first API call.
‘fs’ (file system) module is being used to read the file names in the directory and comparing each of the file name with the zone name that we got using listHostedZones API. If the both names are matched, the file records are being imported to the same zone. The records are then imported using a module ‘execsync’ which is used to execute the commands in terminal. So, after getting the matching record file for a particular zone we are just executing a command to import that file in the zone. The command consists of a command line tool for Route53 (cli53) which should be installed in your system. Refer to this link for installing cli53 : https://github.com/barnybug/cli53.git
Till now, its quite easy to import the records for the first 100 zones, what if we are having more than 100 hosted zones? So, for the next zones , we will list the next 100 hosted zones using nextparams variable and execute the same logic for the next zones too. Our script can be used to import the records in approx. 400 hosted zones.

Hope it reduces the manual efforts you have put in till now. Happy Automation..!! :)

Priyanka Sharma

Priyanka is Senior Cloud and DevOps Engineer. She can churn out CloudFormation templates at a moment's notice and play with Chef/Ansible. Dancing, music, badminton and word games are her hobbies

comments powered by Disqus