Server Configuration Management With Chef Solo
Having set up one Linux server from scratch too many, I decided to investigate
configuration management solutions and try to
automatise my setups.
I ended up choosing Chef Solo for the task, due to being a
standalone solution not requiring a client/server setup. The following
blog posts served as inspiration and reference for my implementation:
Following up my previous post where
I set up a base minimum Ubuntu installation with a SSH daemon running on the
server (a requirement for my solution), I will now describe my implementation.
Revision control is a must
for any project, so my first step was to create a git repository on github
to maintain the Chef cookbooks and recipes as well as any additional files
required by the solution. This also has the added advantage that cloning the
git repository is an excellent way of deploying these files on the server.
The first component of the solution is a bash bootstrap script which
runs on the local workstation, taking as its argument the remote user (which
will need to have sudo privileges) and server address in the
user@remote-ip-or-fqdn format, and through a SSH session takes care of
automatising the following steps:
- Add the local user's public SSH key as a remote user's authorised key so
the remote user's password doesn't have to be entered again (this requires
typing the remote user's password).
- Update the remote system's package index and upgrade the installed packages
to the latest available version.
- Install the git package and its dependencies.
- Clone the git repository and its sub-modules (not wanting to re-invent
the wheel I make use of some Opscode Public Cookbooks which are referenced in the git
repository as sub-modules).
- Hand over control to a second bash installation script that is
available in the cloned repository.
Running on the remote server, this installation script automates, in turn,
the following steps:
- Install the debconf-utils and python-software-properties system
packages which simplify the tasks of scripting the installation of packages
with interactive prompts and of adding additional package repositories from
the command line (or in this case from a script).
- Add the OpsCode APT repository to the system's
package repositories, from which we'll be able to install the Chef
- Install the chef package and all its dependencies (the chef package
includes Chef Solo), and create a link from its configuration file in our
repository to its default location at /etc/chef.
Finally, with Chef Solo installed and configured, and with many thanks to our
Bash scripts which took care of bootstrapping our Chef installation, we can
now start using Chef recipes for all the remaining steps! The last line of
the installation script simply invokes chef-solo with our default Chef
JSON configuration file.
The Chef recipes perform (as they should) the bulk of the server installation
and configuration (the previous steps were just the minimum required to install
and configure Chef). The following are the actions performed by the Chef
- Disable running the chef client service on start-up. Since we will be
running Chef Solo and aren't really connected to a Chef server and so
having the Chef client running would be redundant and wasteful.
- Install the etckeeper package: keeping
on with the revision control everywhere mantra, having the server's
configuration files under /etc revision controlled seems like a very good
idea and etckeeper does this automatically for you! The recipe also tweaks
the etckeeper configuration to use git (which we already have
installed) instead of Bazaar which is the default
for the default DRCS for Ubuntu
(although the author prefers git in the source distribution and recommends
- Install the ufw
(Uncomplicated Firewall) package. The default recipe blocks all incoming
ports with the exception of the SSH port (22).
- Reconfigure the SSH daemon to disallow root logins and password
authentication (it will only allow connections authenticated with a public
key for non-root users). This and the previous steps are obvious security
- Install the acpid daemon package to allow host initiated graceful shutdowns
on KVM virtual machine guests (which is the case of the this system).
- Install the byobu
package to provide an enhanced terminal multiplexer experience when
interactive sessions with the server are required.
- Install vim.
Although I belong to the Church of Emacs, I am not a
fundamentalist, and, because of its ubiquity, I tend to use an editor of the
vi persuasion when wearing my systems
- Install htop for process and system
- Install multitail (tail on
steroids!) for an improved experience when following log files.
- Finally install the Apache2 web server (using
the default recipe from the Opscode public
cookbook) and reconfigure the
firewall to allow HTTP (port 80) traffic in.
And that sums it up! A functional Ubuntu 12.04 LTS system with an Apache2
HTTP server setup, fully automated using Chef Solo and a couple of
bootstrap shell scripts.