Sorry if you are expecting the 'solution' to be given in this post, but this is basically a brain-dump of where I'm at with this problem, and my thoughts on how I might go about solving it.
First up, a little background on Computerminds and the sort of development we do. We tend to take on a mixture of projects, we have projects where we'll be completely responsible for the entire technology stack, and others where we need to bootstrap a team of developers internal to the client and set them up with a stack capable of running Drupal. We lean towards using Rackspace for hosting, but we let our clients decide with some guidance from us, so it's sometimes Linode, sometimes Pulsant, sometimes their own internal infrastructure.
We'd like to be able to have a reasonably consistent way of working over all our projects, and we'd like it to be easy for developers to get up to speed on a project, at least with boring infrastructure stuff. We want to avoid having to make sure that we detail exactly which Solr configuration this site needs, and would rather the correct one was in place automatically.
We also don't want to be the centre of our clients universe, we want them to be able to walk away from us and be able to use the infrastructure we've provided. We don't want to be their host, so central systems that are centred around Computerminds simply will not do.
We have a lot of projects that have requirements beyond a simple database and web-server. Most of our projects (rightly) include some Solr integration, and often there are custom backend processes that must happen too, some sort of nightly import from an external system etc.
This posses a challenge, how do we set up the technology stack and capture all these extra things at the same time so that we can hand them over to someone else, which can include ourselves passing projects internally around the business?
Documentation provides some of the answer. At the moment we try to document as much as we can, and provide instructions for setting up Solr configurations for specific sites etc. but documentation quickly becomes a list of boring tasks to run through, computers are surprisingly good a running through a list of task, so there should be a way we can automate it.
Enter Puppet, the configuration management tool, much has been written about it, and I shall not explain what it is here. We can use puppet to capture all the configuration a site requires beyond what's in the site's settings.php file.
Puppet allows us, for example to pick the specific version of the Solr configs that we need and ensure that Solr is installed, running and running with the correct configuration.
Puppet is an industry standard tool and is well known, so we're not handing over some proprietary system to our clients for them to wrestle with either.
Now, we also have an infrastructure problem when we are developing sites, not just when they are in production. We want the same Solr configs, we want the same versions of PHP, we want the same background tasks running fetching that data from the external source. If we could use the same Puppet manifests to specify configuration both in development and production, that would be amazing.
Vagrant allows us to easily create groups of virtual machines that can represent a real-world set-ups, irrespective of the host machine. So, wonderfully I can develop on my Ubuntu desktop, or my OSX laptop, or even a windows machine if I so desired.
A requirement of a technology stack should be that the various components should be aware of each other, so for example, if we're going to have two webservers and a database server in a particular setup, then through some Puppet mechanism it should be possible for the webservers to be told how to connect to the database server, irrespective of the networking between them. This essentially requires the usage of Puppet as a server, and using storedconfigs to share the data between the machines.
Also, it would be nice if we could define various 'services' that machine will provide, and let Puppet handle the rest, so if I want to add a new webserver, we bring a skeleton machine online and tell Puppet somehow that this machine should supply a web service. Puppet should then add the web service to this machine and add it to the load balanced pool.
In the degenerate case all the 'services' could be on a single machine, and this should also 'just work'.
Vagrant should allow us to also replicate the setup of machines in the production environment and the layout of services on them.
So, my thinking on how to do something like this is to firstly, establish a puppet server that all other machines will connect to. Then, on that server deploy some Puppet configurations for the all the various 'services'.
Then using a technique of self node classification each machine would define which services it required on it, and Puppet would ensure those services were there.
Assigning this classification would become the key thing to capture about the configuration, and in a production environment this might be done manually or using a build tool, or something like mcollective, but I think we'd also need to be able to get Vagrant to assign this classification during it's build process.
If the production environment moves to a dedicated Solr server, then it should be easy to tweak the Vagrant file so that this is replicated on our development environments, run a quick
vagrant up and have everything set itself up.
I think this is all probably easier to do than I'm thinking it will be. Ha!