Cryptocracy

A blog

Cookbook Reusability In Practice

I recently attempted to use Chef to configure several VMs with software I wanted to play with. My goal only went as far as provisioning a minimally useful instance of each application – it didn’t need to be production-ready, but it did need to start.

The applications were:

  • Jenkins, a CI tool written in Java,
  • Graphite, graphing tool written in Python, and,
  • Sensu, a monitoring tool written in Ruby.

Additionally, Sensu requires:

  • RabbitMQ, a message broker written in Erlang, and,
  • Redis, a key-value store written in C.

None of the dependencies are particular esoteric in a modern environment, though the variety seen here underscores the need for good configuration management. The guest OS was Ubuntu 12.04, as many community-contributed Chef cookbooks prefer or require Ubuntu and I wanted things to proceed as smoothly as possible.

IPsec/L2TP VPN server with Ubuntu 12.04

In an earlier post describing my PPTP VPN configuration, one reason I gave for my use of the (relatively) insecure protocol was that the IPsec alternative appeared to require building updated versions of the software. I’m delighted to report that that’s no longer the case.

The versions of openswan and xl2tpd shipping with Ubuntu 12.04 (precise) are more recent than those mentioned in the elderly walkthroughs I’d found, and have worked for the OS X clients I’m using.

Bootstrapping Chef with ubuntu-vm-builder

It’s very easy to configure a machine as a KVM host these days. Modern releases of Ubuntu and Centos both offer simple installation methods that provide a useful system with minimal configuration.

Creating guests is a different story. A number of good tools are available, supporting a huge variety of installation scenarios. While it’s reassuring to know you won’t be limited by your tools, it can be a frustrating experience when you’re just getting started.

This post shows how ubuntu-vm-builder can be used to go from zero to fully-installed Chef client in under 2 minutes.

Setting up a PPTP VPN

First things first: PPTP, as a protocol, has a number of serious security issues. As a general rule, don’t use it. I’m aware of the risks, and am accepting them for this implementation.

PPTP’s main advantage is that it’s very easy to configure. I briefly investigated the state of IPsec/L2TP, and found a lot of advice to build things from source because the distro packaged versions are too old. That’s fine advice, but I wanted to get something started quickly. Once I’ve built a build box, I’ll be revisiting this decision.

A Dedicated Server

We’ve been building out a new development environment at work – virtualised using KVM, and managed with Chef and MCollective. It has made it so easy to try out new things that I found myself wishing I had the same facilities for my own projects.

An article on Hacker News had me taking another look at Hetzner, which was followed a few days later by an order for a dedicated server with a quad-core i7, 32GB memory, and a pair of 3TB SATA disks. Hetzner gets mixed reviews, but the negatives weren’t enough to put me off – the prices are good, and I’m not planning to host any critical services. I’ll try not to complain when I get what I pay for.

The rest of this post describes the initial configuration of the server for use as a KVM host.

Chef LWRP - managed_directory

A common configuration management pattern is to generate snippets of configuration into a “.d” directory, which are subsequently compiled into a complete configuration – either by a script, or through support from the application itself.

This pattern works well when you’re maintaining a set of snippets, or adding to it, but removing snippets from the set can present a challenge. If you need to specifically remove a snippet from a node, you can always use the File resource with action :delete to do so. But what do you do if you don’t know which snippets need to be removed?

Starting over with Emacs

Starting

I switched to Emacs sometime in 2009. At the time, I was using TextMate most of the time (though diving frequently into vi, as befitting my background as a system administrator). There wasn’t any singular event that drove me to try out Emacs, but I do remember being frustrated by TextMate’s performance with a particularly large project at work. I’d noticed Emacs-using colleagues having a much better time of things, and some stories about Emacs on Hacker News had piqued my interest.

The learning curve was initially quite steep, which presented something of a challenge – I needed to use the tool to get work done, and couldn’t afford to significantly slow myself down for an unknown period. I bought PeepCode’s “Meet Emacs” screencast to see a quick introduction to the essential features, and get a handle on my ignorance. It’s important to know what you don’t know, and the screencast helped me reach “conscious competence” quickly enough to stick with it.

Following the advice in “Meet Emacs”, I used the Emacs Starter Kit for my initial configuration. It was awesome. More awesome than I could comprehend; despite spending time poking around the contents of my new ~/.emacs.d, only the most superficial aspects of the configuration made much sense. I had an editor that was powerful and feature-rich, but the much-vaunted malleability of the Emacs environment lay beyond my grasp.

Fortunately, my earlier switch to OS X had brought with it a certain serenity in the face of technology. If an opinionated application (or OS) does what you want, most of the time, it’s worth going along with it in the places you disagree. That this is largely antithetical to the Emacs view of the world is not lost on me.

So, I spent my first couple of years with Emacs using a barely-customised ESK configuration, and I was pretty happy with it. While missing some of vi’s functionality, I choose not to install any vi-compatibility features. The lynch-pin of my commitment turned out to be magit, the excellent git mode for Emacs. Having become accustomed to such seamless interaction with my VCS, I can no longer imagine working without it.

Restarting

Though I was largely happy with the end result, the amount of magic (or sufficiently advanced technology) bothered me. Nor was this entirely academic – I had been putting up with a bunch of quirks I was sure could be fixed, if only I knew how. Last week, I came across the article that helped me start down that road.

“Emacs Configuration Rewrite” documents Steven Danna’s experience rebuilding his Emacs configuration from scratch. The result is positively minimalist alongside ESK, and lacks many features and customisations the latter delivers “out of the box”. I decided that probably didn’t matter to me – after all, if I missed something enough to add it back in, that would simply drive me to learn how to do that. Above all else, Steven’s configuration showed me that I could start out with something I could comprehend completely, and expand from there. So that’s what I did.

The initial commit to my emacs configuration repo doesn’t tweak anything – it simply introduces the skeleton that everything else hangs off. I’ve added one thing at a time as I’ve needed it, and understood it. That’s not to say it’s entirely (or even mostly) original work – I’ve picked things up from various places, but they only go into my config when I understand what they do. No blind copy-and-paste, no cargo cults.

Emacs makes this exercise pretty easy. The built-in help can give you the value and meaning of any variable (C-h v), and the documentation for any function (C-h f). For anything implemented in elisp (and that’s nearly everything), you can even jump straight to the source. This was way too much to deal with when I first started using Emacs, but I regret leaving it so long to come back to it.

The Future

I don’t like unnecessary wheel reinvention. My goal is to understand how things fit together, that I might change them according to my needs – I don’t feel that meeting that goal demands personally entering every single sexp into my Emacs configuration.

The Emacs Starter Kit has evolved considerably since I made a personal fork in 2009, and I made no attempt to evolve my forked configuration with it. It contains lots of good stuff, and I’ve started to look more closely at exactly how it’s put together. As my understanding grows, I expect to be able to reuse larger pieces of elisp (from ESK and elsewhere) without feeling that my configuration is outgrowing my competence.

I may move to an ESK-based configuration again in the future, and I’m glad I used one in the past. In the present, I’m appreciating a greater understanding of a smaller set of features.

Migrating to Octopress

As may be obvious from the new look, this site is now running on Octopress. Migrating from Posterous wasn’t especially traumatic, but the paucity of content helped in that regard.

Importing from Posterous

Jekyll ships with an importer for pulling content out of Posterous, but it no longer works after the latter changed their API. There’s a fix, but wasn’t in a released version when I needed it.

With the update, the importer appeared to do a reasonable job of importing my posts (although it failed to set published: false on my drafts). One caveat: the date used is the creation date, not the publish date, of the source posts.

The importer didn’t grab any of the “pages” on my Posterous site, but I chose to recreate the “About Me” page in markdown rather than determine whether this was intended behaviour.

I manually converted my posts and drafts into markdown, so let me know if you notice any errors.

Publishing

The site is now hosted on GitHub pages, backed by a private repository. This works well enough, although it doesn’t appear to be possible to assign two custom hostnames for the same site. I’d like to migrate from “www.cryptocracy.com” to “cryptocracy.com”, so a further hosting change is on the cards.

Using MCollective with Chef

MCollective is a Ruby framework “to build server orchestration or parallel job execution systems”. Using messaging middleware (currently STOMP) for communication, a server running on each node can announce its existence, receive requests, and respond with structured data. Writing clients and agents is a straightforward exercise – while you’ll need to know enough Ruby to implement your desired functionality, the framework itself adds little complexity. A number of non-core plugins are available on github.

Although it often seems that MCollective goes hand-in-hand with Puppet, there’s no technical limitation behind this. It can quite readily be used with any other configuration management tool, or none at all. The plugins supporting integration with Puppet may be a little more mature today, but users of Chef won’t be missing out on anything.