<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:sy="http://purl.org/rss/1.0/modules/syndication/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0">

<channel>
	<title>warwickp.com</title>
	
	<link>http://warwickp.com</link>
	<description>Warwick Poole interwebs</description>
	<lastBuildDate>Mon, 14 Jun 2010 17:30:50 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/warwickp" /><feedburner:info uri="warwickp" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><item>
		<title>Debugging Rails processes under Phusion Passenger with nginx</title>
		<link>http://feedproxy.google.com/~r/warwickp/~3/buJozbjaCKk/</link>
		<comments>http://warwickp.com/2010/06/debugging-rails-processes-under-phusion-passenger-with-nginx/#comments</comments>
		<pubDate>Mon, 14 Jun 2010 15:55:18 +0000</pubDate>
		<dc:creator>warwickp</dc:creator>
				<category><![CDATA[infrastructure]]></category>

		<guid isPermaLink="false">http://warwickp.com/?p=413</guid>
		<description><![CDATA[If you are involved in web operations you&#8217;ll no doubt be familiar with this problem: Everything is running along smoothly and suddenly an anomalous load spike occurs which does not correlate to a traffic spike or any problem on which you have any data. Last week this very thing occurred in a mature Rails application [...]]]></description>
			<content:encoded><![CDATA[<p>If you are involved in web operations you&#8217;ll no doubt be familiar with this problem: Everything is running along smoothly and suddenly an anomalous load spike occurs which does not correlate to a traffic spike or any problem on which you have any data. Last week this very thing occurred in a mature Rails application which runs under <a href="http://www.modrails.com/">Phusion Passenger</a> on <a href="http://nginx.org/">nginx</a>. The initial symptom was a rapid CPU spike (Rails processes in user space) and then Rails processes becoming stuck on a single request. This rapidly brought on a typical web server death spiral: Increasing CPU usage, increasing memory usage, eventually swapping occurs and/or the application server runs ouf of available processes in the pool. Frustrated users hit refresh and the issue compounds.</p>
<div id="attachment_415" class="wp-caption aligncenter" style="width: 424px"><img class="size-full wp-image-415" title="web_load-1" src="http://warwickp.com/wp-content/uploads/2010/06/web_load-1.jpg" alt="" width="414" height="228" /><p class="wp-caption-text">Anomalous load spike</p></div>
<p>In my experience the order of likely causes of a problem goes like this: Buggy code recently deployed, large and expensive reports being run, or network (or firewall) problems causing processes to hang on IO operations. How to troubleshoot this problem on Passenger?</p>
<p>Checking the output of <a href="http://modrails.com/documentation/Users%20guide%20Nginx.html#_inspecting_phusion_passenger_8217_s_internal_status">passenger-status</a> we were seeing Rails processes not completing requests, the &#8220;Processed&#8221; column for certain Rails processes were not incrementing, indicating these processes were somehow stuck, thereby decreasing the pool of available processes for subsequent requests. Attaching to these stuck processes with <a href="http://linux.die.net/man/1/strace">strace</a> revealed no activity in the process at all. Similarly, using <a href="http://github.com/tmm1/gdb.rb">gdb.rb</a> revealed nothing immediately useful. Strangely we were seeing some Rails processes continuing to run even after they were no longer being actively managed by Passenger, at least according to the output of passenger-status, in which these processes no longer appeared.</p>
<p>First I upgraded Passenger (using <a href="http://www.opscode.com/chef/">Chef</a>, of course) to the latest version on one server, to see if there was a Passenger bug causing this problem. The issue persisted. Making things a bit more complicated we had recently moved a <a href="http://memcached.org/">memcached</a> instance to a different part of the network, and all the stuck Rails processes had open network connections to this memcached instance, leading me to wonder if it was this network IO which was somehow causing the Rails process to hang. I could find no problems between the application servers and the memcached port and no logs of any network issues there. So what are the stuck Rails processes stuck on?</p>
<p>The way to troubleshoot this problem on Passenger is to  <strong>issue a </strong><a href="http://modrails.com/documentation/Users%20guide%20Nginx.html#debugging_frozen"><strong>kill -SIGABRT</strong></a><strong> to the stuck Rails processes</strong>, and find their backtrace in the Rails log. Looking at the backtraces we were able to track the issue down to a bug in a Ruby gem which was being used to generate certain types of reports. Disabling this reporting prevented new occurrences of the problem until the underlying issue can be resolved. An interesting combination of two usual suspects: Reporting and code library bugs.</p>
<img src="http://feeds.feedburner.com/~r/warwickp/~4/buJozbjaCKk" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://warwickp.com/2010/06/debugging-rails-processes-under-phusion-passenger-with-nginx/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://warwickp.com/2010/06/debugging-rails-processes-under-phusion-passenger-with-nginx/</feedburner:origLink></item>
		<item>
		<title>Vodafone / Vodacom 3G in South Africa</title>
		<link>http://feedproxy.google.com/~r/warwickp/~3/agmVAToR-FM/</link>
		<comments>http://warwickp.com/2010/05/vodafone-vodacom-3g-in-south-africa/#comments</comments>
		<pubDate>Mon, 17 May 2010 13:50:20 +0000</pubDate>
		<dc:creator>warwickp</dc:creator>
				<category><![CDATA[travel]]></category>

		<guid isPermaLink="false">http://warwickp.com/?p=409</guid>
		<description><![CDATA[I&#8217;m in South Africa for 2 weeks and am using a Vodafone Huawei USB 3G card on my Macbook Pro with Snow Leopard. Here are a few tips I found useful:
Brandon West&#8217;s post was very useful in getting started.
Summary: Download and install VodafoneMCInstaller then add the 3G card as a network interface and change the [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;m in South Africa for 2 weeks and am using a Vodafone Huawei USB 3G card on my Macbook Pro with Snow Leopard. Here are a few tips I found useful:</p>
<p>Brandon West&#8217;s <a href="http://brandonmwest.com/hardware/using-a-vodacomvodafone-3g-card-on-mac-os-x">post</a> was very useful in getting started.</p>
<p>Summary: Download and install <a href="http://www.vodacom4me.co.za/vodacom4me-personal-resources/downloads/vodacom/VodafoneMCInstaller.2.11.04.00.dmg.zip">VodafoneMCInstaller</a> then add the 3G card as a network interface and change the settings as mentioned in Brandon&#8217;s post.</p>
<p>To get online you&#8217;ll need to open the Vodafone application, and use the 3G card&#8217;s pin number to Activate your modem every time you connect. Once activated, you need to then dial up the modem using the Network panel in System Preferences.</p>
<p>Because your Vodacom 3G account is a metered account, and I&#8217;m not used to conserving bandwidth in any way, I found <a href="http://www.skoobysoft.com/utilities/utilities.html#surplusmeter">SurplusMeter</a> very useful to watch my usage.</p>
<p><img src="http://img.skitch.com/20100517-cgwhsc1m9ea8hc1cjkn2g5a8sx.jpg" alt="SurplusMeter for Vodacom 3G card" /></p>
<img src="http://feeds.feedburner.com/~r/warwickp/~4/agmVAToR-FM" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://warwickp.com/2010/05/vodafone-vodacom-3g-in-south-africa/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://warwickp.com/2010/05/vodafone-vodacom-3g-in-south-africa/</feedburner:origLink></item>
		<item>
		<title>Ruby self-throttling Nagios alerts</title>
		<link>http://feedproxy.google.com/~r/warwickp/~3/ZaJzh8XTPdw/</link>
		<comments>http://warwickp.com/2010/03/ruby-self-throttling-nagios-alerts/#comments</comments>
		<pubDate>Fri, 19 Mar 2010 15:27:22 +0000</pubDate>
		<dc:creator>warwickp</dc:creator>
				<category><![CDATA[monitoring]]></category>
		<category><![CDATA[nagios]]></category>

		<guid isPermaLink="false">http://warwickp.com/?p=397</guid>
		<description><![CDATA[If you use Nagios no doubt you&#8217;ve experienced a situation where a network issue has triggered an alert on every service on every server. There are a few ways to deal with this in Nagios, but after spending 10 minutes deleting SMS messages on my iPhone I decided to implement an alert system which will [...]]]></description>
			<content:encoded><![CDATA[<p>If you use <a href="http://www.nagios.org/">Nagios</a> no doubt you&#8217;ve experienced a situation where a network issue has triggered an alert on every service on every server. There are a few ways to deal with this in Nagios, but after spending 10 minutes deleting SMS messages on my iPhone I decided to implement an alert system which will self throttle and not allow a gigantic flood of alerts.</p>
<p>In Nagios I created 2 notify commands, one for host notifications and another for service notifications:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #666666; font-style: italic;"># 'notify-throttle-host' command definition</span>
define <span style="color: #7a0874; font-weight: bold;">command</span><span style="color: #7a0874; font-weight: bold;">&#123;</span>
	command_name    notify-throttle-host
	command_line    <span style="color: #000000; font-weight: bold;">/</span>usr<span style="color: #000000; font-weight: bold;">/</span>local<span style="color: #000000; font-weight: bold;">/</span>bin<span style="color: #000000; font-weight: bold;">/</span>ruby <span style="color: #007800;">$USER1</span>$<span style="color: #000000; font-weight: bold;">/</span>throttle_alert.rb <span style="color: #ff0000;">&quot;<span style="color: #007800;">$CONTACTEMAIL</span>$&quot;</span> <span style="color: #ff0000;">&quot;[nagios] <span style="color: #007800;">$NOTIFICATIONTYPE</span>$ Host: <span style="color: #007800;">$HOSTNAME</span>$ <span style="color: #007800;">$HOSTSTATE</span>$&quot;</span> <span style="color: #ff0000;">&quot;at <span style="color: #007800;">$LONGDATETIME</span>$ <span style="color: #000099; font-weight: bold;">\n</span><span style="color: #000099; font-weight: bold;">\n</span> <span style="color: #007800;">$NOTIFICATIONTYPE</span>$ : <span style="color: #007800;">$HOSTNAME</span>$ (<span style="color: #007800;">$HOSTADDRESS</span>$) is <span style="color: #007800;">$HOSTSTATE</span>$ <span style="color: #000099; font-weight: bold;">\n</span><span style="color: #000099; font-weight: bold;">\n</span>: <span style="color: #007800;">$HOSTOUTPUT</span>$ <span style="color: #000099; font-weight: bold;">\n</span>&quot;</span>
<span style="color: #7a0874; font-weight: bold;">&#125;</span>
&nbsp;
<span style="color: #666666; font-style: italic;"># 'notify-throttle-service' command definition</span>
define <span style="color: #7a0874; font-weight: bold;">command</span><span style="color: #7a0874; font-weight: bold;">&#123;</span>
	command_name    notify-throttle-service
	command_line    <span style="color: #000000; font-weight: bold;">/</span>usr<span style="color: #000000; font-weight: bold;">/</span>local<span style="color: #000000; font-weight: bold;">/</span>bin<span style="color: #000000; font-weight: bold;">/</span>ruby <span style="color: #007800;">$USER1</span>$<span style="color: #000000; font-weight: bold;">/</span>throttle_alert.rb <span style="color: #ff0000;">&quot;<span style="color: #007800;">$CONTACTEMAIL</span>$&quot;</span> <span style="color: #ff0000;">&quot;[nagios] <span style="color: #007800;">$NOTIFICATIONTYPE</span>$ Service: <span style="color: #007800;">$HOSTALIAS</span>$/<span style="color: #007800;">$SERVICEDESC</span>$ is <span style="color: #007800;">$SERVICESTATE</span>$&quot;</span> <span style="color: #ff0000;">&quot;at <span style="color: #007800;">$LONGDATETIME</span>$ <span style="color: #000099; font-weight: bold;">\n</span><span style="color: #000099; font-weight: bold;">\n</span> <span style="color: #007800;">$NOTIFICATIONTYPE</span>$ : Service <span style="color: #007800;">$SERVICEDESC</span>$ on <span style="color: #007800;">$HOSTALIAS</span>$ (<span style="color: #007800;">$HOSTADDRESS</span>$) is <span style="color: #007800;">$SERVICESTATE</span>$ <span style="color: #000099; font-weight: bold;">\n</span><span style="color: #000099; font-weight: bold;">\n</span>: <span style="color: #007800;">$SERVICEOUTPUT</span>$ <span style="color: #000099; font-weight: bold;">\n</span>&quot;</span>
<span style="color: #7a0874; font-weight: bold;">&#125;</span></pre></div></div>

<p>Then throttle_alert.rb uses a control file to determine how long it has been since the previous alert, and will redirect alerts to a secondary (non-SMS) email address (and note the throttling in the alert itself) if an alert occurs inside the throttled window (90 seconds in this example):</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#008000; font-style:italic;">#!/usr/bin/env ruby -rubygems</span>
<span style="color:#008000; font-style:italic;">############################################################</span>
<span style="color:#008000; font-style:italic;"># throttle the notifications we send</span>
<span style="color:#008000; font-style:italic;"># get 3 arguments</span>
<span style="color:#008000; font-style:italic;"># &quot;EMAIL&quot; &quot;SUBJECT&quot; &quot;BODY&quot;</span>
<span style="color:#008000; font-style:italic;">############################################################</span>
&nbsp;
<span style="color:#9966CC; font-weight:bold;">unless</span> ARGV.<span style="color:#9900CC;">length</span> == <span style="color:#006666;">3</span>
  <span style="color:#CC0066; font-weight:bold;">puts</span> <span style="color:#996600;">&quot;usage: &lt;&gt; email subject body&quot;</span>
  <span style="color:#CC0066; font-weight:bold;">exit</span>
<span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
minimum_wait_time = <span style="color:#006666;">90</span>   <span style="color:#008000; font-style:italic;">#seconds before we can alert again</span>
alternative_email = <span style="color:#996600;">&quot;secondary-email@yourdomain.com&quot;</span> <span style="color:#008000; font-style:italic;">#send throttled alerts here when silenced</span>
&nbsp;
emailto = ARGV<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#006666;">0</span><span style="color:#006600; font-weight:bold;">&#93;</span>
subject = ARGV<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#006666;">1</span><span style="color:#006600; font-weight:bold;">&#93;</span>
details = ARGV<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#006666;">2</span><span style="color:#006600; font-weight:bold;">&#93;</span>
&nbsp;
email_p = emailto.<span style="color:#CC0066; font-weight:bold;">gsub</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">&quot;@&quot;</span>, <span style="color:#996600;">&quot;_&quot;</span><span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#CC0066; font-weight:bold;">gsub</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">&quot;.&quot;</span>, <span style="color:#996600;">&quot;_&quot;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
&nbsp;
&nbsp;
control_file = <span style="color:#996600;">&quot;/tmp/throttle_nagios_#{email_p}.txt&quot;</span>
mailer_cmd = <span style="color:#996600;">&quot;/usr/bin/mail&quot;</span>
&nbsp;
<span style="color:#9966CC; font-weight:bold;">if</span> <span style="color:#CC00FF; font-weight:bold;">File</span>.<span style="color:#9900CC;">exists</span>?<span style="color:#006600; font-weight:bold;">&#40;</span>control_file<span style="color:#006600; font-weight:bold;">&#41;</span>
  file_age = <span style="color:#CC00FF; font-weight:bold;">File</span>.<span style="color:#9900CC;">mtime</span><span style="color:#006600; font-weight:bold;">&#40;</span>control_file<span style="color:#006600; font-weight:bold;">&#41;</span>
  value = <span style="color:#CC00FF; font-weight:bold;">Time</span>.<span style="color:#9900CC;">now</span> <span style="color:#006600; font-weight:bold;">-</span> file_age
  file_age_nice = <span style="color:#CC0066; font-weight:bold;">sprintf</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">&quot;%1.1f&quot;</span>, value<span style="color:#006600; font-weight:bold;">&#41;</span>
&nbsp;
  <span style="color:#9966CC; font-weight:bold;">unless</span> file_age_nice.<span style="color:#9900CC;">to_f</span> <span style="color:#006600; font-weight:bold;">&gt;</span> minimum_wait_time.<span style="color:#9900CC;">to_f</span>
    <span style="color:#CC0066; font-weight:bold;">system</span> <span style="color:#996600;">&quot;/usr/bin/printf '%b' '#{details} (throttled due to a #{control_file} #{file_age_nice}s old' | #{mailer_cmd} -s '#{subject}' #{alternative_email}&quot;</span>
    <span style="color:#CC00FF; font-weight:bold;">Process</span>.<span style="color:#CC0066; font-weight:bold;">exit</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
<span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
<span style="color:#CC0066; font-weight:bold;">system</span> <span style="color:#996600;">&quot;touch #{control_file}&quot;</span>
<span style="color:#CC0066; font-weight:bold;">system</span> <span style="color:#996600;">&quot;/usr/bin/printf '%b' '#{details}' | #{mailer_cmd} -s '#{subject}' #{emailto}&quot;</span></pre></div></div>

<p>Not rocket science and not perfect but it works to prevent draining my iPhone battery in a single incident.</p>
<img src="http://feeds.feedburner.com/~r/warwickp/~4/ZaJzh8XTPdw" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://warwickp.com/2010/03/ruby-self-throttling-nagios-alerts/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://warwickp.com/2010/03/ruby-self-throttling-nagios-alerts/</feedburner:origLink></item>
		<item>
		<title>Configuration Management with Chef on Debian, Part 2</title>
		<link>http://feedproxy.google.com/~r/warwickp/~3/LjqC47ezetA/</link>
		<comments>http://warwickp.com/2010/01/configuration-management-with-chef-on-debian-part-2/#comments</comments>
		<pubDate>Sat, 09 Jan 2010 23:50:53 +0000</pubDate>
		<dc:creator>warwickp</dc:creator>
				<category><![CDATA[opschef]]></category>

		<guid isPermaLink="false">http://warwickp.com/?p=309</guid>
		<description><![CDATA[At Harvest we are working on putting Chef into production use rapidly. In part 1 I gave you an overview of how to get your Chef server and client installed. There wasn&#8217;t anything really Chefy in that post. In fact, some of the things in that post were done in a decidedly un-Cheflike manor. Seven [...]]]></description>
			<content:encoded><![CDATA[<p>At <a href="http://www.getharvest.com/">Harvest</a> we are working on putting Chef into production use rapidly. <img class="size-full wp-image-349 alignleft" title="Chef" src="http://warwickp.com/wp-content/uploads/2010/01/ratatouille_skinner-e1263074683907.jpg" alt="" width="27" height="49" />In <a href="http://warwickp.com/2009/12/configuration-management-with-chef-on-debian-part-1/">part 1</a> I gave you an overview of how to get your <a href="http://www.opscode.com/chef/">Chef</a> server and client installed. There wasn&#8217;t anything really Chefy in that post. In fact, some of the things in that post were done in a decidedly un-Cheflike manor. Seven lashings for me. Let&#8217;s look now at getting a first basic configuration task done with Chef.</p>
<p><img class="alignright size-full wp-image-341" src="http://warwickp.com/wp-content/uploads/2010/01/2781703346_f56bb0cf70-e1263045165651.jpg" alt="No hands" width="80" height="80" />Previously we installed Chef from the <a href="http://www.opscode.com/">Opscode</a> Debian packages and then replaced the Chef server URL in the Chef client configuration with <a href="http://www.gnu.org/software/sed/">sed</a> so that we could register and validate the Chef client with the Chef server for the first time. This obviously won&#8217;t do, we need to manage all configuration files properly without little post-installation hacks in them. That is a core idea of the Chef. So let&#8217;s now take control of the Chef client configuration files themselves with Chef.</p>
<p>To do this we need to create a Chef cookbook called &#8220;chef&#8221; in our repo, in this cookbook we will create a recipe called &#8220;client&#8221; to handle the client stuff (as opposed to the Chef server stuff which can live happily side by side in the same cookbook but in different recipes), then we need to assign the Chef client recipe to a role (which we will call something like &#8220;base&#8221; because we are going to add it to all servers) and lastly we need to add that &#8220;base&#8221; role to our 2 nodes we have. Let&#8217;s <a href="http://en.wikipedia.org/wiki/Tim_Gunn">make it work, people</a>.</p>
<p><img class="alignleft size-full wp-image-330" title="rake" src="http://warwickp.com/wp-content/uploads/2010/01/Bunker_Rake1-e1263045032406.gif" alt="Rake it like it's 1990" width="80" height="126" />My workflow right now is to have my Chef Git repo cloned on my local Mac and to work in there, then commit to this repo and push it to our origin. Then I login to the Chef server, which has it&#8217;s own clone of the same repo on it, and then use Rake to pull the latest Git changes down and install them into the Chef server directories.</p>
<p>So on my local Mac, lets create the skeleton dir structure for this new cookbook of ours. You could use Rake for this (<code>rake new_cookbook COOKBOOK=chef)</code> but where&#8217;s the fun in letting someone else do all the menial labor for you?</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">git clone git<span style="color: #000000; font-weight: bold;">@</span>yourgitserver.yourdomain.com:your_chef_repo.git
<span style="color: #7a0874; font-weight: bold;">cd</span> your_chef_repo
<span style="color: #c20cb9; font-weight: bold;">mkdir</span> <span style="color: #660033;">-p</span> cookbooks<span style="color: #000000; font-weight: bold;">/</span>chef<span style="color: #000000; font-weight: bold;">/</span>attributes
<span style="color: #c20cb9; font-weight: bold;">mkdir</span> <span style="color: #660033;">-p</span> cookbooks<span style="color: #000000; font-weight: bold;">/</span>chef<span style="color: #000000; font-weight: bold;">/</span>templates<span style="color: #000000; font-weight: bold;">/</span>default
<span style="color: #c20cb9; font-weight: bold;">mkdir</span> <span style="color: #660033;">-p</span> cookbooks<span style="color: #000000; font-weight: bold;">/</span>chef<span style="color: #000000; font-weight: bold;">/</span>recipes</pre></div></div>

<p>Now let&#8217;s first define the attributes of our Chef client configuration. These are basically the values which we want in our config files. What we will now do is create some default values, which can be overridden in other places if we ever needed specific Chef client settings to be different on different servers for some reason.</p>
<p>Here is our barebones cookbooks/chef/attributes/chef.rb</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">set_unless<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:chef</span><span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:server_fqdn</span><span style="color:#006600; font-weight:bold;">&#93;</span>     = <span style="color:#996600;">&quot;chef.yourdomain.com&quot;</span>
set_unless<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:chef</span><span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:server_port</span><span style="color:#006600; font-weight:bold;">&#93;</span>     = <span style="color:#996600;">&quot;4000&quot;</span>
set_unless<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:chef</span><span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:openid_port</span><span style="color:#006600; font-weight:bold;">&#93;</span>     = <span style="color:#996600;">&quot;4001&quot;</span>
set_unless<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:chef</span><span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:log</span><span style="color:#006600; font-weight:bold;">&#93;</span>             = <span style="color:#996600;">&quot;/var/log/chef/client.log&quot;</span>
set_unless<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:chef</span><span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:log_level</span><span style="color:#006600; font-weight:bold;">&#93;</span>       = <span style="color:#996600;">&quot;debug&quot;</span>
set_unless<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:chef</span><span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:filecache</span><span style="color:#006600; font-weight:bold;">&#93;</span>       = <span style="color:#996600;">&quot;/var/cache/chef&quot;</span>
set_unless<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:chef</span><span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:pid</span><span style="color:#006600; font-weight:bold;">&#93;</span>             = <span style="color:#996600;">&quot;/var/run/chef/client.pid&quot;</span></pre></div></div>

<p>Now, we need a template file, which is an <a href="http://www.ruby-doc.org/stdlib/libdoc/erb/rdoc/">ERB</a> template, which our recipe will use to make these dreamy attributes appear on the filesystem somewhere in a fully cooked configuration file.</p>
<p>This is what our cookbooks/chef/templates/default/client.erb looks like:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">log_level          <span style="color:#006600; font-weight:bold;">&lt;%</span>= <span style="color:#0066ff; font-weight:bold;">@node</span><span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:chef</span><span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:log_level</span><span style="color:#006600; font-weight:bold;">&#93;</span> <span style="color:#006600; font-weight:bold;">%&gt;</span>
log_location       &quot;<span style="color:#006600; font-weight:bold;">&lt;%</span>= <span style="color:#0066ff; font-weight:bold;">@node</span><span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:chef</span><span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:log</span><span style="color:#006600; font-weight:bold;">&#93;</span> <span style="color:#006600; font-weight:bold;">%&gt;</span>&quot;
&nbsp;
ssl_verify_mode    :verify_none
&nbsp;
registration_url   &quot;http://<span style="color:#006600; font-weight:bold;">&lt;%</span>= <span style="color:#0066ff; font-weight:bold;">@node</span><span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:chef</span><span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:server_fqdn</span><span style="color:#006600; font-weight:bold;">&#93;</span> <span style="color:#006600; font-weight:bold;">%&gt;</span>:<span style="color:#006600; font-weight:bold;">&lt;%</span>= <span style="color:#0066ff; font-weight:bold;">@node</span><span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:chef</span><span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:server_port</span><span style="color:#006600; font-weight:bold;">&#93;</span> <span style="color:#006600; font-weight:bold;">%&gt;</span>&quot;
openid_url         &quot;http://<span style="color:#006600; font-weight:bold;">&lt;%</span>= <span style="color:#0066ff; font-weight:bold;">@node</span><span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:chef</span><span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:server_fqdn</span><span style="color:#006600; font-weight:bold;">&#93;</span> <span style="color:#006600; font-weight:bold;">%&gt;</span>:<span style="color:#006600; font-weight:bold;">&lt;%</span>= <span style="color:#0066ff; font-weight:bold;">@node</span><span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:chef</span><span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:openid_port</span><span style="color:#006600; font-weight:bold;">&#93;</span> <span style="color:#006600; font-weight:bold;">%&gt;</span>&quot;
template_url       &quot;http://<span style="color:#006600; font-weight:bold;">&lt;%</span>= <span style="color:#0066ff; font-weight:bold;">@node</span><span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:chef</span><span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:server_fqdn</span><span style="color:#006600; font-weight:bold;">&#93;</span> <span style="color:#006600; font-weight:bold;">%&gt;</span>:<span style="color:#006600; font-weight:bold;">&lt;%</span>= <span style="color:#0066ff; font-weight:bold;">@node</span><span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:chef</span><span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:server_port</span><span style="color:#006600; font-weight:bold;">&#93;</span> <span style="color:#006600; font-weight:bold;">%&gt;</span>&quot;
remotefile_url     &quot;http://<span style="color:#006600; font-weight:bold;">&lt;%</span>= <span style="color:#0066ff; font-weight:bold;">@node</span><span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:chef</span><span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:server_fqdn</span><span style="color:#006600; font-weight:bold;">&#93;</span> <span style="color:#006600; font-weight:bold;">%&gt;</span>:<span style="color:#006600; font-weight:bold;">&lt;%</span>= <span style="color:#0066ff; font-weight:bold;">@node</span><span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:chef</span><span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:server_port</span><span style="color:#006600; font-weight:bold;">&#93;</span> <span style="color:#006600; font-weight:bold;">%&gt;</span>&quot;
search_url         &quot;http://<span style="color:#006600; font-weight:bold;">&lt;%</span>= <span style="color:#0066ff; font-weight:bold;">@node</span><span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:chef</span><span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:server_fqdn</span><span style="color:#006600; font-weight:bold;">&#93;</span> <span style="color:#006600; font-weight:bold;">%&gt;</span>:<span style="color:#006600; font-weight:bold;">&lt;%</span>= <span style="color:#0066ff; font-weight:bold;">@node</span><span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:chef</span><span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:server_port</span><span style="color:#006600; font-weight:bold;">&#93;</span> <span style="color:#006600; font-weight:bold;">%&gt;</span>&quot;
role_url           &quot;http://<span style="color:#006600; font-weight:bold;">&lt;%</span>= <span style="color:#0066ff; font-weight:bold;">@node</span><span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:chef</span><span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:server_fqdn</span><span style="color:#006600; font-weight:bold;">&#93;</span> <span style="color:#006600; font-weight:bold;">%&gt;</span>:<span style="color:#006600; font-weight:bold;">&lt;%</span>= <span style="color:#0066ff; font-weight:bold;">@node</span><span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:chef</span><span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:server_port</span><span style="color:#006600; font-weight:bold;">&#93;</span> <span style="color:#006600; font-weight:bold;">%&gt;</span>&quot;
&nbsp;
file_cache_path    &quot;<span style="color:#006600; font-weight:bold;">&lt;%</span>= <span style="color:#0066ff; font-weight:bold;">@node</span><span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:chef</span><span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:filecache</span><span style="color:#006600; font-weight:bold;">&#93;</span> <span style="color:#006600; font-weight:bold;">%&gt;</span>&quot;
pid_file           &quot;<span style="color:#006600; font-weight:bold;">&lt;%</span>= <span style="color:#0066ff; font-weight:bold;">@node</span><span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:chef</span><span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:pid</span><span style="color:#006600; font-weight:bold;">&#93;</span> <span style="color:#006600; font-weight:bold;">%&gt;</span>&quot;</pre></div></div>

<p>OK, now let&#8217;s create a chef::client recipe which will take the attributes and the template and combine them into cold hard configuration files. This is our cookbooks/chef/recipes/client.rb</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#9966CC; font-weight:bold;">case</span> node<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:platform</span><span style="color:#006600; font-weight:bold;">&#93;</span>
 <span style="color:#9966CC; font-weight:bold;">when</span> <span style="color:#996600;">&quot;debian&quot;</span>,<span style="color:#996600;">&quot;ubuntu&quot;</span>
&nbsp;
 template <span style="color:#996600;">&quot;/etc/chef/client.rb&quot;</span> <span style="color:#9966CC; font-weight:bold;">do</span>
    source <span style="color:#996600;">&quot;client.erb&quot;</span>
    mode 0644
    owner <span style="color:#996600;">&quot;root&quot;</span>
    group <span style="color:#996600;">&quot;root&quot;</span>
    backup <span style="color:#0000FF; font-weight:bold;">false</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p>OK, so now we have the attributes, the template and the recipe. Doesn&#8217;t do us much good unless we somehow tell the Chef server that our nodes need to execute the chef::client recipe when the Chef client runs. So let&#8217;s create our role, called &#8220;base&#8221;. Here is roles/base.rb</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">name <span style="color:#996600;">&quot;base&quot;</span>
description <span style="color:#996600;">&quot;All systems to get this role&quot;</span>
recipes <span style="color:#996600;">&quot;chef::client&quot;</span>
&nbsp;
override_attributes <span style="color:#996600;">&quot;chef&quot;</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#006600; font-weight:bold;">&#123;</span> 
    <span style="color:#996600;">&quot;server_fqdn&quot;</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">&quot;chef.yourdomain.com&quot;</span>,
    <span style="color:#996600;">&quot;log_level&quot;</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">&quot;info&quot;</span>
<span style="color:#006600; font-weight:bold;">&#125;</span></pre></div></div>

<p>Something to notice here. In our attributes file earlier, we used set_unless to define a few attributes of this cookbook. But here in the role we are overriding them (with the same values in this case). The utility here is that using the exact same chef cookbook, we could create a new role, called something like base_london and use override_attributes in the Role definition to give those nodes a different value for server_fqdn.</p>
<p>Now let&#8217;s commit all of this new code we have written to our Chef git repo.</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">git add <span style="color: #000000; font-weight: bold;">*</span>
git commit <span style="color: #660033;">-a</span> <span style="color: #660033;">-m</span> <span style="color: #ff0000;">&quot;adding our chef cookbook and role, first pass&quot;</span>
git push</pre></div></div>

<p>Now, let&#8217;s login to our Chef server, pull down all these new changes in our git repo and actually get this stuff into our running Chef server.</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #c20cb9; font-weight: bold;">ssh</span> chef.yourdomain.com
git clone git<span style="color: #000000; font-weight: bold;">@</span>yourgitserver.yourdomain.com:your_chef_repo.git
<span style="color: #7a0874; font-weight: bold;">cd</span> your_chef_repo
rake <span style="color: #c20cb9; font-weight: bold;">install</span>
<span style="color: #c20cb9; font-weight: bold;">sudo</span> <span style="color: #000000; font-weight: bold;">/</span>etc<span style="color: #000000; font-weight: bold;">/</span>init.d<span style="color: #000000; font-weight: bold;">/</span>chef-server restart</pre></div></div>

<p>(The last step, the restart of the Chef server, is needed because we have added a new role. Your role you defined in the Ruby file above gets compiled to <a href="http://www.json.org/">JSON</a> and then is stored in <a href="http://couchdb.apache.org/">CouchDB</a>, and we need to bounce the CouchDB server in the 0.7 Chef series for your changes to become effective).</p>
<p><img class="alignright size-full wp-image-370" src="http://warwickp.com/wp-content/uploads/2010/01/voodoo_knife_holder-e1263077860547.jpg" alt="Knife" width="90" height="90" />OK. So, now we have everything in place, except one. We haven&#8217;t told the Chef server to actually apply the &#8220;base&#8221; role to our nodes. Now you would expect to use an elegant CLI tool which would use the Chef API to perform these types of operations on the Chef server. The good news is that <a href="http://wiki.opscode.com/display/chef/Knife">Knife</a> is that tool. The bad news is that I haven&#8217;t tested Knife yet, and because you are on my blog you are <a href="http://www.urbandictionary.com/define.php?term=S.O.L.">SOL</a>. So we&#8217;ll be using the Chef web UI for this task until I get to try the Knife.</p>
<p>So, login to http://chef.yourdomain.com:4000 using your OpenID login. Go to Nodes and click on &#8220;edit&#8221; next to one of your nodes listed there if both chef.yourdomain.com and web1.yourdomain.com are registered on the server, or whichever node you have been working on. What you need to do now is drag &#8220;base&#8221; from the Available Roles into the Run List and Save Node.</p>
<p>So the final step you need to do is actually run chef-client on your server to actually fetch and apply the base role to it.</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #c20cb9; font-weight: bold;">sudo</span> chef-client <span style="color: #660033;">-l</span> debug</pre></div></div>

<p>If all went according to plan, then you should see that Chef is now managing the contents of /etc/chef/client.rb.</p>
<p>This was a very simple quick example of how a Chef cookbook, recipe, role and runlist work together to Get Things Done. There is a whole lot more to a Chef cookbook than this. The next thing to do is to forget everything I just told you, thank the heavens for <a href="http://twitter.com/jtimberman">jtimberman</a> and <a href="http://twitter.com/kallistec">kallistec</a> and all the other fine Chefs who hang out in #chef on freenode. Take a look at some <a href="http://github.com/opscode/cookbooks">real Cookbooks</a> from these guys which really start to leverage the power of Chef.</p>
<p>In part 3 of this series, coming out to coincide with <a href="http://www.3drealms.com/duke4/">Duke Nukem Forever</a>, I&#8217;ll talk about a more advanced cookbook, and hopefully Knife. Thanks for staying this long.</p>
<img src="http://feeds.feedburner.com/~r/warwickp/~4/LjqC47ezetA" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://warwickp.com/2010/01/configuration-management-with-chef-on-debian-part-2/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		<feedburner:origLink>http://warwickp.com/2010/01/configuration-management-with-chef-on-debian-part-2/</feedburner:origLink></item>
		<item>
		<title>Using multiple EC2 accounts with the EC2 API tools</title>
		<link>http://feedproxy.google.com/~r/warwickp/~3/4EphsgmVpzA/</link>
		<comments>http://warwickp.com/2010/01/using-multiple-ec2-accounts-with-the-ec2-api-tools/#comments</comments>
		<pubDate>Mon, 04 Jan 2010 21:22:45 +0000</pubDate>
		<dc:creator>warwickp</dc:creator>
				<category><![CDATA[amazon-ec2]]></category>

		<guid isPermaLink="false">http://warwickp.com/?p=291</guid>
		<description><![CDATA[Various projects I am involved with each have their own Amazon EC2 accounts. This means I have a few sets of certificates/keys to access and manage these different instances. My previous solution was a different user account on my Macbook Pro for each project. That is not very elegant at all. This is my new [...]]]></description>
			<content:encoded><![CDATA[<p>Various projects I am involved with each have their own <a href="http://aws.amazon.com/ec2/">Amazon EC2</a> accounts. This means I have a few sets of certificates/keys to access and manage these different instances. My previous solution was a different user account on my Macbook Pro for each project. That is not very elegant at all. This is my new solution, which involves a set of dynamic bash aliases and a script to create them. </p>
<p>To start, create a directory structure like this (preferably in a Git or SVN repo)</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">base<span style="color: #000000; font-weight: bold;">/</span>
accounts<span style="color: #000000; font-weight: bold;">/</span></pre></div></div>

<p>Then in accounts/, create a subdirectory for each project/client/ec2 account, and add 3 things to each subdirectory: the EC2 X.509 certificate, the EC2 private key and a single SSH private key to use for SSH access. So end up with a directory structure something like this, separated by client/project/account:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">base<span style="color: #000000; font-weight: bold;">/</span>
accounts<span style="color: #000000; font-weight: bold;">/</span>project1<span style="color: #000000; font-weight: bold;">/</span>cert-TYTYTHJHDJHDJHDJHDJH.pem
accounts<span style="color: #000000; font-weight: bold;">/</span>project1<span style="color: #000000; font-weight: bold;">/</span>pk-DNKJNFKDJNFFKJNDFKNSDFJ.pem
accounts<span style="color: #000000; font-weight: bold;">/</span>project1<span style="color: #000000; font-weight: bold;">/</span>id_dsa_project1
accounts<span style="color: #000000; font-weight: bold;">/</span>client55<span style="color: #000000; font-weight: bold;">/</span>cert-SASDASDASDASDASDASD.pem
accounts<span style="color: #000000; font-weight: bold;">/</span>client55<span style="color: #000000; font-weight: bold;">/</span>pk-UYWYWUYWUYNNSNSNS.pem
accounts<span style="color: #000000; font-weight: bold;">/</span>client55<span style="color: #000000; font-weight: bold;">/</span>mykey_client55
accounts<span style="color: #000000; font-weight: bold;">/</span>myappx<span style="color: #000000; font-weight: bold;">/</span>cert-XCMLKMLKMLKMLKM.pem
accounts<span style="color: #000000; font-weight: bold;">/</span>myappx<span style="color: #000000; font-weight: bold;">/</span>pk-CCJKJDKPOPOPOPPOP.pem
accounts<span style="color: #000000; font-weight: bold;">/</span>myappx<span style="color: #000000; font-weight: bold;">/</span>awskey_appx</pre></div></div>

<p>Now we&#8217;ll <a href="http://s3.amazonaws.com/ec2-downloads/ec2-api-tools.zip">download the latest EC2 API tools</a> and expand them into base/, so we will have a directory structure like this:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">base<span style="color: #000000; font-weight: bold;">/</span>THIRDPARTYLICENSE.TXT
base<span style="color: #000000; font-weight: bold;">/</span>bin<span style="color: #000000; font-weight: bold;">/</span>ec2-add-group
base<span style="color: #000000; font-weight: bold;">/</span>bin<span style="color: #000000; font-weight: bold;">/</span>ec2-add-group.cmd
base<span style="color: #000000; font-weight: bold;">/</span>bin<span style="color: #000000; font-weight: bold;">/</span>ec2-add-keypair
base<span style="color: #000000; font-weight: bold;">/</span>bin<span style="color: #000000; font-weight: bold;">/</span>ec2-add-keypair.cmd
<span style="color: #660033;">--</span> ETC <span style="color: #660033;">--</span> OMITTING THE REST OF bin<span style="color: #000000; font-weight: bold;">/</span>
base<span style="color: #000000; font-weight: bold;">/</span>lib<span style="color: #000000; font-weight: bold;">/</span>activation-1.1.jar
base<span style="color: #000000; font-weight: bold;">/</span>lib<span style="color: #000000; font-weight: bold;">/</span>bcprov.jar
<span style="color: #660033;">--</span> ETC <span style="color: #660033;">--</span> OMITTING THE REST OF lib<span style="color: #000000; font-weight: bold;">/</span>
base<span style="color: #000000; font-weight: bold;">/</span>license.txt
base<span style="color: #000000; font-weight: bold;">/</span>notice.txt
accounts<span style="color: #000000; font-weight: bold;">/</span>project1<span style="color: #000000; font-weight: bold;">/</span>cert-TYTYTHJHDJHDJHDJHDJH.pem
accounts<span style="color: #000000; font-weight: bold;">/</span>project1<span style="color: #000000; font-weight: bold;">/</span>pk-DNKJNFKDJNFFKJNDFKNSDFJ.pem
accounts<span style="color: #000000; font-weight: bold;">/</span>project1<span style="color: #000000; font-weight: bold;">/</span>id_dsa_project1
<span style="color: #660033;">--</span> ETC <span style="color: #660033;">--</span> OMITTING THE REST OF accounts<span style="color: #000000; font-weight: bold;">/</span></pre></div></div>

<p>Now, we will use a simple bash script to generate a bash alias for each EC2 operation for each EC2 account we have. It essentially maps each EC2 command to the appropriate key and cert for each of our projects/clients. </p>
<p>NOTE: This version sets up some environment variables which are specific to a Mac OS X > Leopard environment. Yours may need different JAVA_HOME, if you are on a different OS, etc.</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
</pre></td><td class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">#!/bin/bash</span>
<span style="color: #7a0874; font-weight: bold;">export</span> <span style="color: #007800;">JAVA_HOME</span>=<span style="color: #000000; font-weight: bold;">/</span>System<span style="color: #000000; font-weight: bold;">/</span>Library<span style="color: #000000; font-weight: bold;">/</span>Frameworks<span style="color: #000000; font-weight: bold;">/</span>JavaVM.framework<span style="color: #000000; font-weight: bold;">/</span>Home<span style="color: #000000; font-weight: bold;">/</span>
<span style="color: #7a0874; font-weight: bold;">export</span> <span style="color: #007800;">EC2_TOP</span>=$<span style="color: #7a0874; font-weight: bold;">&#40;</span> <span style="color: #c20cb9; font-weight: bold;">dirname</span> <span style="color: #007800;">$BASH_SOURCE</span> <span style="color: #7a0874; font-weight: bold;">&#41;</span>
<span style="color: #7a0874; font-weight: bold;">export</span> <span style="color: #007800;">EC2_HOME</span>=<span style="color: #007800;">$EC2_TOP</span><span style="color: #000000; font-weight: bold;">/</span>base
&nbsp;
<span style="color: #007800;">ALL_ACCOUNTS</span>=$<span style="color: #7a0874; font-weight: bold;">&#40;</span> <span style="color: #c20cb9; font-weight: bold;">ls</span> <span style="color: #007800;">$EC2_TOP</span><span style="color: #000000; font-weight: bold;">/</span>accounts <span style="color: #7a0874; font-weight: bold;">&#41;</span>
<span style="color: #007800;">EC2_TOOLS</span>=$<span style="color: #7a0874; font-weight: bold;">&#40;</span> <span style="color: #c20cb9; font-weight: bold;">ls</span> <span style="color: #007800;">$EC2_HOME</span><span style="color: #000000; font-weight: bold;">/</span>bin <span style="color: #000000; font-weight: bold;">|</span> <span style="color: #c20cb9; font-weight: bold;">grep</span> <span style="color: #660033;">-v</span> .cmd <span style="color: #7a0874; font-weight: bold;">&#41;</span>
&nbsp;
<span style="color: #007800;">THIS_KEY</span>=<span style="color: #ff0000;">''</span>
<span style="color: #007800;">THIS_CERT</span>=<span style="color: #ff0000;">''</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">for</span> a <span style="color: #000000; font-weight: bold;">in</span> <span style="color: #007800;">$ALL_ACCOUNTS</span>; <span style="color: #000000; font-weight: bold;">do</span>
        <span style="color: #007800;">THIS_KEY</span>=$<span style="color: #7a0874; font-weight: bold;">&#40;</span> <span style="color: #c20cb9; font-weight: bold;">ls</span> <span style="color: #007800;">$EC2_TOP</span><span style="color: #000000; font-weight: bold;">/</span>accounts<span style="color: #000000; font-weight: bold;">/</span><span style="color: #007800;">$a</span><span style="color: #000000; font-weight: bold;">/</span>pk-<span style="color: #000000; font-weight: bold;">*</span>.pem <span style="color: #7a0874; font-weight: bold;">&#41;</span>
        <span style="color: #007800;">THIS_CERT</span>=$<span style="color: #7a0874; font-weight: bold;">&#40;</span> <span style="color: #c20cb9; font-weight: bold;">ls</span> <span style="color: #007800;">$EC2_TOP</span><span style="color: #000000; font-weight: bold;">/</span>accounts<span style="color: #000000; font-weight: bold;">/</span><span style="color: #007800;">$a</span><span style="color: #000000; font-weight: bold;">/</span>cert-<span style="color: #000000; font-weight: bold;">*</span>.pem <span style="color: #7a0874; font-weight: bold;">&#41;</span>
        <span style="color: #007800;">THIS_SSH</span>=$<span style="color: #7a0874; font-weight: bold;">&#40;</span> <span style="color: #c20cb9; font-weight: bold;">ls</span> <span style="color: #007800;">$EC2_TOP</span><span style="color: #000000; font-weight: bold;">/</span>accounts<span style="color: #000000; font-weight: bold;">/</span><span style="color: #007800;">$a</span><span style="color: #000000; font-weight: bold;">/*</span> <span style="color: #000000; font-weight: bold;">|</span> <span style="color: #c20cb9; font-weight: bold;">grep</span> <span style="color: #660033;">-v</span> .pem <span style="color: #7a0874; font-weight: bold;">&#41;</span>
&nbsp;
        <span style="color: #7a0874; font-weight: bold;">alias</span> ssh-ec2-<span style="color: #007800;">$a</span>=<span style="color: #ff0000;">&quot;ssh -i <span style="color: #007800;">$THIS_SSH</span>&quot;</span>
&nbsp;
        <span style="color: #000000; font-weight: bold;">for</span> e <span style="color: #000000; font-weight: bold;">in</span> <span style="color: #007800;">$EC2_TOOLS</span>; <span style="color: #000000; font-weight: bold;">do</span>
                <span style="color: #7a0874; font-weight: bold;">alias</span> ec2-<span style="color: #007800;">$a</span>-<span style="color: #007800;">$e</span>=<span style="color: #ff0000;">&quot;<span style="color: #007800;">$EC2_HOME</span>/bin/<span style="color: #007800;">$e</span> -K <span style="color: #007800;">$THIS_KEY</span> -C <span style="color: #007800;">$THIS_CERT</span>&quot;</span>
        <span style="color: #000000; font-weight: bold;">done</span>
&nbsp;
        <span style="color: #007800;">THIS_KEY</span>=<span style="color: #ff0000;">''</span>
        <span style="color: #007800;">THIS_CERT</span>=<span style="color: #ff0000;">''</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">done</span></pre></td></tr></table></div>

<p>This base script (I&#8217;ve called mine setup_env.sh) needs to live at the top level, so again, we have a structure like this:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">base<span style="color: #000000; font-weight: bold;">/</span>
accounts<span style="color: #000000; font-weight: bold;">/</span>
setup_env.sh</pre></div></div>

<p>Now, simply source setup_env.sh as part of your login procedure, by putting something like this in .bash_profile:</p>
<p>NOTE: My top level directory lives at ~/Tools/Amazon</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #7a0874; font-weight: bold;">source</span> ~<span style="color: #000000; font-weight: bold;">/</span>Tools<span style="color: #000000; font-weight: bold;">/</span>Amazon<span style="color: #000000; font-weight: bold;">/</span>setup_env.sh</pre></div></div>

<p>Now, when I login, I can create an instance on the correct EC2 account with something like:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">ec2-project1-ec2run <span style="color: #000000; font-weight: bold;">&lt;</span>options<span style="color: #000000; font-weight: bold;">&gt;</span></pre></div></div>

<p>And I can SSH to a running EC2 instance with something like:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">ssh-ec2-project1 root<span style="color: #000000; font-weight: bold;">@</span>myinstance.address.com</pre></div></div>

<p>Simple, possibly inelegant, but very functional. Do you have anything which works better than this? Please share.. </p>
<img src="http://feeds.feedburner.com/~r/warwickp/~4/4EphsgmVpzA" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://warwickp.com/2010/01/using-multiple-ec2-accounts-with-the-ec2-api-tools/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		<feedburner:origLink>http://warwickp.com/2010/01/using-multiple-ec2-accounts-with-the-ec2-api-tools/</feedburner:origLink></item>
		<item>
		<title />
		<link>http://feedproxy.google.com/~r/warwickp/~3/JwKXvAe7x-Q/</link>
		<comments>http://warwickp.com/2010/01/287/#comments</comments>
		<pubDate>Sat, 02 Jan 2010 14:37:17 +0000</pubDate>
		<dc:creator>warwickp</dc:creator>
				<category><![CDATA[quicklink]]></category>

		<guid isPermaLink="false">http://warwickp.com/?p=287</guid>
		<description><![CDATA[&#8220;The image comparison below indicates that I have something to offer in this area.&#8221;
]]></description>
			<content:encoded><![CDATA[<p><a href="http://pdxcell.com/">&#8220;The image comparison below indicates that I have something to offer in this area.&#8221;</a></p>
<img src="http://feeds.feedburner.com/~r/warwickp/~4/JwKXvAe7x-Q" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://warwickp.com/2010/01/287/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://warwickp.com/2010/01/287/</feedburner:origLink></item>
		<item>
		<title />
		<link>http://feedproxy.google.com/~r/warwickp/~3/-Fm1hH7WbYM/</link>
		<comments>http://warwickp.com/2010/01/284/#comments</comments>
		<pubDate>Fri, 01 Jan 2010 19:37:55 +0000</pubDate>
		<dc:creator>warwickp</dc:creator>
				<category><![CDATA[quicklink]]></category>

		<guid isPermaLink="false">http://warwickp.com/?p=284</guid>
		<description><![CDATA[Residents in the Virgin Islands sharing the important information online.
]]></description>
			<content:encoded><![CDATA[<p>Residents in the Virgin Islands <a href="http://www.vimovingcenter.com/talk/read.php?4,128453">sharing the important information</a> online.</p>
<img src="http://feeds.feedburner.com/~r/warwickp/~4/-Fm1hH7WbYM" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://warwickp.com/2010/01/284/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://warwickp.com/2010/01/284/</feedburner:origLink></item>
		<item>
		<title>Side Project. I need one. Help me decide, idea 1: HPIT</title>
		<link>http://feedproxy.google.com/~r/warwickp/~3/_jS6rzB7Bv0/</link>
		<comments>http://warwickp.com/2009/12/side-project-i-need-one-help-me-decide-idea-1-hpit/#comments</comments>
		<pubDate>Wed, 30 Dec 2009 15:28:39 +0000</pubDate>
		<dc:creator>warwickp</dc:creator>
				<category><![CDATA[thinking]]></category>

		<guid isPermaLink="false">http://warwickp.com/?p=276</guid>
		<description><![CDATA[I want to write a another web application in early 2010. Here is the first idea I had. Rain some criticism down or heap some praise. I haven&#8217;t seen this service out there, so if I missed it somewhere, please tell me.
Idea 1: The Hosting Provider Incident Tracker (HPIT)
A real time database where we track [...]]]></description>
			<content:encoded><![CDATA[<p>I want to write a another web application in early 2010. Here is the first idea I had. Rain some criticism down or heap some praise. I haven&#8217;t seen this service out there, so if I missed it somewhere, please tell me.</p>
<p><strong>Idea 1: The Hosting Provider Incident Tracker (HPIT)</strong></p>
<p>A real time database where we track major (and minor) incidents at hosting providers around the world. Too many times I have asked hosting providers about their history of incidents only to receive vague assertions about 100% uptime and heroic stories surviving the <a href="http://en.wikipedia.org/wiki/Northeast_Blackout_of_2003">great blackout</a>s of our time. This always fails to impress me. What would REALLY impress me is a provider who would give me a link to their incident history with detailed technical explanations around the root causes (ugh, hate that word) and mitigation steps. Sadly, providers still want to sell the snakeoil of <a href="http://www.rackspace.com/whyrackspace/network/index.php?CMP=Google_100+uptime">100% uptime</a>. This isn&#8217;t the point, because there isn&#8217;t 100% uptime. There is only honest and timely response to inevitable outages. This is what matters. This, however, opens the door for an independent tracker of these incidents. This service will vet incident reports, seek and post responses from hosting providers, or simply link to their own responses, and be your source for evaluating how a hosting company responds to critical issues. </p>
<p>BTW: I don&#8217;t know why <a href="http://pingdom.com/">Pingdom</a> isn&#8217;t providing this service today. It has most of the data required already.</p>
<img src="http://feeds.feedburner.com/~r/warwickp/~4/_jS6rzB7Bv0" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://warwickp.com/2009/12/side-project-i-need-one-help-me-decide-idea-1-hpit/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		<feedburner:origLink>http://warwickp.com/2009/12/side-project-i-need-one-help-me-decide-idea-1-hpit/</feedburner:origLink></item>
		<item>
		<title>Configuration Management with Chef on Debian, Part 1</title>
		<link>http://feedproxy.google.com/~r/warwickp/~3/hE28vh1OAHI/</link>
		<comments>http://warwickp.com/2009/12/configuration-management-with-chef-on-debian-part-1/#comments</comments>
		<pubDate>Fri, 18 Dec 2009 04:31:39 +0000</pubDate>
		<dc:creator>warwickp</dc:creator>
				<category><![CDATA[opschef]]></category>

		<guid isPermaLink="false">http://warwickp.com/?p=190</guid>
		<description><![CDATA[UPDATE: Part 2 now online
I&#8217;m familiar with configuration management tools like Cfengine, Puppet and slack. I am also familiar with using homebrewed tools which leverage trees of shell scripts to apply and manage a bunch of configuration files stored in version control. I am going to teach myself to use Chef on Debian Lenny. Follow [...]]]></description>
			<content:encoded><![CDATA[<p>UPDATE: <a href="http://warwickp.com/2010/01/configuration-management-with-chef-on-debian-part-2/">Part 2 now online</a></p>
<p>I&#8217;m familiar with configuration management tools like <a href="http://www.cfengine.org/">Cfengine</a>, <a href="http://reductivelabs.com/products/">Puppet</a> and <a href="http://code.google.com/p/slack/">slack</a>. I am also familiar with using homebrewed tools which leverage trees of shell scripts to apply and manage a bunch of configuration files stored in version control. I am going to teach myself to use <a href="http://www.opscode.com/chef/">Chef</a> on <a href="http://www.debian.org/releases/stable/">Debian</a> Lenny. Follow along.</p>
<p>Firstly, <strong>idempotent</strong>. Chef is <a href="http://en.wikipedia.org/wiki/Idempotence">idempotent</a>. Wha? This means that if you run the chef client on a <strong>node</strong> multiple times, you should never get a gradually changing state. Given the same <strong>recipes</strong>, the system should always return to an identical state after the Chef tools run on the system. Think about those shell scripts you have written in the past. Sometimes they are appending strings to files, or removing strings from files, or moving files around based on some algorithm. Well, Chef doesn&#8217;t perform a single action out of context. It does every action, every time. And the actions Chef performs are defined in <strong>recipes</strong>. Collections of recipes are called <strong>cookbooks</strong>. These recipes are written in <a href="http://ruby-lang.org">Ruby</a>. Recipes can be grouped together in <strong>roles</strong>, so when you apply a role to a <strong>node</strong> that node will receive all the recipes in that role. Recipes can reference <strong>attributes</strong> in other recipes, and also apply other recipes.</p>
<p>The bulk of the Chef work is done by the <strong>chef-client</strong> which runs on the host you are managing with chef. It may or may not contact a <strong>chef-server</strong>. Using <a href="http://wiki.opscode.com/display/chef/Chef+Solo">chef-solo</a> you can do a bunch of useful things without needing a central chef-server.</p>
<p>There are quite a few different tools in use in the complete Chef stack. Wonderful tools like <a href="http://couchdb.apache.org/">couchdb</a>, <a href="http://stompserver.rubyforge.org/">Stomp</a>, <a href="http://www.merbivore.com/">Merb</a>. Luckily, thanks to great packages from Opscode, you can get all of this stuff installed without too much trouble.</p>
<p><strong>Note on versions:</strong> Chef 0.8 branch is currently getting some very interesting sounding features. In fact, I remarked in <a href="http://wiki.opscode.com/display/chef/IRC">IRC</a> today that I fully expect Chef 0.8 to file my taxes and walk my dog. However, I am not going there yet. This post will be all about Chef 0.7 branch, specifically the version of Chef provided in the Opscode apt repositories. By the way, you should totally hang out in #chef on <a href="http://freenode.net/">Freenode</a>. The people in there are awesome, helpful and very very good looking.</p>
<p>This is it. Let&#8217;s do things.</p>
<p><span style="text-decoration: underline;"><strong>Set up your Git repository</strong></span></p>
<p>The various pieces which end up becoming files on the filesystem are stored in version control. You can apparently use SVN, but we&#8217;ll go with Git. You&#8217;ll need a nice fresh Git repo. To this repo you&#8217;ll add your Chef cookbooks and roles, etc. So you could either host your Git repo with <a href="http://github.com">GitHub</a> (you&#8217;ll probably want to use a private repo, the repo will most likely contain some private things) or you could <a href="http://scie.nti.st/2007/11/14/hosting-git-repositories-the-easy-and-secure-way">set up you own Git repo</a> using <a href="http://eagain.net/gitweb/?p=gitosis.git">Gitosis</a>.</p>
<p>Once you have your Chef repo setup, get the contents of the Opscode Chef Repository into your own repo. I&#8217;m not going to go into the details of how to do this using Git, mostly because you don&#8217;t want Git advice from me. Nevertheless, you want to grab the contents of this repo, and merge them in your new repo:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">git clone git:<span style="color: #000000; font-weight: bold;">//</span>github.com<span style="color: #000000; font-weight: bold;">/</span>opscode<span style="color: #000000; font-weight: bold;">/</span>chef-repo.git</pre></div></div>

<p>When all is said and done, your repo should have a structure similar to this:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
</pre></td><td class="code"><pre class="bash" style="font-family:monospace;">certificates<span style="color: #000000; font-weight: bold;">/</span>
config<span style="color: #000000; font-weight: bold;">/</span>
config<span style="color: #000000; font-weight: bold;">/</span>client.rb.example
config<span style="color: #000000; font-weight: bold;">/</span>server.rb.example
config<span style="color: #000000; font-weight: bold;">/</span>rake.rb
config<span style="color: #000000; font-weight: bold;">/</span>solo.rb.example
cookbooks<span style="color: #000000; font-weight: bold;">/</span>
Rakefile
roles<span style="color: #000000; font-weight: bold;">/</span>
site-cookbooks<span style="color: #000000; font-weight: bold;">/</span></pre></td></tr></table></div>

<p>More detailed info on the <a href="http://wiki.opscode.com/display/chef/Chef+Repository">Chef Repository</a></p>
<p><span style="text-decoration: underline;"><strong>Setup your 2 servers and your DNS</strong></span></p>
<p>For the purposes of this tutorial, we&#8217;ll assume you have 2 servers. You could have 17 servers, that would be fine too. We&#8217;ll call server 1 <em>chef.yourdomain.com</em> and server 2 will be <em>web1.yourdomain.com</em>. Make sure these servers have Debian Lenny installed and you have created proper working DNS entries for the hostnames chef.yourdomain.com and web1.yourdomain.com</p>
<p>We&#8217;ll be installing Chef server AND a Chef client on chef.yourdomain.com<br />
We&#8217;ll be installing only a Chef client on web1.yourdomain.com</p>
<p><span style="text-decoration: underline;"><strong>Setup your Chef server</strong></span></p>
<p>There are Chef cookbooks which will allow Chef to bootstrap itself, which is a fairly cool concept. This isn&#8217;t necessary, however, when using the Opscode chef packages for Debian, since they will provide everything we need for our Chef server in the packages. So we&#8217;ll simply install the packages and be on our way.</p>
<p>First, we&#8217;ll need these:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
</pre></td><td class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #c20cb9; font-weight: bold;">apt-get</span> update
<span style="color: #c20cb9; font-weight: bold;">apt-get</span> <span style="color: #c20cb9; font-weight: bold;">install</span> <span style="color: #660033;">-y</span> curl git-core <span style="color: #c20cb9; font-weight: bold;">sudo</span></pre></td></tr></table></div>

<p>Now let&#8217;s set up the Opscode repo and install Chef:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
</pre></td><td class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #ff0000;">&quot;deb http://apt.opscode.com/ debian contrib&quot;</span> <span style="color: #000000; font-weight: bold;">&gt;</span> <span style="color: #000000; font-weight: bold;">/</span>etc<span style="color: #000000; font-weight: bold;">/</span>apt<span style="color: #000000; font-weight: bold;">/</span>sources.list.d<span style="color: #000000; font-weight: bold;">/</span>opscode.list
curl http:<span style="color: #000000; font-weight: bold;">//</span>apt.opscode.com<span style="color: #000000; font-weight: bold;">/</span>packages<span style="color: #000000; font-weight: bold;">@</span>opscode.com.gpg.key <span style="color: #000000; font-weight: bold;">|</span> <span style="color: #c20cb9; font-weight: bold;">apt-key</span> add -
<span style="color: #c20cb9; font-weight: bold;">apt-get</span> update
<span style="color: #c20cb9; font-weight: bold;">apt-get</span> <span style="color: #c20cb9; font-weight: bold;">install</span> <span style="color: #660033;">-y</span> rubygems libshadow-ruby1.8 ohai chef chef-server</pre></td></tr></table></div>

<p>Done. Buy Opscode some beer! OK, now let&#8217;s do some configuration of the Chef server. Firstly, Chef uses <a href="http://openid.net/">OpenID</a> extensively for authentication. We need to have an OpenID provider, which we trust defined in the chef server config. If you don&#8217;t have an OpenID provider that you use, head over to <a href="https://www.myopenid.com/">myOpenID</a> and sign up for an account. You&#8217;ll get an OpenID URL. Now we&#8217;ll put that into the chef config at /etc/chef/server.rb by adding the following line at the bottom of that file:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
</pre></td><td class="code"><pre class="bash" style="font-family:monospace;">authorized_openid_providers <span style="color: #7a0874; font-weight: bold;">&#91;</span> <span style="color: #ff0000;">&quot;https://chef.localdomain&quot;</span>, <span style="color: #ff0000;">&quot;https://chef&quot;</span>, <span style="color: #ff0000;">&quot;https://whateveryourswas.myopenid.com&quot;</span><span style="color: #7a0874; font-weight: bold;">&#93;</span></pre></td></tr></table></div>

<p>Now we are going to generate a validation token for our Chef clients to use to auto-register themselves against the Chef server. You need a nice random string. If you lack the creativity to make one up, try this:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
</pre></td><td class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #007800;">thedate</span>=$<span style="color: #7a0874; font-weight: bold;">&#40;</span> <span style="color: #c20cb9; font-weight: bold;">date</span> <span style="color: #7a0874; font-weight: bold;">&#41;</span>; <span style="color: #007800;">thehost</span>=$<span style="color: #7a0874; font-weight: bold;">&#40;</span> <span style="color: #c20cb9; font-weight: bold;">hostname</span> <span style="color: #7a0874; font-weight: bold;">&#41;</span>; <span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #007800;">$thedate</span><span style="color: #007800;">$thehost</span> <span style="color: #000000; font-weight: bold;">|</span> sha256sum</pre></td></tr></table></div>

<p>Now put the string you came up with above into /etc/chef/server.rb by finding the validation_token line, uncommenting it and giving it a value:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
</pre></td><td class="code"><pre class="bash" style="font-family:monospace;">validation_token   <span style="color: #ff0000;">&quot;2d926b251e18cb39b00350bb956d44ef8639b4ed33809194a7e2ed60ac5d772c&quot;</span></pre></td></tr></table></div>

<p>Restart Chef server:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
</pre></td><td class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">/</span>etc<span style="color: #000000; font-weight: bold;">/</span>init.d<span style="color: #000000; font-weight: bold;">/</span>chef-server restart</pre></td></tr></table></div>

<p><span style="text-decoration: underline;"><strong>Setup your <a href="http://wiki.opscode.com/display/chef/Chef+Repository">Chef Repository</a></strong></span></p>
<p>Now we need our Git repository created earlier. We are going to use this repository to store our recipes, and we are going to use tools inside this repository to manage Chef itself. How meta. So on your newly installed chef server, in your home directory, or whereever else, clone your git repo:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
</pre></td><td class="code"><pre class="bash" style="font-family:monospace;">git clone git<span style="color: #000000; font-weight: bold;">@</span>yourgitserver.yourdomain.com:your_chef_repo.git
<span style="color: #7a0874; font-weight: bold;">cd</span> your_chef_repo</pre></td></tr></table></div>

<p>We are now going to use <a href="http://rake.rubyforge.org/">Rake</a> to install the initial (blank) Chef cookbooks into place, and also to set up the SSL certificates which Chef uses when communicating between components. Obviously you&#8217;ll want to use your Chef server&#8217;s proper FQDN here.</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
</pre></td><td class="code"><pre class="bash" style="font-family:monospace;">rake <span style="color: #c20cb9; font-weight: bold;">install</span>
rake ssl_cert <span style="color: #007800;">FQDN</span>=<span style="color: #ff0000;">'chef.yourdomain.com'</span></pre></td></tr></table></div>

<p>Now, try logging into the Chef web UI, at http://chef.yourdomain.com:4000</p>
<p>In the login field, enter the openID URL you configured earlier, eg: https://whateveryourswas.myopenid.com you&#8217;ll be forwarded to the OpenID provider, asked to authenticate and sent back to Chef. You should now be logged in.</p>
<p><span style="text-decoration: underline;"><strong>Set up your Chef client</strong></span></p>
<p>OK, now that we have a working, albeit currently fairly useless, Chef server let&#8217;s install our first Chef client. On your other host, web1.yourdomain.com, you could use this script I quickly put together to go from a freshly installed server to a working Chef client. Obviously you should substitute your auth_token you created earlier and your chef&#8217;s DNS location.</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
</pre></td><td class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">#!/bin/bash</span>
<span style="color: #666666; font-style: italic;">### VARIABLES ##########################################################</span>
<span style="color: #007800;">chef_server</span>=<span style="color: #ff0000;">&quot;chef.yourdomain.com&quot;</span>
<span style="color: #007800;">chef_client</span>=<span style="color: #000000; font-weight: bold;">/</span>usr<span style="color: #000000; font-weight: bold;">/</span>bin<span style="color: #000000; font-weight: bold;">/</span>chef-client
<span style="color: #007800;">chef_client_config</span>=<span style="color: #ff0000;">&quot;/etc/chef/client.rb&quot;</span>
<span style="color: #007800;">chef_auth_token</span>=<span style="color: #ff0000;">&quot;2d926b251e18cb39b00350bb956d44ef8639b4ed33809194a7e2ed60ac5d772c&quot;</span>
&nbsp;
<span style="color: #007800;">opscode_apt</span>=<span style="color: #ff0000;">&quot;deb http://apt.opscode.com/ debian contrib&quot;</span>
&nbsp;
<span style="color: #666666; font-style: italic;">### ACTIONS ############################################################</span>
<span style="color: #c20cb9; font-weight: bold;">apt-get</span> update
<span style="color: #c20cb9; font-weight: bold;">apt-get</span> <span style="color: #c20cb9; font-weight: bold;">install</span> <span style="color: #660033;">-y</span> curl git-core <span style="color: #c20cb9; font-weight: bold;">sudo</span>
&nbsp;
<span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #007800;">$opscode_apt</span> <span style="color: #000000; font-weight: bold;">&gt;</span> <span style="color: #000000; font-weight: bold;">/</span>etc<span style="color: #000000; font-weight: bold;">/</span>apt<span style="color: #000000; font-weight: bold;">/</span>sources.list.d<span style="color: #000000; font-weight: bold;">/</span>opscode.list
curl http:<span style="color: #000000; font-weight: bold;">//</span>apt.opscode.com<span style="color: #000000; font-weight: bold;">/</span>packages<span style="color: #000000; font-weight: bold;">@</span>opscode.com.gpg.key <span style="color: #000000; font-weight: bold;">|</span> <span style="color: #c20cb9; font-weight: bold;">apt-key</span> add -
<span style="color: #c20cb9; font-weight: bold;">apt-get</span> update
<span style="color: #c20cb9; font-weight: bold;">apt-get</span> <span style="color: #c20cb9; font-weight: bold;">install</span> <span style="color: #660033;">-y</span> rubygems ohai chef libshadow-ruby1.8
&nbsp;
<span style="color: #666666; font-style: italic;">### SETUP CHEF CLIENT AND REGISTER #####################################</span>
<span style="color: #c20cb9; font-weight: bold;">sed</span> <span style="color: #660033;">-i</span> <span style="color: #ff0000;">&quot;s/localhost/<span style="color: #007800;">$chef_server</span>/g&quot;</span> <span style="color: #007800;">$chef_client_config</span>
<span style="color: #007800;">$chef_client</span> <span style="color: #660033;">-t</span> <span style="color: #007800;">$chef_auth_token</span>
&nbsp;
<span style="color: #666666; font-style: italic;">### REMOVE THYSELF #####################################################</span>
<span style="color: #c20cb9; font-weight: bold;">rm</span> $<span style="color: #000000;">0</span></pre></td></tr></table></div>

<p>If all went according to plan, this should now be a working chef client which knows where the chef server is, and has auto registered itself with the Chef server. Have a look at http://chef.yourdomain.com:4000/registrations and see if web1.yourdomain.com is listed there. If so you are halfway to Nirvana. So now we actually want to start doing things by creating cookbooks, roles, ie: actually doing shit.</p>
<p>Stay tuned for part 2 in this enthralling series. Contact me for movie rights.</p>
<p>UPDATE: <a href="http://warwickp.com/2010/01/configuration-management-with-chef-on-debian-part-2/">Part 2 now online</a></p>
<img src="http://feeds.feedburner.com/~r/warwickp/~4/hE28vh1OAHI" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://warwickp.com/2009/12/configuration-management-with-chef-on-debian-part-1/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		<feedburner:origLink>http://warwickp.com/2009/12/configuration-management-with-chef-on-debian-part-1/</feedburner:origLink></item>
		<item>
		<title />
		<link>http://feedproxy.google.com/~r/warwickp/~3/7U-36ruqGFQ/</link>
		<comments>http://warwickp.com/2009/12/199/#comments</comments>
		<pubDate>Tue, 15 Dec 2009 02:38:36 +0000</pubDate>
		<dc:creator>warwickp</dc:creator>
				<category><![CDATA[quicklink]]></category>

		<guid isPermaLink="false">http://warwickp.com/?p=199</guid>
		<description><![CDATA[Nice little villa in Peter Bay for $45,000/week.
]]></description>
			<content:encoded><![CDATA[<p>Nice little <a href="http://www.homeaway.com/vacation-rental/p7029971hi">villa in Peter Bay </a>for $45,000/week.</p>
<img src="http://feeds.feedburner.com/~r/warwickp/~4/7U-36ruqGFQ" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://warwickp.com/2009/12/199/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://warwickp.com/2009/12/199/</feedburner:origLink></item>
		<item>
		<title />
		<link>http://feedproxy.google.com/~r/warwickp/~3/a7eT_UHWUiI/</link>
		<comments>http://warwickp.com/2009/12/198/#comments</comments>
		<pubDate>Fri, 11 Dec 2009 23:23:12 +0000</pubDate>
		<dc:creator>warwickp</dc:creator>
				<category><![CDATA[quicklink]]></category>

		<guid isPermaLink="false">http://warwickp.com/2009/12/198/</guid>
		<description><![CDATA[The Nginx mailing list is the best techlist I subscribe to.
]]></description>
			<content:encoded><![CDATA[<p>The <a href="http://forum.nginx.org/read.php?2,27636,27808">Nginx mailing list</a> is the best techlist I subscribe to.</p>
<img src="http://feeds.feedburner.com/~r/warwickp/~4/a7eT_UHWUiI" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://warwickp.com/2009/12/198/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://warwickp.com/2009/12/198/</feedburner:origLink></item>
		<item>
		<title />
		<link>http://feedproxy.google.com/~r/warwickp/~3/gqXJkEYg1Xg/</link>
		<comments>http://warwickp.com/2009/12/197/#comments</comments>
		<pubDate>Fri, 11 Dec 2009 03:27:02 +0000</pubDate>
		<dc:creator>warwickp</dc:creator>
				<category><![CDATA[quicklink]]></category>

		<guid isPermaLink="false">http://warwickp.com/2009/12/197/</guid>
		<description><![CDATA[Who else used to marvel at the weirdness of superbad.com?
]]></description>
			<content:encoded><![CDATA[<p>Who else used to marvel at the weirdness of <a href="http://superbad.com">superbad.com</a>?</p>
<img src="http://feeds.feedburner.com/~r/warwickp/~4/gqXJkEYg1Xg" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://warwickp.com/2009/12/197/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://warwickp.com/2009/12/197/</feedburner:origLink></item>
		<item>
		<title />
		<link>http://feedproxy.google.com/~r/warwickp/~3/DbRICCmZgcE/</link>
		<comments>http://warwickp.com/2009/12/194/#comments</comments>
		<pubDate>Wed, 09 Dec 2009 00:48:27 +0000</pubDate>
		<dc:creator>warwickp</dc:creator>
				<category><![CDATA[quicklink]]></category>

		<guid isPermaLink="false">http://warwickp.com/?p=194</guid>
		<description><![CDATA[DRBD is now in the Linux kernel expected to arrive in 2.6.33. Wow.
]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.drbd.org/">DRBD</a> is now <a href="http://marc.info/?l=linux-kernel&amp;m=125302593323927&amp;w=2">in the Linux kernel</a> expected to arrive in 2.6.33. Wow.</p>
<img src="http://feeds.feedburner.com/~r/warwickp/~4/DbRICCmZgcE" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://warwickp.com/2009/12/194/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://warwickp.com/2009/12/194/</feedburner:origLink></item>
		<item>
		<title />
		<link>http://feedproxy.google.com/~r/warwickp/~3/Ws9gn8EOrW4/</link>
		<comments>http://warwickp.com/2009/12/188/#comments</comments>
		<pubDate>Wed, 02 Dec 2009 05:33:53 +0000</pubDate>
		<dc:creator>warwickp</dc:creator>
				<category><![CDATA[quicklink]]></category>

		<guid isPermaLink="false">http://warwickp.com/?p=188</guid>
		<description><![CDATA[The water bear, a.k.a moss piglet or Tardigrade, is a serious creature.
]]></description>
			<content:encoded><![CDATA[<p>The <a href="http://en.wikipedia.org/wiki/Water_bear">water bear</a>, a.k.a moss piglet or Tardigrade, is a serious creature.</p>
<img src="http://feeds.feedburner.com/~r/warwickp/~4/Ws9gn8EOrW4" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://warwickp.com/2009/12/188/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://warwickp.com/2009/12/188/</feedburner:origLink></item>
		<item>
		<title />
		<link>http://feedproxy.google.com/~r/warwickp/~3/NT04pcoPQaA/</link>
		<comments>http://warwickp.com/2009/11/186/#comments</comments>
		<pubDate>Mon, 30 Nov 2009 01:20:21 +0000</pubDate>
		<dc:creator>warwickp</dc:creator>
				<category><![CDATA[quicklink]]></category>

		<guid isPermaLink="false">http://warwickp.com/?p=186</guid>
		<description><![CDATA[Frank Oz being fairly frank on Brando, Yoda, Hollywood and his career.
]]></description>
			<content:encoded><![CDATA[<p>Frank Oz <a href="http://www.avclub.com/articles/frank-oz,14141/">being fairly frank</a> on Brando, Yoda, Hollywood and his career.</p>
<img src="http://feeds.feedburner.com/~r/warwickp/~4/NT04pcoPQaA" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://warwickp.com/2009/11/186/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://warwickp.com/2009/11/186/</feedburner:origLink></item>
	</channel>
</rss>
