AWS Elastic Load Balancer HTTP health check ping not reaching Rails application server

amazon-web-serviceselastic-beanstalkhealthcheckruby-on-rails

I have just inherited a Ruby + Rails application running on AWS Elastic Beanstalk, and it is currently using TCP for the Elastic Load Balancer health check. I wish to switch to HTTP, and actually hit my application.

To do this I creat an endpoint on the application that always returns status 200. I deploy this, and test it with curl.

louis $ curl -I https://my.domain.goes.here/__status__
HTTP/1.1 200 OK
Cache-Control: max-age=0, private, must-revalidate
Date: Tue, 25 Aug 2015 16:09:29 GMT
ETag: W/"028714d01e3aa7ed0ffa7a023f82ca94"
Server: nginx/1.6.2
Strict-Transport-Security: max-age=31536000
X-Request-Id: 1ce6b907-779a-45d2-b9f9-d19a74ef8abd
X-Runtime: 0.002703
Connection: keep-alive

This is the result I expected.

I use the AWS console to set up the health check with the following configuration:

Ping Target          HTTP:80/__status__
Timeout              5 seconds
Interval             30 seconds
Unhealthy Threshold  5
Healthy Threshold    3

But now the health check fails consistently. The same for HTTPS on port 443

I ssh into the instance and curl from there.

# With the "Private IP"
[ec2-user@ip-$PRIVATE_IP_ADDRESS ~]$ curl -I $PRIVATE_IP_ADDRESS/__status__
HTTP/1.1 301 Moved Permanently
Server: nginx/1.6.2
Date: Wed, 26 Aug 2015 08:14:21 GMT
Content-Type: text/html
Connection: keep-alive
Location: https://$PRIVATE_IP_ADDRESS/__status__

# With the "Private DNS"
[ec2-user@ip-$PRIVATE_IP_ADDRESS ~]$ curl -I $PRIVATE_DNS_ADDRESS/__status__
HTTP/1.1 301 Moved Permanently
Server: nginx/1.6.2
Date: Wed, 26 Aug 2015 08:17:20 GMT
Content-Type: text/html
Connection: keep-alive
Location: https://$PRIVATE_DNS_ADDRESS/__status__

# With the "Public IP"
[ec2-user@ip-$PRIVATE_IP_ADDRESS ~]$ curl -I $PUBLIC_IP_ADDRESS/__status__
curl: (7) Failed to connect to $PUBLIC_IP_ADDRESS port 80: Connection timed out

# With the "Public DNS"
[ec2-user@ip-$PRIVATE_IP_ADDRESS ~]$ curl -I $PUBLIC_DNS_ADDRESS/__status__
HTTP/1.1 301 Moved Permanently
Server: nginx/1.6.2
Date: Wed, 26 Aug 2015 07:24:37 GMT
Content-Type: text/html
Connection: keep-alive
Location: https://$PUBLIC_DNS_ADDRESS/__status__

# With the "Public DNS" over HTTPS
[ec2-user@ip-$PRIVATE_IP_ADDRESS ~]$ curl -I https://$PUBLIC_DNS_ADDRESS/__status__
curl: (7) Failed to connect to $PUBLIC_DNS_ADDRESS port 443: Connection refused

What might be the problem here?

Best Answer

The ELB will not hit your domain name, it'll hit your IP address. Test curl -I https://my.**IP**.goes.here/__status__ to verify your status check works properly - it'll hit the default vhost.

edit: Per your updated results, your server is redirecting your HTTP accesses to HTTPS. ELB doesn't consider a 301 a success, so it's treating it as a failure. Exempt your status page from the HTTP → HTTPS redirect.