Wellfire Interactive // Expertise for established Django SaaS applications

Configuration management when your Django app is already deployed (This Old Pony #27)

Do you know how to install and setup your Django app? If you needed to toggle a setting in an auxiliary service would you risk leaving that setting in place?

Of course not. _Your _application has a documented, reproducible build process. Whether it’s PaaS-based or running on a fleet of self-managed AWS services, a combination of scripts and declarative files which govern how the application - and components - are set up[0]

What if you didn’t have a documented, reproducible build process? What would it look like to set it up again?

Without configuration management

Source-managed configuration and automation are both critical even if for any reason you don’t make much use of either on a day to day basis.
 

The costs of going without

Written documentation about how to install and setup a web application is helpful but insufficient. It puts the onus on a human being to perform critical, sequential steps which can be repeated by a computer program.

This increases the ramp up time for new developers by a significant margin. It also increases the risk of differing environments since it pushes the responsibility for configuration _decisions _about individual copies of the environment to individual developers.

The big reason is that decreases the testability of the system as a whole. If you can’t create production like environments then you’ll forever be testing on a mock up of a simulacrum.

And critically, since we’re talking about existing Django apps and legacy systems, it takes away the power of way points for change. It’s rather difficult to move ahead if you can’t fix where you started from.
 

The governing principle of ex post facto configuration management

Configure your environment as it is.

This is your goal when you start out. Before you start making changes, make a map of what you have in such a way that it effects no changes at all.

Let’s say you want to start running Daphne[1] for your Django app. This is going to mean changing some of the deployed scripts and perhaps some Nginx configuration.

In the absence of any configuration you have no way of testing out this change _exactly _or of neatly reverting the changes. You’d be stuck between an old ad hoc configuration and some very risky business.

So if you were starting with Ansbile, for example, you’d start building a playbook that does some incredibly basic things and then verifying that when applied these have no effect.

  1. Ensure the web server is installed (check)
  2. Ensure the directories the web server configuration needs are present (check)
  3. Ensure the web server configuration files match the files in your app configuration by first downloading them so that the file content hashes match exactly (check)  With each tiny change you apply (preferably first with an option to check the execution without applying) and ensure that what is present in your deployed environment matches what is in your application’s managed configuration - even if you’re working backwards.
     

    What about PaaS?

    The good news if you’re running your application on a PaaS (e.g. Heroku) is that by leaning on buildpacks you already have most of the deployed configuration management in place _or _don’t have to worry about it.

Instead you’ll be concerned with porting your Django application from one environment to another or matching a dev environment to production.

There are several approaches you can take.

To start with, make use of any PaaS-native configuration management, e.g. Heroku’s app.json file which can be used to specify add-ons and environment variables.

Secondly, you can make judicious use of containers. An end goal might be to work with deployed containers, but even short of this using a Dockerized dev environment while running your application directly on the PaaS environment (which, yes, is still containerized) is a step in the right direction[2].

Ensure that the author is signed off,
Ben

[0] Ansible is our example here _not _because it’s written in Python but because for most use cases it’s mostly-declarative YAML syntax is easy to work with and the SSH based execution model scales up and down. If you’re shopping around based on my opinion I have no used SaltStack, think highly of Puppet’s declarative model although working with modules can get complex very fast, and Chef’s Ruby DSL is unappealing. See http://docs.ansible.com/http://docs.ansible.com/
[1] Daphne https://github.com/django/daphne/
[2] Docker/containers are not a strict substitute for configuration management. In many cases these tools (e.g. Ansible) will be used for orchestrating the containers, even if they’re not used for managing the structure of their contents.

Learn from more articles like this how to make the most out of your existing Django site.