William Huba bio photo

William Huba

Immutably currying dev workflows into your ops.

Email Github Twitter LinkedIn Stackoverflow

Using a small Python script that runs when a new server is created lets us automatically add the server to DNS for round-robin based load balancing. This makes sure that new servers are immediately available for use without having to modify existing servers or code.

Note that in order for this method to work you need some way to dynamically obtain the type of service the new server is running. For our naming scheme, hosts are named IDENTIFIER-SERVICE-ENVIRONMENT, making it easy to parse out the service name.

As an example of what this looks like, let’s say I have a server called cyberdyne-web-sfo-prod with an IP address of 13.37.1.1. After setting up the server, I run one of the scripts on it. I can now query my DNS server for either web.skynet.hiveary.com or cyberdyne-web-sfo-prod.skynet.hiveary.com; both will resolve to 13.37.1.1.

I then setup another server called techcom-web-sfo-prod with an address of 13.37.1.2 and run the same script on it. Now querying techcom-web-sfo-prod.skynet.hiveary.com always resolves to 13.37.1.2 and cyberdyne-web-sfo-prod.skynet.hiveary.com always resolves to 13.37.1.1; querying web.skynet.hiveary.com, however, will return both 13.37.1.1 and 13.37.1.2. The order in which they are returned is rotated in a round-robin fashion with each request.

The first step is to make sure that dynamic DNS is enabled for the zones that will be updated. For BIND9, this is done with the “allow-update” option (actual names and IPs changed to protect the innocent):

acl internal-ips {
  127.0.0.1;
   13.37/16;
 };
 zone "skynet.hiveary.com" IN {
   type master;
   file "skynet.hiveary.com.zone";
   allow-update { "internal-ips"; };
 };
 zone "37.13.in-addr.arpa" IN {
   type master;
   file "37.13.in-addr.arpa.zone";
   allow-update { "internal-ips"; };
 };

Now the DNS server is setup for dynamic updates. On the server to be added, make sure Python is installed (both 2.x and 3.x work), and install the excellent dnspython package: sudo pip install dnspython

The last step is to run the update script (linked from the end of this post) on the server using whatever your preferred configuration management method is. I’ve created two versions of a Python script for this purpose; the first uses the sockets library to discover host information, while the second is written to be used as a Salt template. Either script can be modified fairly easily to fit other systems.


Dynamic DNS Python scripts: