freedomvote / ansible-django-stack

Ansible Playbook for setting up a Django app with Nginx, Gunicorn, PostgreSQL, Celery, RabbitMQ, Supervisor, Virtualenv, and Memcached. A Vagrantfile for provisioning a VirtualBox virtual machine is included as well.
MIT License
0 stars 0 forks source link

ansible-django-stack

Ansible Playbook designed for environments running a Django app. It can install and configure these applications that are commonly used in production Django deployments:

Default settings are stored in roles/role_name/vars/main.yml. Environment-specific settings are in the env_vars directory.

A certbot role is also included for automatically generating and renewing trusted SSL certificates with Let's Encrypt.

Tested with OS: Ubuntu 14.04 LTS x64

Tested with Cloud Providers: Digital Ocean, Amazon, Rackspace

Getting Started

A quick way to get started is with Vagrant and VirtualBox.

Requirements

The main settings to change here is in the env_vars/base file, where you can configure the location of your Git project, the project name, and application name which will be used throughout the Ansible configuration.

Note that the default values in the playbooks assume that your project structure looks something like this:

myproject
├── manage.py
├── myapp
│   ├── apps
│   │   └── __init__.py
│   ├── __init__.py
│   ├── settings
│   │   ├── base.py
│   │   ├── __init__.py
│   │   ├── local.py
│   │   └── production.py
│   ├── templates
│   │   ├── 403.html
│   │   ├── 404.html
│   │   ├── 500.html
│   │   └── base.html
│   ├── urls.py
│   └── wsgi.py
├── README.md
└── requirements.txt

The main things to note are the locations of the manage.py and wsgi.py files. If your project's structure is a little different, you may need to change the values in these 2 files:

Also, if your app needs additional system packages installed, you can add them in roles/web/tasks/install_additional_packages.yml.

I set some default values in the env_vars based on my open-source app, YouTube Audio Downloader, so all you really have to do is type in this one command in the project root:

vagrant up

Wait a few minutes for the magic to happen. Access the app by going to this URL: http://192.168.33.15

Yup, exactly, you just provisioned a completely new server and deployed an entire Django stack in 5 minutes with two words :).

Additional vagrant commands

SSH to the box

vagrant ssh

Re-provision the box to apply the changes you made to the Ansible configuration

vagrant provision

Reboot the box

vagrant reload

Shutdown the box

vagrant halt

Security

NOTE: Do not run the Security role without understanding what it does. Improper configuration could lock you out of your machine.

Security role tasks

The security module performs several basic server hardening tasks. Inspired by this blog post:

Security role configuration

Running the Security role

ansible-playbook -i development security.yml

Running the Ansible Playbook to provision servers

NOTE: to enable the Security module you can use the steps above prior to following the steps below.

Create an inventory file for the environment, for example:

# development

[all:vars]
env=dev

[webservers]
webserver1.example.com
webserver2.example.com

[dbservers]
dbserver1.example.com

Next, create a playbook for the server type. See webservers.yml for an example.

Run the playbook:

ansible-playbook -i development webservers.yml [-K]

You can also provision an entire site by combining multiple playbooks. For example, I created a playbook called site.yml that includes both the webservers.yml and dbservers.yml playbook.

A few notes here:

You can then provision the entire site with this command:

ansible-playbook -i development site.yml [-K]

If you're testing with vagrant, you can use this command:

ansible-playbook -i vagrant_ansible_inventory_default --private-key=~/.vagrant.d/insecure_private_key vagrant.yml [-K]

Using Ansible for Django Deployments

When doing deployments, you can simply use the --tags option to only run those tasks with these tags.

For example, you can add the tag deploy to certain tasks that you want to execute as part of your deployment process and then run this command:

ansible-playbook -i stage webservers.yml --tags="deploy"

This repo already has deploy tags specified for tasks that are likely needed to run during deployment in most Django environments.

Advanced Options

Using Python 3.5

Python 3.5 is already installed and to use this version in the virtualenv, just override the value of the virtualenv_python_version variable in roles/web/defaults/main.yml.

Creating a swap file

By default, the playbook won't create a swap file. To create/enable swap, simply change the values in roles/base/vars/main.yml.

You can also override these values in the main playbook, for example:

---

...

  roles:
    - { role: base, create_swap_file: yes, swap_file_size_kb: 1024 }
    - db
    - rabbitmq
    - web
    - celery

This will create and mount a 1GB swap. Note that block size is 1024, so the size of the swap file will be 1024 x swap_file_size_kb.

Automatically generating and renewing Let's Encrypt SSL certificates with the certbot client

A certbot role has been added to automatically install the certbot client and generate a Let's Encrypt SSL certificate.

Requirements:

In roles/nginx/defaults.main.yml, you're going to want to override the nginx_use_letsencrypt variable and set it to yes/true to reference the Let's Encrypt certificate and key in the Nginx template.

In roles/certbot/defaults/main.yml, you may want to override the certbot_admin_email variable.

A cron job to automatically renew the certificate will run daily. Note that if a certificate is due for renewal (expiring in less than 30 days), Nginx will be stopped before the certificate can be renewed and then started again once renewal is finished. Otherwise, nothing will happen so it's safe to leave it running daily.

Useful Links