Configuring a Single Server
We know that if we're managing a cluster of similar machines we need a configuration management tool (CTL) such as Puppet, Chef or Ansible. But what if we have a single machine where we run our services, a snowflake server?
In my experience, if that server is used in production it's still worth it:
- If you ever have hardware problems or have to migrate your services to another machine, having the configuration scripted will make this process painless. Just boot the machine, apply the configuration and you'll have all the services up and running.
- The configuration works as documentation, you'll be able to see why any step is done and which other steps it depends on. This way if you need to change anything some months after it will be obvious which steps to modify and which ones can be deleted safely.
- You can store your configuration in git (or any other SCM system) so you can collaborate with others and work on it iteratively. Hey, is code after all!
- If you use a CTL and Vagrant, you can actually test your services and the machine configuration right on your development machine. You can roll out a pre-production environment in seconds, and is awesome.
Of course, you'll have to learn a new language, and writing all the configuration and verifying that everything works will take much longer than if you were doing it directly on the machine, especially in the beginning.
Another problem is there might be some differences between the Vagrant and the production box. For example, Vagrant will make sure to have your CTL of choice when booting the machine, but this won't probably be the case if you pick a stock operating system.
Finally, you might find some steps that you won't be able to do with a CTL. For example, I haven't found the way to programatically install Java 8, because during the installation is required to accept the licence. In those cases, you might try to find a dirty hack that solves your problem or document the steps in a text file.
Remember that even if you only get to automate 80% of the process, you'll already be in a much better position when you need to redeploy your server.
Example setup with Vagrant
With all this in mind, here's a sample setup that has worked well for me.
server-config/ manifests/ modules/ Vagrantfile readme.txt prod-setup.sh
Since I use Puppet, manifests and modules directories contain the recipes with the configuration. Those will change if you use another CTL.
The Vagrantfile contains the configuration of the Vagrant box. I like to leave it as default as I can, just defining a private network IP and the Puppet configuration options.
The readme.txt file documents all the steps that I couldn't automate and any information that I need to remember when it's time to deploy the server. Because I know that I'll forget it otherwise.
Finally, the prod-setup.sh script is the one I use to configure the production machine. Usually contains the following steps: installing Puppet and git, cloning/pulling from the repository that contains the configuration and performing