Deploying a Django app on AWS

From Littledamien Wiki
Jump to navigation Jump to search

Overview

All of these steps are performed locally.

Prerequisites

I didn't realize this at first, but these prerequisites are all local. The first time I tried this out, I thought I had to get on a remote server to install Python, Django, awsebcli, etc. All of these things are installed on the local workstation and eb deploy handles moving them over and replicating the app environment.

AWS Elastic Beanstalk

Existing Elastic Beanstalk applications and environments can be found in the AWS Elastic Beanstalk management console.

Create a ne Elastic Beanstalk application from the command line one a local workstation,

$ eb init

This will prompt for region, credentials, application name, python version, ssh availability, etc.

These properties are stored in .elasticbeanstalk/config.yml which should not be added to Git.

Create a new Elastic Beanstalk environment from the command line on a local workstation.

$ eb create --database.engine postgres

This will prompt for the environment name, its URL prefix, and a database username and password.

The --database.engine argument is optional. I was running into the problem of the RDS instance not being created when the environment was created. This option fixed that issue, but since getting a working version of the site I have not confirmed that the --database.engine option is essential to creating the RDS instance.

Deploying a Django app

Updates to the app are deployed with eb deploy.

This looks at .elasticbeanstalk/config.yml for the target application and environment.

branch-defaults:
  master:
    environment: nrose-env
global:
  application_name: north-rose
  default_ec2_keyname: nrosedevs-aws
  default_platform: 64bit Amazon Linux 2015.09 v2.0.6 running Python 3.4
  default_region: us-west-2
  profile: eb-cli
  sc: git

With the master Git branch checked out, and the config.yml above, eb deploy will package up the project file and upload them to the EC2 instance corresponding with the nrose-env environment of the north-rose app.

To update a staging environment, edit config.yml with the following:

branch-defaults:
  master:
    environment: nrose-env
  staging:
    environment: nrose-staging
  staging-nodebug:
    environment: nrose-staging

With the staging Git branch checked out, eb deploy will now update the nrose-staging environment.

Alternatively, use eb deploy alternate-env to target a non-default EB environment named alternate-env.

Installing Django app dependencies

See Defining Django App Dependencies

Production environment project settings

Set DEBUG to False:

# myapp/settings.py
# ...
DEBUG = False

With DEBUG = False, ALLOWED_HOSTS is required. [1]

Add localhost, the domain of the site, Elastic Beanstalk, and AWS's Elastic Load Balancer to ALLOWED_HOSTS:

# myapp/settings.py
# ...
DEBUG = False

ALLOWED_HOSTS = [
    "localhost",
    "mydomain.com",
    ".us-west-2.elasticbeanstalk.com",
    ".compute-1.amazonaws.com" # allow viewing of instances directly
]

# Grant access to AWS's Elastic Load Balancer
import requests
EC2_PRIVATE_IP = None
try:
    EC2_PRIVATE_IP = requests.get('http://169.254.169.254/latest/meta-data/local-ipv4', timeout=0.01).text
except requests.exceptions.RequestException:
    pass

if EC2_PRIVATE_IP:
    ALLOWED_HOSTS.append(EC2_PRIVATE_IP)

It's necessary to install python-requests for the above code. (pip install requests).

Configuring an independent RDS instance

See Using Elastic Beanstalk With Amazon RDS

  1. In the Amazon RDS Management Console, create a new RDS instance. [2]

Serving static files using Amazon S3

Notes

See also

References

  1. ALLOWED_HOSTS - Django documentation
  2. Launching and Connecting to an External RDS - AWS Elastic Beanstalk Developers Guide