Search code examples
djangoamazon-ecsamazon-elbaws-application-load-balancer

Getting 400's from aws ELB hostcheck to work with django ALLOWED_HOSTS in aws ECS under awsvpc networking mode?


When moving over to ECS with awsvpc networking mode, my ALB says all my hosts are unhealthy because checking /status/ yields 400s. I've narrowed it down to the issue being something wrong with ALLOWED_HOSTS.

How do I get my web app to give 200's to the ELB Healthchecker?


Solution

  • The solution I came up with is to add the LB's address to ALLOWED_HOSTS:

    ELB_HEALTHCHECK_HOSTNAMES = [ip for network in 
        requests.get(os.environ['ECS_CONTAINER_METADATA_URI']).json()['Networks']
        for ip in network['IPv4Addresses']]
    ALLOWED_HOSTS += ELB_HEALTHCHECK_HOSTNAMES
    

    This will take every IP from every networks attached to your container and add it to your ALLOWED_HOSTS.

    Prior to moving over to ECS with awsvpc networking mode, a lot of us are familiar with this line that retrieves the EC2 instance's IP which is used as the hostname by the ELB health checker:

    ELB_HEALTHCHECK_HOSTNAME = requests.get('http://169.254.169.254/latest/meta-data/local-ipv4', timeout=2).text
    

    This line under ECS with awsvpc networking retrieves the IP of the EC2 instance, not the ENI attached to your container. To retrieve the IP of the ENI, you send a request to the endpoint in the environment variable ${ECS_CONTAINER_METADATA_URI}

    This returns useful metadata about the containers, including the IPV4

    https://docs.aws.amazon.com/AmazonECS/latest/developerguide/task-metadata-endpoint-v3.html