Thursday, February 22, 2018

Serverless Django

Introduction


In the last few years, since around 2016, there’s a concept that’s been gaining popularity. This concept is known as “Serverless Infrastructure”.

Having a serverless infrastructure allows you to have a project running live, but without any permanent infrastructure. This means that when no requests are arriving for the server, there will be no servers actively running. When a request is received, the server will turn on, answer the request, and then shut down.

This serverless approach has one big benefit: server resources will only be in use while they are required, leaving in the past the problem of idle servers.

Providers


Nowadays there are different cloud providers that support this kind of infrastructure. Some of the most popular are:

This tutorial will focus on AWS as it is one of the most widely used cloud providers in the world.

AWS provides serverless capabilities through one of their services called Lambda. Quoting AWS Lambda description:

AWS Lambda lets you run code without provisioning or managing servers. You pay only for the compute time you consume - there is no charge when your code is not running. With Lambda, you can run code for virtually any type of application or backend service - all with zero administration. Just upload your code and Lambda takes care of everything required to run and scale your code with high availability. You can set up your code to automatically trigger from other AWS services or call it directly from any web or mobile app.

Quite cool, right? Especially these two aspects:

  • Takes care of running and scaling your code (no need to worry about the horizontal scale, Lambda has that covered).
  • Only pay for what you use (save money by only paying for actual usage, no usage, no charge).

Frameworks


Regarding deploying Django apps with a serverless infrastructure, there are two big players that can help us:




Both frameworks are up to the task, but 'Zappa' is focused on serverless Python, while 'Serverless' allows you to deploy code of several programming languages like Node, Python, Java, PHP, among others.

For this tutorial, we will use Zappa for its simplicity and because it’s python focused.

Getting started




First, we need to make sure we have an AWS account with root access. If you don’t have an account with that level of permissions you will need to create an IAM user with programmatic access that has permissions to the following services:


  • Cloud Formation
  • IAM
  • Lambda
  • S3
  • API Gateway
  • CloudWatch
  • Other services you would want to use

There is currently an open task in Zappa for a proper definition of the permissions needed. In the meanwhile, there are two approaches you can take: be flexible with the permissions or do some trial and error until reaching the minimal permissions you need for your app. It’s recommended to remove the IAM permission after Zappa creates the user the first time.

After the user is ready, make sure you have the proper awscli configuration, you can find quite a good guide on the Serverless page.


The Project


We will be deploying a simple project that was developed for this tutorial. The project itself is not really important, so please focus on learning how to add Zappa support to an existing Django project. The project can be found here.


First of all, let’s install the project:



#git clone https://github.com/innuy/innuy_lambda #pip install -r requirements/dev.txt


** You will have to create a bucket to locate your sqlite database, then update the database settings

Then let’s create a configuration file using the following command:


# zappa init


After running that command you'll be asked a few questions. I recommend you leave everything as default if it’s your first time.

A file called “zappa_settings.json” should have been created. It will look something like this:


{
"dev": { "aws_region": "us-east-1", "django_settings": "innuy_lambda.settings.dev", "profile_name": "default", "project_name": "innuy-lambda", "runtime": "python3.6", "s3_bucket": "bucketname" } }


Zappa has many additional configuration settings. If you need something more specific, please take a look at the documentation for more advanced use cases.

Let’s now run the following command to upload our code to Lambda:

# zappa deploy

If the deployment process succeeds you should see an url like this:


If you add “/admin” to the url the result is:


You should be taken to the django admin… but static files are missing!

We can solve this by setting a few variables in the dev settings file (or you can do it by env variables in zappa). In this case just set the bucket where you want the statics files to live (if you don’t have a bucket, you can create one with a wizard in AWS S3):

AWS_STORAGE_BUCKET_NAME = 'innuylambda-static'


Then update the code in lambda using:


# zappa update


Now lets collect the static files:

# zappa manage dev "collectstatic --noinput"

You should now see the admin perfectly. You can try creating a user by running the project locally and running the createsuperuser command from manage.py.

Your app should be running completely serverless!!

To undeploy run the following command:


# zappa undeploy


And everything is off (the buckets are still there though).

Deploying a Django project in Lambda using Zappa is quite easy. 

I recommend you to try it out!