How to implement free failover function with Cloudflare
Cloudflare has Load Balancer module which can implement auto failover for your serivces. But that's a premium feature, which you need to buy from Cloudflare. Please read the following article.
Load Balancing & Intelligent Failover with Cloudflare
Thankfully Cloudlflare provides the free API for its DNS operation. By using their DNS API we can create our own failover scripts and that's totally free.
Given your web service URL is www.sample.com, first we have to deploy health checks for this URL. This is easy implemented by a perl script as follows.
use strict;
use LWP::UserAgent;
my $url = 'http://www.sample.com/';
my $ua = LWP::UserAgent->new(timeout => 10);
my $response = $ua->get($url);
if ($response->is_success) {
# print $response->decoded_content;
}
else {
# failover();
}
As the code above, when fetching the URL successes, nothing shall happen. If fetching failed, we can run failover() function.
Since we are talking about failover, that means at least there are two active backend servers. The first server is serving normally, we call it primary server. When primary server fails to respond, we change DNS record pointing to the second server, which we call slave server.
So in failover() function we just change the DNS record for www.sample.com to slave server. This can be implemeted by using the perl module Net::Cloudflare::DNS which is written by me as well.
Net::Cloudflare::DNS - DNS API for Cloudflare API v4
To install it, run this command in shell,
$ sudo cpanm Net::Cloudflare::DNS
The next, write the perl function as follows,
use Net::Cloudflare::DNS;
# credentials got from Cloudflare
my $api_key = " ";
my $zone_id = " ";
my $email = " ";
# new the object
my $dns = Net::Cloudflare::DNS->new(email=>$email, api_key=>$api_key, zone_id=>$zone_id);
# get existing record ID
my $res = $dns->get_records(name=>"www.sample.com");
my $rid = $res->{result}->[0]->{id};
# update the record
$dns->update_record($rid, type=>"A", name=>"www.sample.com",content=>"slave_server_ip", proxied=>\1, ttl=>1);
Hence this is the full script,
use strict;
use Net::Cloudflare::DNS;
use LWP::UserAgent;
# hostname and IP for slave server
my $hostname = "www.sample.com";
my $slave_ip = "74.81.81.81";
my $url = "http://$hostname/";
my $ua = LWP::UserAgent->new(timeout => 10);
my $response = $ua->get($url);
if ($response->is_success) {
# do nothing
}
else {
failover($hostname,$slave_ip);
}
sub failover {
my $hostname = shift;
my $slave_ip = shift;
# credentials got from Cloudflare
my $api_key = '5f69...';
my $zone_id = 'fcc9...';
my $email = '[email protected]';
# new CF DNS object
my $dns = Net::Cloudflare::DNS->new(email=>$email, api_key=>$api_key, zone_id=>$zone_id);
# get existing record ID
my $res = $dns->get_records(name=>$hostname);
my $rid = $res->{result}->[0]->{id};
# update the record
$dns->update_record($rid, type=>"A", name=>$hostname,content=>$slave_ip, proxied=>\1, ttl=>1);
}
Now the DNS A record for www.sample.com will be changed to the IP of slave server automatically, if primary server dies. You have failovered it!