Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ALLOWED_HOSTS not working in my Django App deployed to Elastic Beanstalk

I deployed a Django App to AWS Elastic Beanstalk and I'm getting "Invalid HTTP_HOST header" error even when I've added it to my allowed hosts settings.

I'm getting this error:

Invalid HTTP_HOST header: 'recordings-env.kf4qfzaijd.us-west-2.elasticbeanstalk.com'. You may need to add 'recordings-env.kf4qfzaijd.us-west-2.elasticbeanstalk.com' to ALLOWED_HOSTS.

This is what I have in my settings.py

settings.py:

ALLOWED_HOSTS = [
    '127.0.0.1',
    'localhost',
    '.amazonaws.com',
    '.elasticbeanstalk.com',
    'recordings-env.kf4qfzaijd.us-west-2.elasticbeanstalk.com',
]

I think the problem is that my settings aren't being updated, because isn't working either if I put ALLOWED_HOSTS = ['*']. I left DEBUG = True and in request information I'm getting: ALLOWED_HOSTS: ['localhost']

after modifying it I run eb deploy without errors.

like image 416
Josefina Estevez Avatar asked Mar 30 '19 17:03

Josefina Estevez


People also ask

When should you not use Elastic Beanstalk?

Elastic Beanstalk isn't great if you need a lot of environment variables. The simple reason is that Elastic Beanstalk has a hard limit of 4KB to store all key-value pairs. The environment had accumulated 74 environment variables — a few of them had exceedingly verbose names.

What workloads can you deploy using Elastic Beanstalk?

Elastic Beanstalk is a service for deploying and scaling web applications and services. Upload your code and Elastic Beanstalk automatically handles the deployment—from capacity provisioning, load balancing, and auto scaling to application health monitoring.

Does Elastic Beanstalk use Gunicorn?

Starting with Amazon Linux 2 platform branches, Elastic Beanstalk provides Gunicorn as the default WSGI server. You can add a Procfile to your source bundle to specify and configure the WSGI server for your application.


2 Answers

I've realized that my changes wasn't being deployed because I needed to commit first and I didn't know that (my first time deploying to eb). So, that was the problem.

like image 110
Josefina Estevez Avatar answered Oct 23 '22 13:10

Josefina Estevez


It's a little tricky because you need to dynamically declare your ALLOWED_HOSTS with EB. This article provides some good information in Gotcha #3 on how you could achieve this

I would create a separate settings file called something like settings_production.py then you could place the following code in there:

mysite/settings_production.py

from mysite.settings import *


def is_ec2_linux():
    """Detect if we are running on an EC2 Linux Instance
       See http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/identify_ec2_instances.html
    """
    if os.path.isfile("/sys/hypervisor/uuid"):
        with open("/sys/hypervisor/uuid") as f:
            uuid = f.read()
            return uuid.startswith("ec2")
    return False


def get_linux_ec2_private_ip():
    """Get the private IP Address of the machine if running on an EC2 linux server"""
    from urllib.request import urlopen
    if not is_ec2_linux():
        return None
    try:
        response = urlopen('http://169.254.169.254/latest/meta-data/local-ipv4')
        return response.read().decode("utf-8")
    except:
        return None
    finally:
        if response:
            response.close()


# ElasticBeanstalk healthcheck sends requests with host header = internal ip
# So we detect if we are in elastic beanstalk,
# and add the instances private ip address
private_ip = get_linux_ec2_private_ip()
if private_ip:
    ALLOWED_HOSTS += [private_ip, 'your-django-env.elasticbeanstalk.com']

# Other production overrides
DEBUG = False


Now you set "DJANGO_SETTINGS_MODULE" env variable to mysite.production_settings for your production (.i.e your EB environment).

UPDATE:

I decided to take this for a test spin and managed to get it up and running. I discovered a few things though. The above code adds the internal IP of each instance to the ALLOWED_HOSTS. This is purely for health checks so that AWS console can ping the instances internally and receive a 200OK response. I'm leaving the above solution as it is still useful for that purpose. It will not solve your particular error though. To serve you simply need to add your EB url, that is all. You can find it in the AWS console (highlighted in red below) or in the cli by typing eb status and checking the CNAME property.

enter image description here

CONFIG:

Here are my basic config files I manually created in my source:

.ebextensions/django.config


option_settings:
  aws:elasticbeanstalk:container:python:
    WSGIPath: mysite/wsgi.py
  aws:elasticbeanstalk:application:environment:
    DJANGO_SETTINGS_MODULE: mysite.settings_production

.ebextensions/db-migrate.config


container_commands:
  01_migrate:
    command: "django-admin.py migrate"
    leader_only: true
option_settings:
  aws:elasticbeanstalk:application:environment:
    DJANGO_SETTINGS_MODULE: mysite.settings_production
like image 4
Lance Avatar answered Oct 23 '22 14:10

Lance