Saturday, February 25, 2012

War Story: The day I nearly invented server management

Long before I knew about puppet (or heard about chef via vagrant), I was working on a system with around 100 virtual hosts, nearly all of them configured from a small pool of standard features.  This made for a long, complicated vhosts.conf file, which we managed by keeping it in alphabetical order and using search a lot.  I realized that a lot of the duplication could be removed by generating it from a template file.

I spent an hour or two hacking together the necessary combination of $employer oriented interface in PHP and the smarty template that would generate the final vhost.conf file, and configured it to generate both our most frequent features ("this site has a gallery2 install at /gallery/") and our most complicated site, that of the main business, as a proof-of-concept.

I'm pretty sure the vhost configuration API, which was modeled on the ideas of a domain-specific language without going down that path, looked something like:
$vh->domain('example.org example.net example.com');
$vh->subdomain('example.com', 'nqn blog foo');
$vh->gallery('/gallery', 'example.net example.com');
$vh->webdav('/dav', 'example.org');
All of the feature methods added things in bulk, so the layout of the vhost-dsl would read something like "we have a whole ton of domains; we have a bunch of galleries; we have this webDAV user."  If we wanted to upgrade gallery2 on all sites using it, this also would give us a compact list of where those were installed.  The output of this process was a large hash, indexed by domain, so that the template then read something like:
<VirtualHost *:80>
  ServerName {$domain.name}
  ServerAlias www.{$domain.name}
  DocumentRoot /vhosts/{$domain.name}/html
  {if $domain.dav}  <Location "{$domain.dav}/">
    # webdav auth stuff here
  </Location>
  {/if}
  # ...
</VirtualHost>
The obvious extension to this would be to generate the entire httpd config file from the template.  There would just be non-vhost-related things before the giant {foreach $vhost as $domain} loop.

Of course, most of the domains had ftp access (because, well, there are something like 1.0e108 ftp clients and 1 graphical sftp client that I can name) so it would be pretty nifty to build a whole instant server configuration that could not only build the Apache file, but also ensure the appropriate directories existed and set up ftpd as well.

Except that I had the intuition that the boss wouldn't go for it, so I quietly dropped the concept.

Five Years Later

I'm looking at the difference between puppet and chef, trying to wrap my head around using vagrant to produce genesis-in-a-box (genesis being the production server at my current employer), as an experiment along the path of producing genesis-as-an-ec2-instance, in turn a necessary waypoint to being able to scale out all the way to Revelation.  Ha ha!  Genesis is actually named after the 80s band.  We'd scale out to violentfemmes.

This is precisely the problem I had been working on: take a canonical source like a puppet manifest and produce a known-good server configuration.

Meta-reflection

As a result of this, I don't think serendipity synchronicity is really an interesting phenomenon.  There are only a few sensible directions to pursue within the constraints of the problem space to begin with, so it's not so unlikely that independent solutions would bear resemblances.

It seems much more likely that hundreds of copies of the solution bubble up, but only a few build enough pressure to break out of confinement and become widely known.  And in singling out those resounding successes, we forget all the concurrent failures.

No comments: