In Django, Python, Amazon Web Services - 5 months, 4 weeks ago

Deploy your Django applications to AWS Elastic Beanstalk

Jack and the Beanstalk

Introduction

AWS Elastic Beanstalk is a PaaS (Platform As A Service) offered by Amazon Web Services for deploying and managing web applications.

It allows you to deploy your applications quickly to the cloud while letting you retain full control over your AWS application resources.

A great benefit of deploying your applications using AWS Elastic Beanstalk is that it leverages on core AWS services such as EC2, ECS, RDS, Auto Scaling and Elastic Load Balancing to streamline your setup.

Requirements

  • Python v3.7.2
  • Django v2.1.5
  • AWS Elastic Beanstalk
  • PostgreSQL
  • awsebcli v3.14.11

Initial setup

  1. Clone this boilerplate from the Create a Simple Django Boilerplate tutorial to your desktop
$ git clone https://github.com/Papagoat/Create-a-Simple-Django-Boilerplate.git

 

  1. Cd into the project folder and set up venv
$ cd Create-a-Simple-Django-Boilerplate/demo
$ python3 -m venv myvenv
$ source ./myvenv/bin/activate

 

  1. Install pip if you haven't already
  2. Install Django and the Postgres client
$ pip install django
$ pip install psycopg2

 

  1. Install the CLI. This is a tool to help with deploying and managing your AWS Elastic Beanstalk application.
$ pip install awsebcli

 

  1. Save our dependencies in requirements.txt.
$ pip freeze > requirements.txt

 

  1. Log in or Register for an account with AWS. 

AWS Identity and Access Management

To configure the application and environment, we need to set up an IAM user.

The new user needs to have the appropriate permissions to access the AWS Elastic Beanstalk application.

The simplest way is to search for the "AWSElasticBeanstalkFullAccess" policy in the IAM Policies console and attach it to the user or group.

See this guide on how to use Elastic Beanstalk with AWS IAM.

Avoid using the root user credentials to perform everyday AWS tasks. Create individual users with different permission settings in the IAM console instead.

See this guide on how to create your first IAM admin user and group.

Configure your AWS Elastic Beanstalk application

We are ready to roll! First, we need to create and configure our AWS Elastic Beanstalk application. Cd into the project folder and run this command.

$ eb init

 

Select a default region

For best performance, choose a region closest to your intended audience.

Application Name

Leave it as default.

Select a Python version

For this tutorial, we will use the default Python EC2 image. (Option 1)

SSH

Type "y" to set up SSH. We will be using SSH to create our admin user and perform database migrations later.

RSA Keypair name

Leave it as default.

 

After we have configured the application, we see a hidden .elasticbeanstalk folder inside the demo folder.

Open .elasticbeanstalk/config.yml to view the different parameters.

branch-defaults:
  default:
    environment: null
    group_suffix: null
global:
  application_name: demo
  branch: null
  default_ec2_keyname: aws-eb2
  default_platform: Python 3.6
  default_region: ap-southeast-1
  include_git_submodules: true
  instance_profile: null
  platform_name: null
  platform_version: null
  profile: eb-cli
  repository: null
  sc: null
  workspace_type: Application

 

Create an AWS Elastic Beanstalk environment

Run this command to create an environment for our application.

$ eb create testENV --database.engine postgres

 

Why not just $ eb create testENV?

If we run $ eb create testENV without creating the postgres RDS database now, we may encounter a failure later on.

This appears to be a bug with AWS.

Note down the RDS DB username and password. We need it shortly. Once completed,  AWS Elastic Beanstalk will create the environment automatically.

It's a good time to grab a beer as this may take a while.

 

Once the process has completed, run the following command to access the dashboard.

$ eb console

Our testENV dashboard overview. 

 

You may encounter an error that says "Your WSGIPath refers to a file that does not exist."

To fix that, let us change the WSGIPath in AWS Elastic Beanstalk's global configuration.

$ eb config

 

Scroll to the bottom where it says WSGIPath: application.py and change it to WSGIPath: demo/wsgi.py.

Hit CTRL + X to save your changes and wait for the environment to update.

We need to add our application URL to the ALLOWED_HOSTS setting. You can locate the URL from the top right corner of the application dashboard.

 Add the URL to ALLOWED_HOSTS in demo/settings.py

...
ALLOWED_HOSTS = [
    'your-application-url'
]
...

Configure the database

  1. Click on 'Configuration'.

  1. Scroll to the bottom until you see 'Database' and click on the endpoint link.

  1. Access the DB instance and copy the endpoint URL.

  1. Edit demo/settings.py with the new database details. Replace the 'USER' and 'PASSWORD' values with the RDS DB username and password that we created earlier. Replace 'HOST' with the endpoint URL.
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.postgresql_psycopg2',
        'NAME': 'postgres',
        'USER': 'your-db-username',
        'PASSWORD': 'your-db-password',
        'HOST': 'your-db-endpoint',
        'PORT': '5432',
    }
}

When we create an AWS Elastic Beanstalk environment, AWS sets the database name as postgres by default. See this guide on how to rename a DB instance.

  1. Specify a STATIC_ROOT in demo/settings.py for static files collection.
# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/2.1/howto/static-files/
STATIC_ROOT = os.path.join(BASE_DIR,'static')
STATIC_URL = '/static/'

 

  1. Collect static files and deploy the changes to our instance.
$ python manage.py collectstatic
$ eb deploy

AWS Elastic Beanstalk will look for the requirements.txt file and install the dependencies automatically whenever we deploy our code. Very cool! 

Create model tables in the database and admin credentials

We have to create our model tables for the application to work. We do that by connecting to our instance via SSH.

Run this command in our terminal.

$ eb ssh

 

Ignore the warnings and continue. We can now access the files on the AWS Elastic Beanstalk instance. 

We are going to

  1. activate the virtual environment.
  2. run the migrate command.
  3. create an admin user. (Note down the username and password)
$ source ../../opt/python/run/venv/bin/activate
$ cd ../../opt/python/current/app
$ python manage.py migrate
$ python manage.py createsuperuser

If you encounter permission errors, try adding sudo to the command. E.g. $ sudo python manage.py migrate.

In an actual live production environment, you should configure IAM permissions instead.

Exit from SSH and launch the application in the browser.

$ exit
$ eb open

Awesome!

Test the application

  1. Access our Django admin page by appending /admin/ to the instance URL.
  2. Log in using the new admin credentials.
  3. Create a dummy post and SAVE.

  1. Verify that the dummy post displays correctly.
$ eb open

Conclusion

Although this tutorial is a contrived example, it shows the ease of deploying Python applications or any web applications for that matter using AWS Elastic Beanstalk.

In a real-world situation though, we would secure the database using environment variables and leverage on AWS CodeCommit as our code repository. We would also write AWS Elastic Beanstalk configuration files and Django custom management commands to streamline the deployment further!

It may seem confusing if this is your initial foray into AWS. As you begin to understand how all the different parts fit together, you will find that deploying and managing your applications in AWS Cloud is actually pretty straightforward.


blog comments powered by Disqus