<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	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/"
	>

<channel>
	<title>Coherent Ramblings &#187; ruby</title>
	<atom:link href="http://plathrop.tertiusfamily.net/blog/tag/ruby/feed/" rel="self" type="application/rss+xml" />
	<link>http://plathrop.tertiusfamily.net/blog</link>
	<description>My thoughts on everything from Operations through Parenting and beyond.</description>
	<lastBuildDate>Thu, 03 Jun 2010 17:12:31 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Capistrano</title>
		<link>http://plathrop.tertiusfamily.net/blog/2008/02/03/capistrano/</link>
		<comments>http://plathrop.tertiusfamily.net/blog/2008/02/03/capistrano/#comments</comments>
		<pubDate>Sun, 03 Feb 2008 22:51:58 +0000</pubDate>
		<dc:creator>plathrop</dc:creator>
				<category><![CDATA[Tools]]></category>
		<category><![CDATA[automation]]></category>
		<category><![CDATA[capistrano]]></category>
		<category><![CDATA[ruby]]></category>

		<guid isPermaLink="false">http://plathrop.tertiusfamily.net/blog/2008/02/03/capistrano/</guid>
		<description><![CDATA[One of the things you quickly learn as you become a more sophisticated systems administrator is that performing the same task on several servers is both tedious and error-prone. Of course, if your infrastructure has been deployed in an ad-hoc manner, sometimes you don&#8217;t have a choice; the task is unique on each machine simply [...]]]></description>
			<content:encoded><![CDATA[<p>One of the things you quickly learn as you become a more sophisticated systems administrator is that performing the same task on several servers is both tedious and error-prone. Of course, if your infrastructure has been deployed in an ad-hoc manner, sometimes you don&#8217;t have a choice; the task is unique on each machine simply because each machine has a unique configuration. However, once you have made the transition to stock configurations on multiple machines, you gain the ability to use new tools to perform tasks in parallel on a number of systems at once. The tendency for many admins is to <a href="http://sial.org/howto/openssh/publickey-auth/">set up public-key authentication</a> and hand-roll a script. This isn&#8217;t necessarily a bad approach; sometimes a quick-and-dirty script is all you really need to get the job done. On the other hand, there are tools which can make the process more elegant, consistent, and professional. The two I know of are <a href="http://sourceforge.net/projects/clusterssh/">ClusterSSH</a> and <a href="http://www.capify.org">Capistrano</a>.</p>
<p>I&#8217;m fairly new to Capistrano, but I&#8217;ve been using it to perform some simple tasks for a couple of months, and I&#8217;m really pleased with the results. I first encountered Capistrano when I was looking for a simple way to remove the SNMP agent from a group of about 20 machines. I knew I could whip up a script, but I had remembered reading a blog post somewhere (sorry, I don&#8217;t remember where) about ClusterSSH; several Google searches later I had found both ClusterSSH and Capistrano. At the time, I was learning Ruby (in order to get involved in <a href="http://puppet.reductivelabs.com">Puppet</a> development), so Capistrano seemed the natural choice.</p>
<p>According to the website, Capistrano was originally written to help deploy Ruby on Rails applications. Like many tools, it has grown beyond its initial mission, and is now a powerful tool for systems administration. Capistrano makes some assumptions about your infrastructure. First, you must be using SSH to access your systems, because Capistrano does not support older methods such as telnet (and if you are still using telnet, shame on you!) Second, your systems must have a POSIX shell in the default system path. For most *nix systems these days, this is a given. Finally, to *really* utilize Capistrano correctly, you should be using public-key authentication to access your servers. You don&#8217;t necessarily need to use password-less keys (in fact, I suggest you resist that temptation in general). Just use ssh-agent to keep your passphrase in memory. All of these assumptions are true for my environment, so I got started.</p>
<p>Installation was trivial using <a href="http://www.rubygems.org/">RubyGems</a>. Next I needed to create a &#8220;capfile&#8221; &#8211; the Capistrano equivalent of a &#8220;Makefile&#8221;. The &#8220;capfile&#8221; gives Capistrano information about your environment and defines &#8220;roles&#8221; and &#8220;tasks&#8221;. &#8220;Roles&#8221; describe groups of systems, &#8220;webservers&#8221; or &#8220;firewalls&#8221; for example. &#8220;Tasks&#8221; are the actions you wish to perform. After reading through the <a href="http://www.capify.org/getting-started/basics">Basics</a> on the Capistrano website, it was fairly simple to define a task to do what I wanted:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">task <span style="color:#ff3333; font-weight:bold;">:remove_snmp</span> <span style="color:#9966CC; font-weight:bold;">do</span>
  run <span style="color:#996600;">&quot;sudo aptitude -y purge snmp&quot;</span>
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p>One complication of my environment is that most of the systems are not directly accessible from outside. We have an SSH &#8220;bastion host&#8221; which acts as a gateway to the internal network. Luckily, Capistrano is ready for this. I added the following to the beginning of my capfile:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">set <span style="color:#ff3333; font-weight:bold;">:gateway</span>, <span style="color:#996600;">&quot;ssh-gateway.example.com&quot;</span></pre></div></div>

<p>This tells Capistrano to first establish an SSH connection to <samp>ssh-gateway.example.com</samp>, and connect from that machine to the systems we want to run commands on. &#8220;But how does Capistrano know what systems to run commands on?&#8221; you ask. Good question! That is what we need a &#8220;role&#8221; for:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">role <span style="color:#ff3333; font-weight:bold;">:de_snmp</span>, <span style="color:#996600;">&quot;server1.example.com&quot;</span>, <span style="color:#996600;">&quot;server2.example.com&quot;</span>, <span style="color:#996600;">&quot;server3.example.com&quot;</span>, <span style="color:#996600;">&quot;server4.example.com&quot;</span>, <span style="color:#996600;">&quot;server5.example.com&quot;</span>, <span style="color:#996600;">&quot;server6.example.com&quot;</span></pre></div></div>

<p>Before you run a task on all of your systems at once, you probably want to test it first. I usually try the task by hand on one or two systems. Once I am happy with the procedure and the results, I pick several less-critical (or easy to rollback) hosts to do a second pass on. Finally, after all is well with those hosts, I run the task on the full group. Here is our completed &#8220;capfile&#8221; for the second pass:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
</pre></td><td class="code"><pre class="ruby" style="font-family:monospace;">set <span style="color:#ff3333; font-weight:bold;">:gateway</span>, <span style="color:#996600;">&quot;ssh-gateway.example.com&quot;</span>
&nbsp;
role <span style="color:#ff3333; font-weight:bold;">:de_snmp</span>, <span style="color:#996600;">&quot;server1.example.com&quot;</span>, <span style="color:#996600;">&quot;server2.example.com&quot;</span>, <span style="color:#996600;">&quot;server3.example.com&quot;</span>, <span style="color:#996600;">&quot;server4.example.com&quot;</span>, <span style="color:#996600;">&quot;server5.example.com&quot;</span>, <span style="color:#996600;">&quot;server6.example.com&quot;</span>
&nbsp;
task <span style="color:#ff3333; font-weight:bold;">:remove_snmp</span>, <span style="color:#ff3333; font-weight:bold;">:roles</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#ff3333; font-weight:bold;">:de_snmp</span> <span style="color:#9966CC; font-weight:bold;">do</span>
  run <span style="color:#996600;">&quot;sudo aptitude -y purge snmp&quot;</span>
<span style="color:#9966CC; font-weight:bold;">end</span></pre></td></tr></table></div>

<p>As you can see, we&#8217;ve modified our &#8220;task&#8221; definition to apply to the &#8220;role&#8221; we created. All we have to do now is run <samp>cap remove_snmp</samp> and Capistrano will do its job! There is plenty of output, so it is fairly easy to review what is happening (though it can be challenging to follow the events on a single server unless you know your way around <samp>grep</samp>; you do, right?)</p>
<p>This is just the tip of the iceberg. Capistrano is very sophisticated, allowing your tasks to be self-documenting, divided into namespaces, use variables, and more! Perhaps the most powerful feature is the ability to define &#8220;transactions&#8221; and &#8220;rollback&#8221; functions. Although you still have to manually define what a &#8220;rollback&#8221; means, Capistrano allows you to do that once, and use the capability as often as necessary. In addition, you have the full power of Ruby at your command in Capistrano scripts. I haven&#8217;t had the need to explore these features but as I do I&#8217;ll be sure to share my experiences here!</p>
]]></content:encoded>
			<wfw:commentRss>http://plathrop.tertiusfamily.net/blog/2008/02/03/capistrano/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>
