Server Decisions: How we configure our server with Chef

Schermafbeelding 2010-08-29 om 22.39.29

I’ve heard a lot of stuff about Chef by Opscode some time ago but never actually gave it a try. Chef is a bundle of software that allows you to configure and install your servers by coding, not by entering commands. I fiddled with it one time but it was really hard to set up.

Because we’re launching our new server infrastructure on a new bigger Amazon instance in a fe days, I thought I’d give it a try.

The main reason I was looking for something like Chef was automation. In the past I would install every server manually and I didn’t have some predefined bash scripts for setting up a server, installing the base system and preconfigure Rails, PHP apps and things like backups. Chef allows me to do that now.

Our new server is going to run various apps. Our own website, some WordPress websites and mainly Ruby on Rails apps. Because we run some business-critical apps for our clients the server setup should be clean and certainly not hacked together, and we need external backups to S3 and be able to add another server to the pool when usage gets bigger – which is going to happen.

When you have Chef installed, you probably want to run a Chef Server and a Chef Client. The Chef Server keeps all the state of the server configuration for the configuration and installation scripts. The Chef Client actually reads the configuration and runs the script.

The chef clients runs multiple recipes that configure your server. For example, a recipe downloads apache or nginx via apt-get when you’re on Ubuntu, but could install an RPM if you are on an rpm-based distribution. The recipe is the actual script, but you can also store configuration attributes and download urls with the recipes. These little bundles of recipes and other configuration are called cookbooks.

We currently have the following cookbooks in our Chef repository:

Screenshot of the directory lay-out of our Chef repostitory

Our Chef repository

Recipes can depend on other recipes from other cookbooks. For instance to install Phusion Passenger and nginx, I want to use the ruby_enterprise cookbook so it will first in stall the Phusion Ruby Enterprise Edition and then installes and configures nginx and passenger for it.

We use Scout App for monitoring the performance and usage of the instance and we use it so we receive warnings if something reaches critical numbers.

For Scout, I did not run the Scout agent as explained on their on website, but I created a recipe for it in the scout cookbook:

gem_package "scout" do
  action :install
end


gem_package "request-log-analyzer" do
  action :install
end

user "scout" do
  comment "Scout Agent User"
  home "/home/scout"
  supports :manage_home => true
end

execute "scout_first_run" do
  user "scout"
  command "scout #{node[:scout][:key]}"
  creates "/home/scout/.scout/client_history.yaml"
  cwd "/home/scout"
  returns 1
  action :run
end

cron "scout_run" do
  minute "*/5"
  command "scout #{node[:scout][:key]}"
end

What this recipe does it that it installs the gem “scout” using the gem_package Chef command. It then goes on to create a new system user for scout, run the scout agent for the first time and actually adds a cronjob to run it every 5 minutes.

You can see the code is quite clean and it doesn’t look like a hacked-together bash script and it doesn’t look as closed down as some kind of configuration database or .ini file. They are nice Ruby recipe’s for configuring stuff on your server.

You can see that I’m using the node[] variable a few times. The node variable is a Ruby hash of the current configuration the server (or node) is in that the client is being run. Using the web interface on the Chef server you can actually configure per-server configuration values. In our case, the Scout key would be different for every server.

You can do a l it more with these recipes like defining templates for files, default attributes, generating passwords but I’ll save that for another post.

The best thing about the recipes is that I can also communicate with the AWS API. The application cookbook you see there actually creates an EBS block storage devices and attaches it to the current node if it is not already created.

Because all state is saved in the Chef Server configuration database you can easily add more block storage devices or other external stuff just by running the Chef Client. The Chef client probes the server for all the current state the client is in and goes on upgrading all the new changes the recipes requested.

The status page in the Chef Server webapp

fold-left fold-right
About the author
I am the co-founder and lead developer of Firmhouse. An internet company that focuses on developing new internet concepts in an agile way.

Leave a Reply