<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/atom10full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><feed xmlns="http://www.w3.org/2005/Atom" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0">
  <id>http://robin.wenglewski.de/</id>
  <title>Robin Wenglewski - Articles</title>
  <updated>2012-01-10T23:00:00Z</updated>
  <link rel="alternate" href="http://robin.wenglewski.de/" />
  
  <author>
    <name>Robin Wenglewski</name>
    <uri>http://robin.wenglewski.de</uri>
  </author>
  <atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/atom+xml" href="http://feeds.feedburner.com/robin-wenglewski" /><feedburner:info uri="robin-wenglewski" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><entry>
    <id>tag:robin.wenglewski.de,2012-01-11:/posts/2012/01/11/littlechef/</id>
    <title type="html">Push-Configuration and -Deployment with Chef Solo and Littlechef</title>
    <published>2012-01-10T23:00:00Z</published>
    <updated>2012-01-10T23:00:00Z</updated>
    <link rel="alternate" href="http://feedproxy.google.com/~r/robin-wenglewski/~3/AHLOkGuvPec/" />
    <content type="html">&lt;h2 id="introduction"&gt;Introduction&lt;/h2&gt;

&lt;p&gt;&lt;a href="http://www.opscode.com/chef/"&gt;Chef&lt;/a&gt;, &lt;a href="http://puppetlabs.com/"&gt;Puppet&lt;/a&gt; and &lt;a href="http://babushka.me/"&gt;babushka&lt;/a&gt; are great tools for automating machine configuration and deployment.
However, where babushka is not enterprise-ready, Chef and Puppet are designed for a server/client architecture.
There are several cases where you do not want your servers to pull configuration automatically from a central place, but rather push your configuration to the nodes.
Both, Chef and Puppet, provide a way to run recipes locally.
However, as this is not the main use case, doing so lacks some level of usability.&lt;/p&gt;

&lt;p&gt;There are two projects which got my attention as a wrapper around chef-solo: &lt;a href="https://github.com/tobami/littlechef"&gt;littlechef&lt;/a&gt; and &lt;a href="https://github.com/mkocher/soloist"&gt;soloist&lt;/a&gt;. Soloist seems to be made for configuring the current machine, whereas the strength of littlechef seems to be pushing and configuring remote machines.&lt;/p&gt;

&lt;p&gt;I will describe here my setup for pushing configurations to nodes by utilizing &lt;a href="https://github.com/tobami/littlechef"&gt;littlechef&lt;/a&gt;. &lt;/p&gt;

&lt;h2 id="littlechef"&gt;Littlechef&lt;/h2&gt;

&lt;p&gt;There is a &lt;a href="http://sysadvent.blogspot.com/2010/12/day-9-automated-deployments-with.html"&gt;great blog post&lt;/a&gt; for getting started with little chef.
In short, follow the installation guide on &lt;a href="https://github.com/tobami/littlechef"&gt;littlechef&lt;/a&gt; to get started.
After the installation, you should have the command &lt;em&gt;fix&lt;/em&gt; available in your path.
To create your littlechef kitchen run&lt;/p&gt;

&lt;pre&gt;&lt;code class="language-shell"&gt;&lt;table class="CodeRay"&gt;&lt;tr&gt;
&lt;td class="line_numbers" title="click to toggle" onclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }"&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }"&gt;mkdir littlechef&lt;tt&gt;
&lt;/tt&gt;cd littlechef&lt;tt&gt;
&lt;/tt&gt;fix new_kitchen&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This should give you the folder structure described on &lt;a href="https://github.com/tobami/littlechef"&gt;littlechef&lt;/a&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;auth.cfg&lt;/code&gt;: Authentication information needed to be able to connect to the nodes&lt;/li&gt;
  &lt;li&gt;
&lt;code&gt;nodes/&lt;/code&gt;: After recipes are run on [Nodes][], their configuration is stored here in
JSON format. You can manually edit them or even add new ones. The name of a node
should be its FQDN&lt;/li&gt;
  &lt;li&gt;
&lt;code&gt;cookbooks/&lt;/code&gt;: This will be your [Cookbooks][] repository&lt;/li&gt;
  &lt;li&gt;
&lt;code&gt;site-cookbooks/&lt;/code&gt;: Here you can override upstream cookbooks (Opscode’s, for example)&lt;/li&gt;
  &lt;li&gt;
&lt;code&gt;roles/&lt;/code&gt;: Where Chef [Roles][] are defined in JSON&lt;/li&gt;
  &lt;li&gt;
&lt;code&gt;data_bags/&lt;/code&gt;: Chef [Data Bags][]. JSON databag items. Search is supported&lt;/li&gt;
  &lt;li&gt;
&lt;code&gt;plugins/&lt;/code&gt;: Your plugin tasks&lt;/li&gt;
&lt;/ul&gt;&lt;h2 id="installing-cookbooks"&gt;Installing cookbooks&lt;/h2&gt;

&lt;p&gt;Now there are several ways to install external cookbooks.
I use braid because it keeps the cookbook code directly in the repository and can thus just be cloned and used on another machine (no git submodule init and no librarian-chef install).&lt;/p&gt;

&lt;h3 id="with-braid"&gt;With Braid&lt;/h3&gt;

&lt;pre&gt;&lt;code class="language-text"&gt;&lt;table class="CodeRay"&gt;&lt;tr&gt;
&lt;td class="line_numbers" title="click to toggle" onclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }"&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }"&gt;gem install braid&lt;tt&gt;
&lt;/tt&gt;braid add --branch master git://github.com/fnichol/chef-rbenv.git cookbooks/rbenv&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This downloads the repository to &lt;em&gt;cookbooks/rbenv&lt;/em&gt;, adds the information about the location and branch of the repository to a &lt;em&gt;.braids&lt;/em&gt; file and commits it with the message&lt;/p&gt;

&lt;p&gt;fa7c4c8 Braid: Add mirror ‘cookbooks/rbenv’ at ‘9ecda8b’ (2 minutes ago)&lt;/p&gt;

&lt;h3 id="a-nameinstallation-librariana-using-librarian"&gt;
&lt;a name="installation-librarian"&gt;&lt;/a&gt; Using Librarian&lt;/h3&gt;

&lt;p&gt;The &lt;a href="https://github.com/applicationsonline/librarian#readme"&gt;Librarian&lt;/a&gt; gem aims to be Bundler for your Chef cookbooks.
Include a reference to the cookbook in a &lt;a href="https://github.com/applicationsonline/librarian/blob/master/lib/librarian/chef/templates/Cheffile"&gt;Cheffile&lt;/a&gt; and run
&lt;code&gt;librarian-chef install&lt;/code&gt;. To install with Librarian:&lt;/p&gt;

&lt;pre&gt;&lt;code class="language-text"&gt;&lt;table class="CodeRay"&gt;&lt;tr&gt;
&lt;td class="line_numbers" title="click to toggle" onclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }"&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;5&lt;tt&gt;
&lt;/tt&gt;6&lt;tt&gt;
&lt;/tt&gt;7&lt;tt&gt;
&lt;/tt&gt;8&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }"&gt;gem install librarian&lt;tt&gt;
&lt;/tt&gt;cd chef-repo&lt;tt&gt;
&lt;/tt&gt;librarian-chef init&lt;tt&gt;
&lt;/tt&gt;cat &amp;gt;&amp;gt; Cheffile &amp;lt;&amp;lt;END_OF_CHEFFILE&lt;tt&gt;
&lt;/tt&gt;cookbook 'rbenv',&lt;tt&gt;
&lt;/tt&gt;  :git =&amp;gt; 'git://github.com/fnichol/chef-rbenv.git', :ref =&amp;gt; 'v0.6.0'&lt;tt&gt;
&lt;/tt&gt;END_OF_CHEFFILE&lt;tt&gt;
&lt;/tt&gt;librarian-chef install&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;h3 id="a-nameinstallation-kgca-using-knife-github-cookbooks"&gt;
&lt;a name="installation-kgc"&gt;&lt;/a&gt; Using knife-github-cookbooks&lt;/h3&gt;

&lt;p&gt;The &lt;a href="https://github.com/websterclay/knife-github-cookbooks#readme"&gt;knife-github-cookbooks&lt;/a&gt; gem is a plugin for &lt;em&gt;knife&lt;/em&gt; that supports
installing cookbooks directly from a GitHub repository. To install with the
plugin:&lt;/p&gt;

&lt;pre&gt;&lt;code class="language-text"&gt;&lt;table class="CodeRay"&gt;&lt;tr&gt;
&lt;td class="line_numbers" title="click to toggle" onclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }"&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }"&gt;gem install knife-github-cookbooks&lt;tt&gt;
&lt;/tt&gt;cd chef-repo&lt;tt&gt;
&lt;/tt&gt;knife cookbook github install fnichol/chef-rbenv/v0.6.0&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;h3 id="a-nameinstallation-gitsubmodulea-as-a-git-submodule"&gt;
&lt;a name="installation-gitsubmodule"&gt;&lt;/a&gt; As a Git Submodule&lt;/h3&gt;

&lt;p&gt;A common practice (which is getting dated) is to add cookbooks as Git
submodules. This is accomplishes like so:&lt;/p&gt;

&lt;pre&gt;&lt;code class="language-text"&gt;&lt;table class="CodeRay"&gt;&lt;tr&gt;
&lt;td class="line_numbers" title="click to toggle" onclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }"&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }"&gt;cd chef-repo&lt;tt&gt;
&lt;/tt&gt;git submodule add git://github.com/fnichol/chef-rbenv.git cookbooks/rbenv&lt;tt&gt;
&lt;/tt&gt;git submodule init &amp;amp;&amp;amp; git submodule update&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; the head of development will be linked here, not a tagged release.&lt;/p&gt;

&lt;h3 id="a-nameinstallation-tarballa-as-a-tarball"&gt;
&lt;a name="installation-tarball"&gt;&lt;/a&gt; As a Tarball&lt;/h3&gt;

&lt;p&gt;If the cookbook needs to downloaded temporarily just to be uploaded to a Chef
Server or Opscode Hosted Chef, then a tarball installation might fit the bill:&lt;/p&gt;

&lt;pre&gt;&lt;code class="language-text"&gt;&lt;table class="CodeRay"&gt;&lt;tr&gt;
&lt;td class="line_numbers" title="click to toggle" onclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }"&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }"&gt;cd chef-repo/cookbooks&lt;tt&gt;
&lt;/tt&gt;curl -Ls https://github.com/fnichol/chef-rbenv/tarball/v0.6.0 | tar xfz - &amp;amp;&amp;amp; \&lt;tt&gt;
&lt;/tt&gt;  mv fnichol-chef-rbenv-* rbenv&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;h2 id="testing-cookbooks-with-vagrant"&gt;Testing cookbooks with Vagrant&lt;/h2&gt;

&lt;p&gt;&lt;a href="http://vagrantup.com/"&gt;Vagrant&lt;/a&gt; can be used for starting virtual machines from the command line and configuring them with chef or puppet recipes.
To avoid reinstalling my servers or creating EC2 machines, I use vagrant for testing my cookbooks.&lt;/p&gt;

&lt;p&gt;For this to work you need to install &lt;a href="https://www.virtualbox.org/"&gt;VirtualBox&lt;/a&gt;.
Then you can follow the &lt;a href="http://vagrantup.com/"&gt;installation guide&lt;/a&gt; on the vagrant website:&lt;/p&gt;

&lt;pre&gt;&lt;code class="language-text"&gt;&lt;table class="CodeRay"&gt;&lt;tr&gt;
&lt;td class="line_numbers" title="click to toggle" onclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }"&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }"&gt;gem install vagrant&lt;tt&gt;
&lt;/tt&gt;vagrant box add base http://files.vagrantup.com/lucid32.box&lt;tt&gt;
&lt;/tt&gt;vagrant init&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;You can find different pre-packaged boxes on &lt;a href="http://vagrantbox.es/"&gt;vagrantbox.es&lt;/a&gt;.
Before running &lt;code&gt;vagrant up&lt;/code&gt;, you need to enable automatic configuration with chef-solo.
Therefore, put this block in your Vagrantfile which should have been created by the vagrant init command:&lt;/p&gt;

&lt;pre&gt;&lt;code class="language-ruby"&gt;&lt;table class="CodeRay"&gt;&lt;tr&gt;
&lt;td class="line_numbers" title="click to toggle" onclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }"&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;5&lt;tt&gt;
&lt;/tt&gt;6&lt;tt&gt;
&lt;/tt&gt;7&lt;tt&gt;
&lt;/tt&gt;8&lt;tt&gt;
&lt;/tt&gt;9&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;10&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;11&lt;tt&gt;
&lt;/tt&gt;12&lt;tt&gt;
&lt;/tt&gt;13&lt;tt&gt;
&lt;/tt&gt;14&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }"&gt;config.vm.provision &lt;span style="color:#A60"&gt;:chef_solo&lt;/span&gt; &lt;span style="color:#080;font-weight:bold"&gt;do&lt;/span&gt; |chef|&lt;tt&gt;
&lt;/tt&gt;  chef.cookbooks_path = &lt;span style="background-color:#fff0f0;color:#D20"&gt;&lt;span style="color:#710"&gt;"&lt;/span&gt;&lt;span style=""&gt;cookbooks&lt;/span&gt;&lt;span style="color:#710"&gt;"&lt;/span&gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  chef.add_recipe &lt;span style="background-color:#fff0f0;color:#D20"&gt;&lt;span style="color:#710"&gt;"&lt;/span&gt;&lt;span style=""&gt;quc&lt;/span&gt;&lt;span style="color:#710"&gt;"&lt;/span&gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;span style="color:#888"&gt;# You may also specify custom JSON attributes:&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  chef.json = {&lt;span style="background-color:#fff0f0;color:#D20"&gt;&lt;span style="color:#710"&gt;"&lt;/span&gt;&lt;span style=""&gt;quc&lt;/span&gt;&lt;span style="color:#710"&gt;"&lt;/span&gt;&lt;/span&gt; =&amp;gt; {&lt;tt&gt;
&lt;/tt&gt;                &lt;span style="background-color:#fff0f0;color:#D20"&gt;&lt;span style="color:#710"&gt;"&lt;/span&gt;&lt;span style=""&gt;repository&lt;/span&gt;&lt;span style="color:#710"&gt;"&lt;/span&gt;&lt;/span&gt; =&amp;gt; &lt;span style="background-color:#fff0f0;color:#D20"&gt;&lt;span style="color:#710"&gt;"&lt;/span&gt;&lt;span style=""&gt;https://rweng:pw@github.com/rweng/project.git&lt;/span&gt;&lt;span style="color:#710"&gt;"&lt;/span&gt;&lt;/span&gt;,&lt;tt&gt;
&lt;/tt&gt;                &lt;span style="background-color:#fff0f0;color:#D20"&gt;&lt;span style="color:#710"&gt;"&lt;/span&gt;&lt;span style=""&gt;dump&lt;/span&gt;&lt;span style="color:#710"&gt;"&lt;/span&gt;&lt;/span&gt; =&amp;gt; &lt;span style="background-color:#fff0f0;color:#D20"&gt;&lt;span style="color:#710"&gt;"&lt;/span&gt;&lt;span style=""&gt;http://dl.dropbox.com/u/456244/dump&lt;/span&gt;&lt;span style="color:#710"&gt;"&lt;/span&gt;&lt;/span&gt;,&lt;tt&gt;
&lt;/tt&gt;                &lt;span style="background-color:#fff0f0;color:#D20"&gt;&lt;span style="color:#710"&gt;"&lt;/span&gt;&lt;span style=""&gt;data&lt;/span&gt;&lt;span style="color:#710"&gt;"&lt;/span&gt;&lt;/span&gt; =&amp;gt; &lt;span style="background-color:#fff0f0;color:#D20"&gt;&lt;span style="color:#710"&gt;"&lt;/span&gt;&lt;span style=""&gt;http://dl.dropbox.com/u/456244/data.zip&lt;/span&gt;&lt;span style="color:#710"&gt;"&lt;/span&gt;&lt;/span&gt;,&lt;tt&gt;
&lt;/tt&gt;                &lt;span style="background-color:#fff0f0;color:#D20"&gt;&lt;span style="color:#710"&gt;"&lt;/span&gt;&lt;span style=""&gt;postfix&lt;/span&gt;&lt;span style="color:#710"&gt;"&lt;/span&gt;&lt;/span&gt; =&amp;gt; {&lt;tt&gt;
&lt;/tt&gt;                        &lt;span style="background-color:#fff0f0;color:#D20"&gt;&lt;span style="color:#710"&gt;"&lt;/span&gt;&lt;span style=""&gt;mydomain&lt;/span&gt;&lt;span style="color:#710"&gt;"&lt;/span&gt;&lt;/span&gt; =&amp;gt; &lt;span style="background-color:#fff0f0;color:#D20"&gt;&lt;span style="color:#710"&gt;"&lt;/span&gt;&lt;span style=""&gt;domain.com&lt;/span&gt;&lt;span style="color:#710"&gt;"&lt;/span&gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;                }&lt;tt&gt;
&lt;/tt&gt;        }}&lt;tt&gt;
&lt;/tt&gt;&lt;span style="color:#080;font-weight:bold"&gt;end&lt;/span&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;code&gt;chef.json&lt;/code&gt; can contain arbitrary data that you want to pass into your cookbooks.
I use it for sensitive information like passwords.
When running &lt;code&gt;vagrant up&lt;/code&gt;, you should get a detailed log about what is done in your recipes.&lt;/p&gt;

&lt;h2 id="using-littlechef"&gt;Using Littlechef&lt;/h2&gt;

&lt;h3 id="authentication"&gt;Authentication&lt;/h3&gt;

&lt;p&gt;My &lt;em&gt;auth.cfg&lt;/em&gt; file contains only a reference to the default ssh configuration file:&lt;/p&gt;

&lt;pre&gt;&lt;code class="language-text"&gt;&lt;table class="CodeRay"&gt;&lt;tr&gt;
&lt;td class="line_numbers" title="click to toggle" onclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }"&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }"&gt;[userinfo]&lt;tt&gt;
&lt;/tt&gt;ssh-config = ~/.ssh/config&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;You should handle all login related stuff in there. 
Please note that there is currently a &lt;a href="https://github.com/tobami/littlechef/issues/78"&gt;bug&lt;/a&gt; when setting HostName to an IP instead of a FQDN.&lt;/p&gt;

&lt;h3 id="deploying-chef"&gt;Deploying Chef&lt;/h3&gt;

&lt;p&gt;Before applying your cookbooks to a remote machine, you need to make sure that chef is installed on it.
Therefore, you can run &lt;code&gt;fix node:youdomain.com deploy_chef&lt;/code&gt;.
As described in the &lt;a href="https://github.com/tobami/littlechef"&gt;littlechef readme&lt;/a&gt;, &lt;code&gt;deploy_chef:ask=no&lt;/code&gt; runs deploy_chef without confirmation.&lt;/p&gt;

&lt;p&gt;If the machine was already configured with littlechef, the node.json file is downloaded and put in the node directory.
This way, the json configuration does not have to be set again manually.&lt;/p&gt;

&lt;h3 id="applying-cookbooks"&gt;Applying Cookbooks&lt;/h3&gt;

&lt;p&gt;To apply a recipe to a node run&lt;/p&gt;

&lt;pre&gt;&lt;code class="language-text"&gt;&lt;table class="CodeRay"&gt;&lt;tr&gt;
&lt;td class="line_numbers" title="click to toggle" onclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }"&gt;&lt;pre&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }"&gt;fix node:domain.com recipe:vim&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;or&lt;/p&gt;

&lt;pre&gt;&lt;code class="language-text"&gt;&lt;table class="CodeRay"&gt;&lt;tr&gt;
&lt;td class="line_numbers" title="click to toggle" onclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }"&gt;&lt;pre&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }"&gt;fix node:domain.com recipe:"vim::test,othercookbook::recipe"&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This creates the file &lt;code&gt;nodes/domain.com.json&lt;/code&gt; with the content&lt;/p&gt;

&lt;pre&gt;&lt;code class="language-json"&gt;&lt;table class="CodeRay"&gt;&lt;tr&gt;
&lt;td class="line_numbers" title="click to toggle" onclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }"&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;5&lt;tt&gt;
&lt;/tt&gt;6&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }"&gt;{&lt;tt&gt;
&lt;/tt&gt;    &lt;span style="color:#808"&gt;&lt;span style="color:#606"&gt;"&lt;/span&gt;ipaddress&lt;span style="color:#606"&gt;"&lt;/span&gt;&lt;/span&gt;: &lt;span style="background-color:#fff0f0;color:#D20"&gt;&lt;span style="color:#710"&gt;"&lt;/span&gt;&lt;span style=""&gt;10.192.221.110&lt;/span&gt;&lt;span style="color:#710"&gt;"&lt;/span&gt;&lt;/span&gt;,&lt;tt&gt;
&lt;/tt&gt;    &lt;span style="color:#808"&gt;&lt;span style="color:#606"&gt;"&lt;/span&gt;run_list&lt;span style="color:#606"&gt;"&lt;/span&gt;&lt;/span&gt;: [&lt;tt&gt;
&lt;/tt&gt;        &lt;span style="background-color:#fff0f0;color:#D20"&gt;&lt;span style="color:#710"&gt;"&lt;/span&gt;&lt;span style=""&gt;recipe[vim]&lt;/span&gt;&lt;span style="color:#710"&gt;"&lt;/span&gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    ]&lt;tt&gt;
&lt;/tt&gt;}&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;You can add other attributes in this file to override the cookbook attributes:&lt;/p&gt;

&lt;pre&gt;&lt;code class="language-json"&gt;&lt;table class="CodeRay"&gt;&lt;tr&gt;
&lt;td class="line_numbers" title="click to toggle" onclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }"&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;5&lt;tt&gt;
&lt;/tt&gt;6&lt;tt&gt;
&lt;/tt&gt;7&lt;tt&gt;
&lt;/tt&gt;8&lt;tt&gt;
&lt;/tt&gt;9&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }"&gt;{&lt;tt&gt;
&lt;/tt&gt;    &lt;span style="color:#808"&gt;&lt;span style="color:#606"&gt;"&lt;/span&gt;ipaddress&lt;span style="color:#606"&gt;"&lt;/span&gt;&lt;/span&gt;: &lt;span style="background-color:#fff0f0;color:#D20"&gt;&lt;span style="color:#710"&gt;"&lt;/span&gt;&lt;span style=""&gt;10.192.221.110&lt;/span&gt;&lt;span style="color:#710"&gt;"&lt;/span&gt;&lt;/span&gt;,&lt;tt&gt;
&lt;/tt&gt;    &lt;span style="color:#808"&gt;&lt;span style="color:#606"&gt;"&lt;/span&gt;run_list&lt;span style="color:#606"&gt;"&lt;/span&gt;&lt;/span&gt;: [&lt;tt&gt;
&lt;/tt&gt;        &lt;span style="background-color:#fff0f0;color:#D20"&gt;&lt;span style="color:#710"&gt;"&lt;/span&gt;&lt;span style=""&gt;recipe[vim]&lt;/span&gt;&lt;span style="color:#710"&gt;"&lt;/span&gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    ],&lt;tt&gt;
&lt;/tt&gt;    &lt;span style="color:#808"&gt;&lt;span style="color:#606"&gt;"&lt;/span&gt;vim&lt;span style="color:#606"&gt;"&lt;/span&gt;&lt;/span&gt;: {&lt;tt&gt;
&lt;/tt&gt;        &lt;span style="color:#808"&gt;&lt;span style="color:#606"&gt;"&lt;/span&gt;install_path&lt;span style="color:#606"&gt;"&lt;/span&gt;&lt;/span&gt;: &lt;span style="background-color:#fff0f0;color:#D20"&gt;&lt;span style="color:#710"&gt;"&lt;/span&gt;&lt;span style=""&gt;/usr/local/vim&lt;/span&gt;&lt;span style="color:#710"&gt;"&lt;/span&gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;        }&lt;tt&gt;
&lt;/tt&gt;}&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;h2 id="conclusion"&gt;Conclusion&lt;/h2&gt;

&lt;p&gt;I learned to love littlechef.
It enables me to push my cookbooks to remote machines and deploy my applications without having a chef master.&lt;/p&gt;

&lt;p&gt;Feel free to point out any (spelling) mistakes or open questions in the comments.&lt;/p&gt;

&lt;h2 id="references"&gt;References&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/tobami/littlechef"&gt;littlechef&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href="http://sysadvent.blogspot.com/2010/12/day-9-automated-deployments-with.html"&gt;blog post about littlechef&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href="https://www.virtualbox.org/"&gt;VirtualBox&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href="http://vagrantup.com/"&gt;Vagrant&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href="http://vagrantbox.es/"&gt;vagrantbox.es&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href="https://github.com/mkocher/soloist"&gt;soloist&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href="http://www.opscode.com/chef/"&gt;chef&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;img src="http://feeds.feedburner.com/~r/robin-wenglewski/~4/AHLOkGuvPec" height="1" width="1"/&gt;</content>
  <feedburner:origLink>http://robin.wenglewski.de/posts/2012/01/11/littlechef/</feedburner:origLink></entry>
  <entry>
    <id>tag:robin.wenglewski.de,2011-12-29:/posts/2011/12/29/rvm-to-rbenv/</id>
    <title type="html">From RVM to rbenv</title>
    <published>2011-12-28T23:00:00Z</published>
    <updated>2011-12-28T23:00:00Z</updated>
    <link rel="alternate" href="http://feedproxy.google.com/~r/robin-wenglewski/~3/2oU5GrbUkxc/" />
    <content type="html">&lt;p&gt;I decided to move from &lt;a href="http://beginrescueend.com/"&gt;RVM&lt;/a&gt; to &lt;a href="https://github.com/sstephenson/rbenv"&gt;rbenv&lt;/a&gt;.
rbenv is getting a lot of hype lately.
Instead of overriding &lt;em&gt;cd&lt;/em&gt; like rvm, it uses the already available UNIX functionality like adjusting the &lt;em&gt;PATH&lt;/em&gt; to the ruby to use.&lt;/p&gt;

&lt;p&gt;My move is mainly motivated by curiosity, although I have had some problems with rvm before and I hope that using rbenv will avoid them.
During the migration, I mainly followed &lt;a href="http://snippets.aktagon.com/snippets/532-How-to-migrate-from-rvm-to-rbenv"&gt;this excellent guide&lt;/a&gt;.
Here is a summary with some additional information:&lt;/p&gt;

&lt;pre&gt;&lt;code class="language-shell"&gt;&lt;table class="CodeRay"&gt;&lt;tr&gt;
&lt;td class="line_numbers" title="click to toggle" onclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }"&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;5&lt;tt&gt;
&lt;/tt&gt;6&lt;tt&gt;
&lt;/tt&gt;7&lt;tt&gt;
&lt;/tt&gt;8&lt;tt&gt;
&lt;/tt&gt;9&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;10&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;11&lt;tt&gt;
&lt;/tt&gt;12&lt;tt&gt;
&lt;/tt&gt;13&lt;tt&gt;
&lt;/tt&gt;14&lt;tt&gt;
&lt;/tt&gt;15&lt;tt&gt;
&lt;/tt&gt;16&lt;tt&gt;
&lt;/tt&gt;17&lt;tt&gt;
&lt;/tt&gt;18&lt;tt&gt;
&lt;/tt&gt;19&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }"&gt;# remove all rvm files&lt;tt&gt;
&lt;/tt&gt;$ rvm implode&lt;tt&gt;
&lt;/tt&gt;WARN: Are you SURE you wish for rvm to implode?      &lt;tt&gt;
&lt;/tt&gt;This will recursively remove /Users/robin/.rvm and other rvm traces?      &lt;tt&gt;
&lt;/tt&gt;(type 'yes' or 'no')&amp;gt; &lt;tt&gt;
&lt;/tt&gt;yes&lt;tt&gt;
&lt;/tt&gt;Removing rvm-shipped binaries (rvm-prompt, rvm, rvm-sudo rvm-shell and rvm-auto-ruby)&lt;tt&gt;
&lt;/tt&gt;Removing rvm wrappers in /Users/robin/.rvm/bin&lt;tt&gt;
&lt;/tt&gt;Hai! Removing /Users/robin/.rvm&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;/Users/robin/.rvm has been removed.&lt;tt&gt;
&lt;/tt&gt;rvm has been fully removed. Note you may need to manually remove /etc/rvmrc and ~/.rvmrc if they exist still.%&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;$ rm ~/.rvmrc&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;# install rbenv and ruby-build&lt;tt&gt;
&lt;/tt&gt;$ brew update&lt;tt&gt;
&lt;/tt&gt;$ brew install rbenv&lt;tt&gt;
&lt;/tt&gt;$ brew install ruby-build&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Now we add &lt;code&gt;eval "$(rbenv init -)"&lt;/code&gt; to &lt;em&gt;.zshenv&lt;/em&gt; as described in the &lt;a href="https://github.com/sstephenson/rbenv"&gt;rbenv README&lt;/a&gt;.
After starting a new session, we should be able to see the current ruby being used with &lt;code&gt;rbenv global&lt;/code&gt; (which should be system).
Run &lt;code&gt;rbenv versions&lt;/code&gt; to see all rubies that can be installed with ruby-build.
To install ruby 1.9.2, run &lt;code&gt;rbenv install 1.9.2-p290&lt;/code&gt;.
Now you can set this as the default ruby with &lt;code&gt;rbenv global 1.9.2-p290&lt;/code&gt;.
Deleting a ruby version and its gems is as easy as &lt;code&gt;rm -r ~/.rbenv/versions/[VERSION]&lt;/code&gt;.&lt;/p&gt;

&lt;h2 id="bundler"&gt;Bundler&lt;/h2&gt;

&lt;p&gt;rbenv does not come with gemset support.
&lt;a href="https://github.com/jamis/rbenv-gemset"&gt;rbenv-gemset&lt;/a&gt; is an extension for rbenv that brings this functionality to rbenv.
However, &lt;a href="http://gembundler.com/"&gt;bundler&lt;/a&gt; is a pretty awesome tool for managing gems and dependencies so I decided to stick only with that.
After installing the gem and running &lt;code&gt;bundle install&lt;/code&gt; in one of my projects I noticed that the binaries of the dependencies were missing.
Usually with rbenv, you only have to install the gem and run &lt;code&gt;rbenv rehash&lt;/code&gt; to make the binaries available.&lt;/p&gt;

&lt;p&gt;After researching this a little bit I noticed, that the missing binaries are not a problem but a feature.
Binaries of projects managed with bundler are usually executed with &lt;code&gt;bundle exec [BINARY]&lt;/code&gt; anyway.
Since I am lazy I usually run bundle exec only when I know that a different version than the globally available one is specified in the Gemfile.
However, it is far safer to always use &lt;em&gt;bundle exec&lt;/em&gt;.
Running them this way works just fine and with an alias like &lt;code&gt;alias be=bundle exec&lt;/code&gt; it is not so much overhead.&lt;/p&gt;

&lt;p&gt;During my research of the missing binaries in bundler I stumbled upon &lt;a href="http://gembundler.com/man/bundle-config.1.html"&gt;bundle config&lt;/a&gt; and the &lt;em&gt;.bundle/config&lt;/em&gt; file.
The &lt;em&gt;.bundle/config&lt;/em&gt; file can be in you app or home directory and defines the bundler configuration.
The following two commands cause bundle to always install gems and binaries in the project folder.
This is great because it does not clutter up my global gemset.
However, don’t forget to add both directories to your .gitignore file ;)&lt;/p&gt;

&lt;pre&gt;&lt;code class="language-shell"&gt;&lt;table class="CodeRay"&gt;&lt;tr&gt;
&lt;td class="line_numbers" title="click to toggle" onclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }"&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }"&gt;bundle config PATH vendor/bundle&lt;tt&gt;
&lt;/tt&gt;bundle config BIN .bin&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;img src="http://feeds.feedburner.com/~r/robin-wenglewski/~4/2oU5GrbUkxc" height="1" width="1"/&gt;</content>
  <feedburner:origLink>http://robin.wenglewski.de/posts/2011/12/29/rvm-to-rbenv/</feedburner:origLink></entry>
  <entry>
    <id>tag:robin.wenglewski.de,2011-09-25:/posts/2011/09/25/zsh-theme/</id>
    <title type="html">zsh theme</title>
    <published>2011-09-24T22:00:00Z</published>
    <updated>2011-09-24T22:00:00Z</updated>
    <link rel="alternate" href="http://feedproxy.google.com/~r/robin-wenglewski/~3/f2PbV3TJqio/" />
    <content type="html">&lt;p&gt;I made an oh-my-zsh zsh theme. This is how it looks like:&lt;/p&gt;

&lt;p&gt;&lt;img src="../rweng-zsh-theme.png" alt="zsh theme"&gt;&lt;/p&gt;

&lt;p&gt;The current path in blue is starting the first line.
If the current path is a git repository, the time since the last commit is displayed as well as the current branch.
If behind the branch is an asterix, there are uncommited files in the repository.
The color of the git information is dependent on the time since the last commit.&lt;/p&gt;

&lt;p&gt;The second line, the execution line, starts with a flash in red after which you can enter your commands.
At the end of the line, the current username and machine is displayed.&lt;/p&gt;

&lt;p&gt;Another feature is that the error code is shown in red if a command failed.
If you like the theme, feel free to download it &lt;a href="https://raw.github.com/rweng/dotzsh/master/themes/rweng.zsh-theme"&gt;from my github repository&lt;/a&gt;.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/robin-wenglewski/~4/f2PbV3TJqio" height="1" width="1"/&gt;</content>
  <feedburner:origLink>http://robin.wenglewski.de/posts/2011/09/25/zsh-theme/</feedburner:origLink></entry>
  <entry>
    <id>tag:robin.wenglewski.de,2011-09-08:/posts/2011/09/08/iterm2-error/</id>
    <title type="html">iTerm2 error</title>
    <published>2011-09-07T22:00:00Z</published>
    <updated>2011-09-07T22:00:00Z</updated>
    <link rel="alternate" href="http://feedproxy.google.com/~r/robin-wenglewski/~3/Vi4kzvZz-Gs/" />
    <content type="html">&lt;p&gt;After upgrading iTerm2, i got the following error:&lt;/p&gt;

&lt;pre&gt;&lt;code class="language-text"&gt;&lt;table class="CodeRay"&gt;&lt;tr&gt;
&lt;td class="line_numbers" title="click to toggle" onclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }"&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }"&gt;## exec failed ##&lt;tt&gt;
&lt;/tt&gt;login No such file or directory&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Fix it by deleting &lt;code&gt;.MacOSX/environment.plist&lt;/code&gt;.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/robin-wenglewski/~4/Vi4kzvZz-Gs" height="1" width="1"/&gt;</content>
  <feedburner:origLink>http://robin.wenglewski.de/posts/2011/09/08/iterm2-error/</feedburner:origLink></entry>
  <entry>
    <id>tag:robin.wenglewski.de,2011-09-07:/posts/2011/09/07/configuration-management/</id>
    <title type="html">Configuration Management: Chef, Puppet, Babushka, Sprinkle and Co</title>
    <published>2011-09-06T22:00:00Z</published>
    <updated>2011-09-06T22:00:00Z</updated>
    <link rel="alternate" href="http://feedproxy.google.com/~r/robin-wenglewski/~3/0tUC1mELr_I/" />
    <content type="html">&lt;p&gt;&lt;strong&gt;TL;DR&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;All CM tools suck at some points.
But going without one is no alternative.
&lt;strong&gt;Use chef&lt;/strong&gt;.
Or babushka, if chef has a too steep learning curve and you don’t need to manage tons of nodes.&lt;/p&gt;

&lt;h2 id="intro"&gt;Intro&lt;/h2&gt;

&lt;p&gt;There is an awful load of tools available for &lt;a href="http://en.wikipedia.org/wiki/Software_configuration_management"&gt;Configuration Management&lt;/a&gt;.
This is good, because, like &lt;a href="http://www.infoq.com/presentations/Automation-DSL"&gt;Terence Perr put it&lt;/a&gt;:
“Automation can make critical things work only one way: the right way.”
Additionally, automation increases productivity and consistency.&lt;/p&gt;

&lt;p&gt;But out of this pool of tools, which one fits your needs best?
Let’s take a peek at these tools:&lt;/p&gt;

&lt;h2 id="puppet"&gt;Puppet&lt;/h2&gt;

&lt;p&gt;Puppet a CM tool written in &lt;strong&gt;Ruby&lt;/strong&gt; and (now) released under the &lt;strong&gt;Apache license&lt;/strong&gt;.
It is usually operated in a client/server mode, but you can also run puppet “programs” locally with &lt;code&gt;puppet apply&lt;/code&gt;.
Puppet “programs” are called &lt;strong&gt;manifests&lt;/strong&gt; and are written in puppets own external DSL RALsh (&lt;strong&gt;Resource Abstraction Layer&lt;/strong&gt;).
RALsh looks like this:&lt;/p&gt;

&lt;pre&gt;&lt;code class="language-text"&gt;&lt;table class="CodeRay"&gt;&lt;tr&gt;
&lt;td class="line_numbers" title="click to toggle" onclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }"&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;5&lt;tt&gt;
&lt;/tt&gt;6&lt;tt&gt;
&lt;/tt&gt;7&lt;tt&gt;
&lt;/tt&gt;8&lt;tt&gt;
&lt;/tt&gt;9&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }"&gt;user { 'xyz':&lt;tt&gt;
&lt;/tt&gt;   home =&amp;gt; '/home/xyz',&lt;tt&gt;
&lt;/tt&gt;   shell =&amp;gt; '/bin/bash',&lt;tt&gt;
&lt;/tt&gt;   uid =&amp;gt; '1000',&lt;tt&gt;
&lt;/tt&gt;   comment =&amp;gt; 'xyz,,,',&lt;tt&gt;
&lt;/tt&gt;   gid =&amp;gt; '1000',&lt;tt&gt;
&lt;/tt&gt;   groups =&amp;gt; ['adm','dialout','cdrom','sudo'],&lt;tt&gt;
&lt;/tt&gt;   ensure =&amp;gt; 'present'&lt;tt&gt;
&lt;/tt&gt;}&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;As you can see, in puppet you define how a system should look like.
Puppet figures out the rest.
In the example above, puppet makes sure that the user xyz is present.&lt;/p&gt;

&lt;p&gt;The resources can have dependencies.
The way these dependencies are managed one of the main differences to chef.
Puppet creates an internal graph of dependencies.
This way of calculating dependencies is called &lt;strong&gt;graph-based ordering&lt;/strong&gt;.
It then sends the RALsh to the nodes which act based on the it. &lt;/p&gt;

&lt;p&gt;There is also a Ruby API available.
This API, however, is hardly used and quite ugly.&lt;/p&gt;

&lt;p&gt;A short history excursion:
Luke Kanies is the guy who started puppet.
Before puppet, he was the one main contributor (besides the author) to &lt;a href="http://cfengine.com/"&gt;cfengine&lt;/a&gt;.
Cfengine used to be &lt;em&gt;THE&lt;/em&gt; CM Tool.
So why start puppet?&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;I made my living off of cfengine for a year or three and did everything I could to make it better, including writing the most widely published tutorials on it; in the end, my decision to rewrite was based on a development process that was essentially entirely closed to anything other than simple bug fixes. Even then, I would have forked but I didn’t think I could have worked with C productively, so I decided to pick a language I thought I’d be more productive in. - &lt;a href="http://www.krisbuytaert.be/blog/anybody-else-confused-about-chef"&gt;Luke Kanies&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Ok, at last some stats for you to interpret:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;github repository: 373 followers, 183 forks&lt;/li&gt;
  &lt;li&gt;irc channel: 514 members online&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;&lt;strong&gt;Links&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="http://muffinresearch.co.uk/archives/2009/01/18/puppet-server-configuration-made-easy/"&gt;puppet configuration made easy&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href="http://cfengine.com/"&gt;cfengine&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href="http://www.krisbuytaert.be/blog/anybody-else-confused-about-chef"&gt;article about chef with a great discussion in the comments&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;h2 id="chef"&gt;Chef&lt;/h2&gt;

&lt;p&gt;Like puppet, chef is written in Ruby.
The “programs” in chef are called &lt;strong&gt;recipes&lt;/strong&gt; and collected in cookbooks.
Recipes are written in a &lt;strong&gt;Ruby DSL&lt;/strong&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code class="language-ruby"&gt;&lt;table class="CodeRay"&gt;&lt;tr&gt;
&lt;td class="line_numbers" title="click to toggle" onclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }"&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;5&lt;tt&gt;
&lt;/tt&gt;6&lt;tt&gt;
&lt;/tt&gt;7&lt;tt&gt;
&lt;/tt&gt;8&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }"&gt;user &lt;span style="background-color:#fff0f0;color:#D20"&gt;&lt;span style="color:#710"&gt;"&lt;/span&gt;&lt;span style=""&gt;random&lt;/span&gt;&lt;span style="color:#710"&gt;"&lt;/span&gt;&lt;/span&gt; &lt;span style="color:#080;font-weight:bold"&gt;do&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  comment &lt;span style="background-color:#fff0f0;color:#D20"&gt;&lt;span style="color:#710"&gt;"&lt;/span&gt;&lt;span style=""&gt;Random User&lt;/span&gt;&lt;span style="color:#710"&gt;"&lt;/span&gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  uid &lt;span style="color:#00D;font-weight:bold"&gt;1000&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  gid &lt;span style="background-color:#fff0f0;color:#D20"&gt;&lt;span style="color:#710"&gt;"&lt;/span&gt;&lt;span style=""&gt;users&lt;/span&gt;&lt;span style="color:#710"&gt;"&lt;/span&gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  home &lt;span style="background-color:#fff0f0;color:#D20"&gt;&lt;span style="color:#710"&gt;"&lt;/span&gt;&lt;span style=""&gt;/home/random&lt;/span&gt;&lt;span style="color:#710"&gt;"&lt;/span&gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  shell &lt;span style="background-color:#fff0f0;color:#D20"&gt;&lt;span style="color:#710"&gt;"&lt;/span&gt;&lt;span style=""&gt;/bin/zsh&lt;/span&gt;&lt;span style="color:#710"&gt;"&lt;/span&gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  password &lt;span style="background-color:#fff0f0;color:#D20"&gt;&lt;span style="color:#710"&gt;"&lt;/span&gt;&lt;span style=""&gt;$1$JJsvHslV$szsCjVEroftprNn4JHtDi.&lt;/span&gt;&lt;span style="color:#710"&gt;"&lt;/span&gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span style="color:#080;font-weight:bold"&gt;end&lt;/span&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Like puppet, chef usually runs in a client/server mode.
However, &lt;code&gt;chef solo&lt;/code&gt; allows you to run chef recipes without a server.
Although not visible in the example above, chef defines actions to bring the system in a desired state.
This is contrary to puppets &lt;em&gt;“describe how the system should be”&lt;/em&gt;-mentality.
Here is better example than the user above:&lt;/p&gt;

&lt;pre&gt;&lt;code class="language-ruby"&gt;&lt;table class="CodeRay"&gt;&lt;tr&gt;
&lt;td class="line_numbers" title="click to toggle" onclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }"&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;5&lt;tt&gt;
&lt;/tt&gt;6&lt;tt&gt;
&lt;/tt&gt;7&lt;tt&gt;
&lt;/tt&gt;8&lt;tt&gt;
&lt;/tt&gt;9&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;10&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;11&lt;tt&gt;
&lt;/tt&gt;12&lt;tt&gt;
&lt;/tt&gt;13&lt;tt&gt;
&lt;/tt&gt;14&lt;tt&gt;
&lt;/tt&gt;15&lt;tt&gt;
&lt;/tt&gt;16&lt;tt&gt;
&lt;/tt&gt;17&lt;tt&gt;
&lt;/tt&gt;18&lt;tt&gt;
&lt;/tt&gt;19&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;20&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;21&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }"&gt;vim_dir = &lt;span style="color:#036;font-weight:bold"&gt;ENV&lt;/span&gt;[&lt;span style="background-color:#fff0f0;color:#D20"&gt;&lt;span style="color:#710"&gt;"&lt;/span&gt;&lt;span style=""&gt;HOME&lt;/span&gt;&lt;span style="color:#710"&gt;"&lt;/span&gt;&lt;/span&gt;] + &lt;span style="background-color:#fff0f0;color:#D20"&gt;&lt;span style="color:#710"&gt;"&lt;/span&gt;&lt;span style=""&gt;/.vim&lt;/span&gt;&lt;span style="color:#710"&gt;"&lt;/span&gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;script &lt;span style="background-color:#fff0f0;color:#D20"&gt;&lt;span style="color:#710"&gt;"&lt;/span&gt;&lt;span style=""&gt;clone dotvim from github&lt;/span&gt;&lt;span style="color:#710"&gt;"&lt;/span&gt;&lt;/span&gt; &lt;span style="color:#080;font-weight:bold"&gt;do&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;        interpreter &lt;span style="background-color:#fff0f0;color:#D20"&gt;&lt;span style="color:#710"&gt;"&lt;/span&gt;&lt;span style=""&gt;bash&lt;/span&gt;&lt;span style="color:#710"&gt;"&lt;/span&gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;        url = &lt;span style="background-color:#fff0f0;color:#D20"&gt;&lt;span style="color:#710"&gt;"&lt;/span&gt;&lt;span style=""&gt;http://github.com/rweng/dotvim.git&lt;/span&gt;&lt;span style="color:#710"&gt;"&lt;/span&gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;        code &lt;span style="background-color:#fff0f0;color:#D20"&gt;&lt;span style="color:#710"&gt;"&lt;/span&gt;&lt;span style=""&gt;git clone &lt;/span&gt;&lt;span style="background:#ddd;color:black"&gt;&lt;span style="background:#ddd;font-weight:bold;color:#666"&gt;#{&lt;/span&gt;url&lt;span style="background:#ddd;font-weight:bold;color:#666"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span style=""&gt; &lt;/span&gt;&lt;span style="background:#ddd;color:black"&gt;&lt;span style="background:#ddd;font-weight:bold;color:#666"&gt;#{&lt;/span&gt;vim_dir&lt;span style="background:#ddd;font-weight:bold;color:#666"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span style="color:#710"&gt;"&lt;/span&gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;        not_if { &lt;span style="color:#036;font-weight:bold"&gt;File&lt;/span&gt;.directory? vim_dir }&lt;tt&gt;
&lt;/tt&gt;&lt;span style="color:#080;font-weight:bold"&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;script &lt;span style="background-color:#fff0f0;color:#D20"&gt;&lt;span style="color:#710"&gt;"&lt;/span&gt;&lt;span style=""&gt;clone vundle from github&lt;/span&gt;&lt;span style="color:#710"&gt;"&lt;/span&gt;&lt;/span&gt; &lt;span style="color:#080;font-weight:bold"&gt;do&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  interpreter &lt;span style="background-color:#fff0f0;color:#D20"&gt;&lt;span style="color:#710"&gt;"&lt;/span&gt;&lt;span style=""&gt;bash&lt;/span&gt;&lt;span style="color:#710"&gt;"&lt;/span&gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  url = &lt;span style="background-color:#fff0f0;color:#D20"&gt;&lt;span style="color:#710"&gt;"&lt;/span&gt;&lt;span style=""&gt;http://github.com/gmarik/vundle.git&lt;/span&gt;&lt;span style="color:#710"&gt;"&lt;/span&gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;  code &lt;span style="background-color:#fff0f0;color:#D20"&gt;&lt;span style="color:#710"&gt;"&lt;/span&gt;&lt;span style=""&gt;git clone &lt;/span&gt;&lt;span style="background:#ddd;color:black"&gt;&lt;span style="background:#ddd;font-weight:bold;color:#666"&gt;#{&lt;/span&gt;url&lt;span style="background:#ddd;font-weight:bold;color:#666"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span style=""&gt; &lt;/span&gt;&lt;span style="background:#ddd;color:black"&gt;&lt;span style="background:#ddd;font-weight:bold;color:#666"&gt;#{&lt;/span&gt;vim_dir&lt;span style="background:#ddd;font-weight:bold;color:#666"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span style=""&gt;/bundle/vundle&lt;/span&gt;&lt;span style="color:#710"&gt;"&lt;/span&gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  not_if {&lt;span style="color:#036;font-weight:bold"&gt;File&lt;/span&gt;.directory? &lt;span style="background-color:#fff0f0;color:#D20"&gt;&lt;span style="color:#710"&gt;"&lt;/span&gt;&lt;span style="background:#ddd;color:black"&gt;&lt;span style="background:#ddd;font-weight:bold;color:#666"&gt;#{&lt;/span&gt;vim_dir&lt;span style="background:#ddd;font-weight:bold;color:#666"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span style=""&gt;/bundle/vundle&lt;/span&gt;&lt;span style="color:#710"&gt;"&lt;/span&gt;&lt;/span&gt; }&lt;tt&gt;
&lt;/tt&gt;&lt;span style="color:#080;font-weight:bold"&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;script &lt;span style="background-color:#fff0f0;color:#D20"&gt;&lt;span style="color:#710"&gt;"&lt;/span&gt;&lt;span style=""&gt;install vundles&lt;/span&gt;&lt;span style="color:#710"&gt;"&lt;/span&gt;&lt;/span&gt; &lt;span style="color:#080;font-weight:bold"&gt;do&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  interpreter &lt;span style="background-color:#fff0f0;color:#D20"&gt;&lt;span style="color:#710"&gt;"&lt;/span&gt;&lt;span style=""&gt;bash&lt;/span&gt;&lt;span style="color:#710"&gt;"&lt;/span&gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  code &lt;span style="background-color:#fff0f0;color:#D20"&gt;&lt;span style="color:#710"&gt;"&lt;/span&gt;&lt;span style=""&gt;vim -u &lt;/span&gt;&lt;span style="background:#ddd;color:black"&gt;&lt;span style="background:#ddd;font-weight:bold;color:#666"&gt;#{&lt;/span&gt;vim_dir&lt;span style="background:#ddd;font-weight:bold;color:#666"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span style=""&gt;/vundle.vim -U NONE +'silent! BundleInstall' +qall&lt;/span&gt;&lt;span style="color:#710"&gt;"&lt;/span&gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span style="color:#080;font-weight:bold"&gt;end&lt;/span&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The three script tags are applied one after another.
This is the way chef works:
Where puppet creates an internal dependency graph, dependency management in puppet is done by ordering the dependencies correctly in the recipe.
This is called &lt;strong&gt;procedural ordering&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;A quote from &lt;a href="http://www.engineyard.com/blog/2009/chef/"&gt;engineyard&lt;/a&gt;:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;The big advantage Chef has over Puppet is that the codebase is 1/10th the size and it is pure ruby, including the recipe DSL. Puppet’s biggest flaw is its configuration language that is not quite ruby and not quite turing complete. So you end up wrestling with it to get it to do anything.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="http://www.opscode.com/"&gt;Opscode&lt;/a&gt;, the main company behind chef, does not promote a distributed way of sharing cookbooks since &lt;a href="http://help.opscode.com/discussions/questions/531-installing-cookbooks-from-non-community-sites"&gt;it is against their business model&lt;/a&gt;.
However, there are &lt;a href="http://jetpackweb.com/blog/2011/06/12/manage-your-third-party-chef-cookbooks-with-knife-github-cookbooks/"&gt;some ways to keep track of remote cookbooks&lt;/a&gt;.
One I really like is &lt;a href="https://github.com/websterclay/knife-github-cookbooks"&gt;knife-github&lt;/a&gt;.
However, knife-github only works in a client/server setup.
And although Opscode does provide a chef-server for five nodes for free, you often just don’t want it.&lt;/p&gt;

&lt;p&gt;Now there are a couple of tools that make using chef-solo easier.
&lt;a href="https://github.com/tobami/littlechef"&gt;Littlechef&lt;/a&gt; is the one with the most github followers.
However, it is written in python.
But there are also tools for Ruby around.
I use a custom-made for setting up my OS X, virtual machines and server.
But this is something for a different post.&lt;/p&gt;

&lt;p&gt;Alright then, at last the infos about the community:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;github repository: 1131 followers, 520 forks&lt;/li&gt;
  &lt;li&gt;238 members inline in irc channel&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;&lt;strong&gt;Links&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="http://wiki.opscode.com/"&gt;chef wiki&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href="http://bhuga.net/2009/09/puppet-vs-chef"&gt;puppet vs chef&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href="http://www.kartar.net/2010/01/puppet-chef-deterministic-ordering-and-the-much-maligned-dsl/"&gt;puppet chef ordering and dsl discussion&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;h2 id="sprinkle"&gt;Sprinkle&lt;/h2&gt;

&lt;p&gt;Enough of the industries big shots.
Let’s get to easier tools for small clusters.
&lt;a href="https://github.com/crafterm/sprinkle"&gt;Sprinkle&lt;/a&gt; is such a tool.&lt;/p&gt;

&lt;p&gt;A couple of days ago, &lt;a href="http://engineering.gomiso.com/2011/08/26/forget-chef-or-puppet-automate-with-sprinkle/"&gt;Miso Engineering brought out a great post explaining Sprinke in depth&lt;/a&gt;.
It is also mentioned in &lt;a href="http://tech.favoritemedium.com/2011/09/deployment-automation-toolsframeworks.html"&gt;another CM tools comparing article&lt;/a&gt;.
I like the syntax and the way of abstracting packages.
The following example actually creates two packages, the package postgres, and the virtual package database:&lt;/p&gt;

&lt;pre&gt;&lt;code class="language-ruby"&gt;&lt;table class="CodeRay"&gt;&lt;tr&gt;
&lt;td class="line_numbers" title="click to toggle" onclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }"&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;5&lt;tt&gt;
&lt;/tt&gt;6&lt;tt&gt;
&lt;/tt&gt;7&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }"&gt;package &lt;span style="color:#A60"&gt;:postgres&lt;/span&gt;, &lt;span style="color:#A60"&gt;:provides&lt;/span&gt; =&amp;gt; &lt;span style="color:#A60"&gt;:database&lt;/span&gt; &lt;span style="color:#080;font-weight:bold"&gt;do&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  description &lt;span style="background-color:#fff0f0;color:#D20"&gt;&lt;span style="color:#710"&gt;"&lt;/span&gt;&lt;span style=""&gt;provides prostgres&lt;/span&gt;&lt;span style="color:#710"&gt;"&lt;/span&gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  version &lt;span style="background-color:#fff0f0;color:#D20"&gt;&lt;span style="color:#710"&gt;"&lt;/span&gt;&lt;span style=""&gt;1.1.1&lt;/span&gt;&lt;span style="color:#710"&gt;"&lt;/span&gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  source &lt;span style="background-color:#fff0f0;color:#D20"&gt;&lt;span style="color:#710"&gt;'&lt;/span&gt;&lt;span style=""&gt;http://example.com/postgres.tgz&lt;/span&gt;&lt;span style="color:#710"&gt;'&lt;/span&gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  requires &lt;span style="color:#A60"&gt;:build_essential&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  verify { has_executable &lt;span style="background-color:#fff0f0;color:#D20"&gt;&lt;span style="color:#710"&gt;'&lt;/span&gt;&lt;span style=""&gt;psql&lt;/span&gt;&lt;span style="color:#710"&gt;'&lt;/span&gt;&lt;/span&gt; }&lt;tt&gt;
&lt;/tt&gt;&lt;span style="color:#080;font-weight:bold"&gt;end&lt;/span&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Unfortunately, the commit rate at the &lt;a href="https://github.com/crafterm/sprinkle"&gt;github repository&lt;/a&gt; implies that the project is not heavily developed anymore.
In the time between May 17th and 21st of August there were no commits at all.&lt;/p&gt;

&lt;p&gt;I also miss the following features: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;a sprinkle folder to keep all packages and to install packages and policies without supplying the file where they are found&lt;/li&gt;
  &lt;li&gt;and a tighter integration with github repositories&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;So Sprinkle is nothing for me, but maybe for you?&lt;/p&gt;

&lt;h2 id="babushka"&gt;Babushka&lt;/h2&gt;

&lt;p&gt;As you can see in my &lt;a href="git@github.com:rweng/babushka-deps.git"&gt;deps repo&lt;/a&gt;, &lt;a href="http://babushka.me/"&gt;Babushka&lt;/a&gt; is the tool that I have explored most (together with chef).
Babushkas awesome strength is that it is incredibly easy to write own deps and make them based on some other, foreign deps.
But first things first:
To install babushka you copy a one-liner from &lt;a href="http://babushka.me/"&gt;babushka.me&lt;/a&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;bash -c "`curl babushka.me/up`"
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This installs babushka on your system.
After that you can start creating own deps by putting any ruby files in the &lt;code&gt;~/.babushka/deps&lt;/code&gt; directory.&lt;/p&gt;

&lt;pre&gt;&lt;code class="language-ruby"&gt;&lt;table class="CodeRay"&gt;&lt;tr&gt;
&lt;td class="line_numbers" title="click to toggle" onclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }"&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;5&lt;tt&gt;
&lt;/tt&gt;6&lt;tt&gt;
&lt;/tt&gt;7&lt;tt&gt;
&lt;/tt&gt;8&lt;tt&gt;
&lt;/tt&gt;9&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;10&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;11&lt;tt&gt;
&lt;/tt&gt;12&lt;tt&gt;
&lt;/tt&gt;13&lt;tt&gt;
&lt;/tt&gt;14&lt;tt&gt;
&lt;/tt&gt;15&lt;tt&gt;
&lt;/tt&gt;16&lt;tt&gt;
&lt;/tt&gt;17&lt;tt&gt;
&lt;/tt&gt;18&lt;tt&gt;
&lt;/tt&gt;19&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;20&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;21&lt;tt&gt;
&lt;/tt&gt;22&lt;tt&gt;
&lt;/tt&gt;23&lt;tt&gt;
&lt;/tt&gt;24&lt;tt&gt;
&lt;/tt&gt;25&lt;tt&gt;
&lt;/tt&gt;26&lt;tt&gt;
&lt;/tt&gt;27&lt;tt&gt;
&lt;/tt&gt;28&lt;tt&gt;
&lt;/tt&gt;29&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;30&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;31&lt;tt&gt;
&lt;/tt&gt;32&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }"&gt;dep &lt;span style="background-color:#fff0f0;color:#D20"&gt;&lt;span style="color:#710"&gt;"&lt;/span&gt;&lt;span style=""&gt;babushka switched&lt;/span&gt;&lt;span style="color:#710"&gt;"&lt;/span&gt;&lt;/span&gt; &lt;span style="color:#080;font-weight:bold"&gt;do&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;span style="color:#888"&gt;# if we would require other deps, we could do this like this:&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;span style="color:#888"&gt;# requires "other dep", "github-user:other dep"&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;span style="color:#888"&gt;# once the variable user is used, &lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;span style="color:#888"&gt;# babushka asks the user for the value and remembers it&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  define_var &lt;span style="color:#A60"&gt;:user&lt;/span&gt;, &lt;span style="color:#A60"&gt;:default&lt;/span&gt; =&amp;gt; &lt;span style="background-color:#fff0f0;color:#D20"&gt;&lt;span style="color:#710"&gt;"&lt;/span&gt;&lt;span style=""&gt;benhoskings&lt;/span&gt;&lt;span style="color:#710"&gt;"&lt;/span&gt;&lt;/span&gt;, &lt;tt&gt;
&lt;/tt&gt;   &lt;span style="color:#A60"&gt;:message&lt;/span&gt; =&amp;gt; &lt;span style="background-color:#fff0f0;color:#D20"&gt;&lt;span style="color:#710"&gt;"&lt;/span&gt;&lt;span style=""&gt;Which github users babushka do you want to use?&lt;/span&gt;&lt;span style="color:#710"&gt;"&lt;/span&gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;span style="color:#888"&gt;# we can put arbitrary ruby code in our deps, like this little helper method&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;span style="color:#080;font-weight:bold"&gt;def&lt;/span&gt; &lt;span style="color:#06B;font-weight:bold"&gt;babushka_path&lt;/span&gt;; &lt;span style="background-color:#fff0f0;color:#D20"&gt;&lt;span style="color:#710"&gt;"&lt;/span&gt;&lt;span style=""&gt;/usr/local/babushka&lt;/span&gt;&lt;span style="color:#710"&gt;"&lt;/span&gt;&lt;/span&gt;; &lt;span style="color:#080;font-weight:bold"&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;span style="color:#888"&gt;# the met? block tests, if the dependency is already satisfied.&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;span style="color:#888"&gt;# in this case we cd into the babushka path and check, if the origin of the&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;span style="color:#888"&gt;# babushka repository is set to the users github repository&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  met? &lt;span style="color:#080;font-weight:bold"&gt;do&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    cd babushka_path &lt;span style="color:#080;font-weight:bold"&gt;do&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;      shell(&lt;span style="background-color:#fff0f0;color:#D20"&gt;&lt;span style="color:#710"&gt;"&lt;/span&gt;&lt;span style=""&gt;git remote -v&lt;/span&gt;&lt;span style="color:#710"&gt;"&lt;/span&gt;&lt;/span&gt;)[&lt;span style="background-color:#fff0ff"&gt;&lt;span style="color:#404"&gt;/&lt;/span&gt;&lt;span style="color:#808"&gt;^origin.+&lt;/span&gt;&lt;span style="color:#04D"&gt;\/&lt;/span&gt;&lt;span style="background:#ddd;color:black"&gt;&lt;span style="background:#ddd;font-weight:bold;color:#666"&gt;#{&lt;/span&gt;var &lt;span style="color:#A60"&gt;:user&lt;/span&gt;&lt;span style="background:#ddd;font-weight:bold;color:#666"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span style="color:#04D"&gt;\/&lt;/span&gt;&lt;span style="color:#808"&gt;.+$&lt;/span&gt;&lt;span style="color:#404"&gt;/&lt;/span&gt;&lt;/span&gt;]&lt;tt&gt;
&lt;/tt&gt;    &lt;span style="color:#080;font-weight:bold"&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;span style="color:#080;font-weight:bold"&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;span style="color:#888"&gt;# met? returns something == false, then execute the meet block&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;span style="color:#888"&gt;# after the meet block got executed, the met? block is run again&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;span style="color:#888"&gt;# to ensure that the dep is now satisfied&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  meet &lt;span style="color:#080;font-weight:bold"&gt;do&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    cd babushka_path &lt;span style="color:#080;font-weight:bold"&gt;do&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;      shell &lt;span style="background-color:#fff0f0;color:#D20"&gt;&lt;span style="color:#710"&gt;"&lt;/span&gt;&lt;span style=""&gt;git remote set-url origin git://github.com/&lt;/span&gt;&lt;span style="background:#ddd;color:black"&gt;&lt;span style="background:#ddd;font-weight:bold;color:#666"&gt;#{&lt;/span&gt;var &lt;span style="color:#A60"&gt;:user&lt;/span&gt;&lt;span style="background:#ddd;font-weight:bold;color:#666"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span style=""&gt;/babushka.git&lt;/span&gt;&lt;span style="color:#710"&gt;"&lt;/span&gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span style="color:#080;font-weight:bold"&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;span style="color:#080;font-weight:bold"&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span style="color:#080;font-weight:bold"&gt;end&lt;/span&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;If this dependency is in your &lt;code&gt;~/.babushka/deps&lt;/code&gt; folder, you can run it with &lt;code&gt;babushka "babushka switched"&lt;/code&gt;.
But the really cool thing is that you can also run it directly from github by putting the github user name before the dep name.
In this case: &lt;code&gt;babushka "rweng:babushka switched"&lt;/code&gt;.
My &lt;em&gt;babushka-deps&lt;/em&gt; repository will be cloned in &lt;code&gt;~/.babushka/sources/rweng&lt;/code&gt; and then the dep will be executed.
If it doesn’t work, just copy the code over to your deps directory or call &lt;code&gt;babushka edit "rweng:babushka switched"&lt;/code&gt; to directly jump with your editor to the dep.
Is that cool or what?&lt;/p&gt;

&lt;p&gt;Now the other neat feature of babushka is the way to discover deps.
Let’s say I am looking for a way to install nginx on my server.
I execute &lt;code&gt;babushka search nginx&lt;/code&gt; to get an overview over the public deps that contain the word nginx.
The output even contains the success rate of installations.&lt;/p&gt;

&lt;p&gt;However, right now babushkas codebase is a mess.
The only developer is ben hoskings who does this project occasionally in his spare time.
Another problem is that there is no way to specify a maintainer, a version or a more detailed description in the deps.&lt;/p&gt;

&lt;h2 id="other-tools"&gt;Other Tools&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://github.com/devstructure/blueprint"&gt;Blueprint&lt;/a&gt; comes in handy if you have a server and you got to scale.
With blueprint you can easily make a snapshot of installed packages and configurations of one server and apply them on another one.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/DAddYE/do"&gt;Do&lt;/a&gt; is an incredibly lightweight framework for running some commands on the server, uploading a file, and so on.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://gitpusshuten.com/"&gt;Gitpusshuden&lt;/a&gt; is a git-based deployment framework.
Check out the 7 min introduction on &lt;a href="http://gitpusshuten.com/"&gt;their website&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Oh, and there is also &lt;a href="https://github.com/railsmachine/moonshine"&gt;Moonshine&lt;/a&gt; which basically only sets up a Rails Stack automatically.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Links&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="http://tech.favoritemedium.com/2011/09/deployment-automation-toolsframeworks.html"&gt;article comparing chef, puppet, babushka, sprinkle, gitpusshuden&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;img src="http://feeds.feedburner.com/~r/robin-wenglewski/~4/0tUC1mELr_I" height="1" width="1"/&gt;</content>
  <feedburner:origLink>http://robin.wenglewski.de/posts/2011/09/07/configuration-management/</feedburner:origLink></entry>
</feed>

