Django Simplifying Life
At Contegix (where I work for those that haven’t been following along) I often have to deploy versions of Atlassian Applications, primarily JIRA and Confluence. I have scripts that handle the vast majority of the deployment written in BASH. These scripts allow me to deploy a new application in under 3 minutes while sticking to all our standards. It creates a new Tomcat container, places the servic
e in daemontools, creates the virtual hosts, and so on and so forth. The end result is an enterprise ready instance of Confluence or JIRA in a mere matter of minutes.
However, that’s not quite ‘easy’ enough for me. I wanted something even easier that requires even less effort from me. Ideally, complete automation from order to installation is the goal, but we’re not quite that far yet. I wanted to reduce the barrier to entry to the scripts I currently use to create a new instance. Formerly what you had to do was the following:
- Log into the app server
- Run the application creation script answering all of the prompts
- Log into the database server
- Run the script for the database creation
It really wasn’t a pain, but it effectively made performing a brand new installation automatically impossible. I was going to have to come up with a new method if I wanted to dramatically reduce the barrier to entry for making new deployments. Granted, our engineers, who are all fully capable of performing these steps, always perform the deployments and that will likely continue to be the case. However, like I said, I was hoping for full automation at some point.
The problem was finding a method of pulling this off. Asking any non-linux geek to SSH into a server, and run some scripts, sounded like an absolutely terrible idea. I don’t know what it is, but the command line still seems to terrify people these days. What doesn’t scare people, even though it really should, is using a web browser. So, I’ve been playing with Django quite a bit lately, and I have a significant love for Python.. I decided to see if it was plausible to put this all together for something a bit easier for the less geeky to be able to pull off these deployments. Here’s how I broke it down:
- Django with the admin interface to fill out a simple form to create a new instance. Fill out the form, click save, deployment happens during the pre_save signal
- Save was clicked, and a call goes out to an XMLRPC server (crafted in Python via about 5 lines of code) on the db node
- Database Server’s XMLRPC server runs a simple bash script to craft a database ready for our application
- Database server was succesful, and a call goes out to an XMLRPC server (crafted in Python via about 5 lines of code) on the app node
- A couple hundred line BASH script is executed to perform the actual deployment
- The bash script fires off another python script at the end to update documentation in our personal Confluence instance (Automated documentation ftw!)
- Email is fired off to support to complete the process of creating a monitor for the site (later to be scripted, and thus automated)
- We enter post_save, and commit the new instance to the Django database for record keeping. The instance is also set to ‘Deployed’, so that it doesn’t get redeployed on accident later.
Obviously there are more moving parts than there is in the manual method. I get that, I really do. On the upside, it’s roughly just as fast as doing it by hand if not faster. Also, the human element, assuming no typos in the form, is all but completely removed. All that needs to be done is a simple form is filled out in the administration interface of Django, you click save, and then go check out your new instance a minute or so later.
The best part was that I found methods to lock it all down pretty well too. The XMLRPC servers will only accept connections from 1 IP address via firewall rules. The XMLRPC instances are also ran as non-privileged users who can essentially do no harm. The reason I chose XMLRPC is that I really, really, really wanted to avoid having to dig into expect. I dig the Python PSSH module, but that method just never seems as stable. A nice offset of the django integration is that I also have a long term record of deployed instances as well. I can display that information via a variety of different means for record keeping later if necessary.
The whole project isn’t quite done yet, and there’s a ton of stuff I can do to streamline the application still. However, I’ve spent roughly 4 hours on the Python sections of the application. The toughest parts being the BASH script, and fighting permissions made up the rest of the time. Hell, the deployment script was probably closer to 8-10 hours of work if not more, but thankfully that was done many moons ago. Anyways, just thought I’d share my triumph. If you have any questions feel free to e-mail. I’d be happy to answer any questions you might have!