Using Amazon Load Balancers to route traffic to private servers outside Amazon
I'm looking into using Amazon Elastic Load Balancing (ELB) in order to reduce downtime when a server goes down. Basically, I don't want to change the relevant DNS records and wait for DNS propagation across the whole world, I just want to redirect traffic to another machine serving my app.
However, almost all my servers are not EC2 instances, they're VPS or dedicated servers with a company which has nothing to do with Amazon.
Is it possible to use some combination of Amazon's services (in particular ELB) which would allow me to point a domain name at an elastic load balancer, and have it forward requests to 1-2 servers outside Amazon's network?
If the balancer's IP changes, this would obviously not work (can't point a root domain name to it then). However, could you assign the balancer an elastic IP, and then point your domain name to it + configure it to forward requests to Non-Amazon-PrivateServer1 and Non-Amazon-PrivateServer2?
Solution 1:
ELB will only send traffic to EC2 instances.
You could have a couple nginx EC2 instances behind an ELB proxying traffic to your real servers, or you could just go the simple route and drop your DNS TTL to something like 10 minutes so changes reflect more quickly.
Solution 2:
As of August 31, 2017, the Application Load Balancers support IP addresses as targets in addition to instance IDs:
We are pleased to announce that Application Load Balancers can now distribute traffic to AWS resources using their IP addresses as targets in addition to the instance IDs. You can also load balance to resources outside the VPC hosting the load balancer using their IP addresses as targets. This includes resources in peered VPCs, EC2-Classic, and on-premises locations reachable over AWS Direct Connect or a VPN connection. Load balancing across AWS and on-premises resources using the same load balancer makes it easy for you to migrate-to-cloud, burst-to-cloud, or failover-to-cloud.
Solution 3:
Why not use Route53 with health checks for this?
First you create an IP-based health check for each of your servers. These checks can be simple and just monitor HTTP 200 status for a certain request; or you can create more advanced checks that search for a specific string in the request result.
Next, if not done already, you create a Hosted Zone for the domain you are using in Route53; and supply the registrar of your domain with the Route53 assigned DNS servers.
Once that is done, for each server that you want to balance requests over create a Record Set (within the Hosted Zone just created) using for example type 'Weighted', a short TTL (60 or lower) and select 'Associate with Health Check: YES' and choose the Health Check that you created above corresponding to the specific server/IP that you are creating the record for. Again, repeat this for each server/IP.
You end up with multiple record sets each with 1 IP and all associated with the same domain in Route53. Upon DNS requests Route53 will now return one of them based on the weight assigned to them AND based on the current status of each health check. If some health check fails that specific IP is omitted.
You can also do this using other Route53 record set types; for example with 'Failover' you have 1 or several primary IPs and 1 or several secondary IPs. Route53 will always return one of the primary IPs unless the health checks for those fail, then it switches to one of the secondary.
And there are more complex record types in Route53 that can also be combined with health checks: Latency, Geolocation, Multivalue. All very well explained in the AWS docs.