Deploy Django to AWS Lamda with Zappa
Tags: aws, django, lambda
Published: 2020-10-09 22:28:44

Originally posted at https://emilpriver.com/posts/deploy-django-to-aws-lamda-with-zappa

## Information
Django is a popular CMS for building a website. Many companies and people use Django to power big APIs for their services, Ex Instagram. This article helps you as a developer to set up Django on AWS Lambda.

### Django
Django is a python based web application framework that comes with a lot of stuff out of the box, ex Security or Object-relational mapping. Django’s main goal is to ease the creation of complex, database-driven websites. Django is a popular framework used by many computes, for example, Instagram. Django is maintained by DSF (Django Software Foundation).

### What is AWS Lambda
AWS Lambda is serverless(Function as a service) computing and makes you able to run code without thinking about servers and downtime. Pretty much deploy code to AWS Lambda with a small config and you are ready to use it. More info about AWS Lambda here: https://aws.amazon.com/lambda/.

### Zappa
Zappa is a Python package that bundles up your code written in Django or Flask and with a command deploys the package to AWS Lambda and handling everything from creating a zip of your code to deploy it to Amazon S3 and then to AWS Lambda. Zappa only requires an AWS config on the machine that is used to deploy the code.

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/0vsa7z03492okbmjr7ip.gif)

## What you need to get started
* Python installed on your computer (https://www.python.org/downloads/)
* Virtualenv installed (https://docs.python.org/3/library/venv.html)
* Have AWS CLI configured on your computer with a profile that is allowed to configure Lambda and S3 ( https://docs.aws.amazon.com/cli/latest/userguide/cli-chap-configure.html)
* A Django application ready to use (https://docs.djangoproject.com/en/1.8/intro/tutorial01/)

## Beginning
Start off by entering a virtualenv and enter it. Then install all needed packages.

```
vitualenv venv
source venv/bin/activate
```

Then run
```
zappa init
```
Zappa will then ask you for an environment name. Example production or dev. Those environments are you then able to use in a CI/CD or something similar to test your code.

```
Your Zappa configuration can support multiple production stages, like 'dev', 'staging', and 'production'.
What do you want to call this environment (default 'dev'): 
Answer with your desired environment name. You will be able to add more environments later on.
```

Zappa will then ask you for the profile that will be used to push and deploy the lambda function. The profile needs to be the profile that is allowed to create lambda functions and upload to and create an S3 bucket.

```
AWS Lambda and API Gateway are only available in certain regions. Let's check to make sure you have a profile set up in one that will work.
We found the following profiles: default, and hdx. Which would you like us to use? (default 'default'): 
Zappa will now ask you which S3 bucket that will be used to upload your code and then deploy it to lambda.
```

Your Zappa deployments will need to be uploaded to a private S3 bucket.

```
If you don't have a bucket yet, we'll create one for you too.
What do you want call your bucket? (default 'zappa-108wqhyn4'): django-zappa-sample-bucket
Answer with the name of the bucked you will use.
```

The next question will either be that Zappa asks for the Django settings path or the main function path depending on if Zappa finds a Django installation in the folder you typed "Zappa init" in. If Zappa doesn't find a Django installation is it not a big deal, you can change to Django set up after the "Zappa init" questions is finished. If Zappa doesn't find a Django installation then type the path to your Django main settings file.

The next questions will be if you want to deploy this Lambda function worldwide.

``` 
If you are using Zappa for the first time, you probably don't want to do this!
Would you like to deploy this application globally? (default 'n') [y/n/(p)rimary]: 
If the config looks good then press y and Zappa will generate a Zappa_settings.json file.
```

If Zappa didn't find a Django installation then change "app_function" to "django_settings" in your zappa_settings.json file.

## Deploying your AWS Lambda function
Deploying your AWS Lambda function is not hard. You only need 1 command to deploy the code.

```
Zappa deploy $ENV
```

** $ENV **, in this case, is the environment you created earlier when running the Zappa init command.

Zappa will not make a zip of your code, Send it to s3, and then deploy it to AWS Lambda and return a URL with the deployed and running code. You can now try your code by accessing the full URL including /admin at the end (If you run you Django admin at /admin".

You will probably not be able to access your website as you need to configure a remote database as your code is running in a Lambda function. Connecting Django to a database as AWS RDS is a good move that will work with your Lambda Django code.


## Uploading updates of your Django code

Doing updates with Zappa is easy as you only need 1 command as well to deploy your code.

```
zappa update $env
```

$env is the environment name you want to update.
Zappa will not make a zip of your code, Send it to s3, and then deploy it to AWS Lambda and return a URL with the deployed and running code.

## Connect a custom domain to your AWS Lambda function
Start off by setting up a certificate for your custom domain at AWS Certificate Manager and verify your domain. You will, later on, use this certificate you created to connect to your API gateway. Now go you AWS API Gateway and create an API if Zappa has not created an API gateway for you. Now go to "Custom domain names" in API Gateway and press create. Add the domain you want to use. For example api.doimain.tld, and select TLS 1.2 and the endpoint type which depends on the settings you made when running "Zappa init" and press "Create domain name". You should now be able to see a generated "API Gateway domain name" which you point the domain to with a CNAME. Go to the tab "API mappings" and press "Configure API mappings" and map the paths you need for your application. For example /admin and /graphql.


If everything is set up correctly would you now be able to enter the domain with the added mapping and use it for your service.

## My thoughts on using Django with AWS Lambda.
Using AWS Lambda with Django has only been great for me so far. Its cheap, and fast. The startup time when the application goes from frozen to warm is fast as well. Most of the request I make is bellow 300ms when the function is warm and when the function is going from cold to warm are the requests served under 800ms. The current setup I have includes Lambda for running the code, RDS for database, and S3 with Cloudfront for all the media. What I like about Lambda is the part of not thinking about scaling and downtime as Lambda scale my application automatic and start my application if is stops(unless the downtime is caused by something else)

I am using a CI/CD which deploys my code to AWS Lambda and handles all the migrations. And if I need to roll back my code am I able to do that with Zappa as well. Zappa has thought of a lot of stuff, for example, CRON jobs(Zappa call CRON jobs "schedule"), Being able to roll back to older versions of the code, and more. More information and commands can be found here: https://github.com/Miserlou/Zappa.

The only "problem" I have with Zappa and AWS, in general, is that Zappa is building for AWS if I want to use most of the tools which Zappa gives me. For example rollback or schedule. And that I don't know a tool which works pretty much the same with another cloud platform example Google Cloud.

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/4wpr051vi1b0bk6ba4gq.gif)

Happy coding!

Twitter if anything: https://twitter.com/emil_priver