<?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>Julian C. Dunn</title>
	<atom:link href="http://www.juliandunn.net/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.juliandunn.net</link>
	<description>Commentary on media, technology, and everything in between.</description>
	<lastBuildDate>Sat, 13 Apr 2013 03:43:14 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.5.1</generator>
		<item>
		<title>No idea what Veewee&#8217;s all about? Watch my screencast!</title>
		<link>http://www.juliandunn.net/2013/04/12/no-idea-what-veewees-all-about-watch-my-screencast/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=no-idea-what-veewees-all-about-watch-my-screencast</link>
		<comments>http://www.juliandunn.net/2013/04/12/no-idea-what-veewees-all-about-watch-my-screencast/#comments</comments>
		<pubDate>Sat, 13 Apr 2013 01:23:18 +0000</pubDate>
		<dc:creator>Julian Dunn</dc:creator>
				<category><![CDATA[Technology]]></category>
		<category><![CDATA[chef]]></category>
		<category><![CDATA[puppet]]></category>
		<category><![CDATA[veewee]]></category>
		<category><![CDATA[virtualbox]]></category>

		<guid isPermaLink="false">http://www.juliandunn.net/?p=809</guid>
		<description><![CDATA[A couple of days ago I wrote a post about Veewee, the automated boxgrinder for Virtualbox boxes. But if you had no idea what Veewee was, all that detail wouldn&#8217;t have made much sense to you. So I threw together a quick screencast on YouTube. Here it is!]]></description>
				<content:encoded><![CDATA[<p>A couple of days ago I wrote a post about <a href="http://github.com/jedi4ever/veewee.git">Veewee</a>, the automated boxgrinder for Virtualbox boxes. But if you had no idea what Veewee was, all that detail wouldn&#8217;t have made much sense to you. So I threw together a quick screencast on YouTube. Here it is!<br />
<iframe src="https://www.youtube.com/embed/3vaLTVkKCPI?rel=0" height="360" width="640" allowfullscreen="" frameborder="0"></iframe></p>
]]></content:encoded>
			<wfw:commentRss>http://www.juliandunn.net/2013/04/12/no-idea-what-veewees-all-about-watch-my-screencast/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Technology Preview: Chef Cookbook integration testing with Test Kitchen 1.0</title>
		<link>http://www.juliandunn.net/2013/04/12/technology-preview-chef-cookbook-integration-testing-with-test-kitchen-1-0/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=technology-preview-chef-cookbook-integration-testing-with-test-kitchen-1-0</link>
		<comments>http://www.juliandunn.net/2013/04/12/technology-preview-chef-cookbook-integration-testing-with-test-kitchen-1-0/#comments</comments>
		<pubDate>Fri, 12 Apr 2013 18:26:02 +0000</pubDate>
		<dc:creator>Julian Dunn</dc:creator>
				<category><![CDATA[Information Technology]]></category>

		<guid isPermaLink="false">http://www.juliandunn.net/?p=793</guid>
		<description><![CDATA[How do you test your Chef cookbooks without firing up a real machine and uploading the recipes to a Chef Server? I get asked this question all the time, especially after I&#8217;ve taught the basics of Chef at Opscode&#8217;s public training classes. For unit testing, there is ChefSpec &#8212; RSpec plus Chef primitives to allow [...]]]></description>
				<content:encoded><![CDATA[<div id="attachment_796" class="wp-caption alignright" style="width: 250px"><a href="http://www.juliandunn.net/wp-content/uploads/2013/04/kimball.jpg"><img class="size-full wp-image-796" alt="Chris Kimball of Cook's Illustrated at the American Museum of Natural History. (CC licensed.)" src="http://www.juliandunn.net/wp-content/uploads/2013/04/kimball.jpg" width="240" height="240" /></a><p class="wp-caption-text">Chris Kimball of Cook&#8217;s Illustrated at the American Museum of Natural History. (CC-Att-NC)</p></div>
<p>How do you test your Chef cookbooks without firing up a real machine and uploading the recipes to a Chef Server?</p>
<p>I get asked this question all the time, especially after I&#8217;ve taught the basics of Chef at Opscode&#8217;s <a href="http://www.opscode.com/blog/events/upcoming/">public training classes</a>. For unit testing, there is <a href="https://github.com/acrmp/chefspec">ChefSpec</a> &#8212; RSpec plus Chef primitives to allow you to make assertions about your recipes. However, that only goes so far without actually converging a real node &amp; running external tests on the services that were configured.</p>
<p>Last year, Opscode released <a href="https://github.com/opscode/test-kitchen">Test Kitchen</a>, allowing you to use workstation-based virtualization (in the form of VirtualBox) to fire up test nodes, converge them, and run Minitests and Cucumber behavioural-driven development (BDD) tests on them after the converge. In this article, I&#8217;ll show you how to set up Test Kitchen 1.0 with Vagrant 1.1 to write and run integration tests.</p>
<p><span id="more-793"></span></p>
<p>Before we begin, I have to warn you that <a href="https://github.com/opscode/test-kitchen/tree/1.0">Test Kitchen 1.0.0</a> is a major rewrite and still under heavy development &#8212; it is currently in alpha, so there <span style="text-decoration: line-through;">may</span> will still be bugs. In particular, the directions in the <a href="https://github.com/opscode/test-kitchen/blob/1.0/README.md">README</a> on the Test Kitchen GitHub refer to the use of Bundler, and this is no longer required or recommended.</p>
<p>One of the major new features in Test Kitchen is to abstract out the drivers for different virtualization providers from the actual Test Kitchen framework. This allows you to run your Kitchen tests on any virtualization provider: you could use Kitchen to converge on a VirtualBox machine when you&#8217;re on an airplane, but when you&#8217;re in the office, you could converge on an Amazon EC2 instance. For this demonstration, though, we&#8217;re going to continue to use VirtualBox for simplicity.</p>
<p>I&#8217;m going to assume you have both Chef and VirtualBox installed on your workstation. If you&#8217;ve used Opscode&#8217;s recommended Omnibus installer, Chef will be installed in /opt/chef (or C:\chef if on Windows) so those are the paths I&#8217;m going to refer to.</p>
<h2>Vagrant Installation</h2>
<p><a href="http://vagrantup.com/">Vagrant</a> is a framework for virtualization providers that allows you to rebuild environments from scratch, using a base image and applying the same provisioning logic you would normally run in your production environment to manage your infrastructure. For Puppet, that might mean your Puppet manifests; for Chef, it means your Chef cookbooks. There&#8217;s more information about Vagrant at <a href="http://vagrantup.com/">vagrantup.com</a>, but suffice it to say that we&#8217;ll be using it as the abstraction layer to VirtualBox, so go ahead and download &amp; install that.</p>
<h2>Berkshelf Installation, Part 1</h2>
<p><a href="http://berkshelf.com/">Berkshelf</a> is a cookbook artifact manager, which obviates you from having to store &#8220;upstream&#8221; or community cookbooks on your local machine, or even in your own source control management system. Test Kitchen uses it to satisfy the dependencies for the cookbook under test, so we&#8217;re going to install that as well.</p>
<p>There are two parts to the installation. The first part is to install the Berkshelf plugin for Vagrant, so that it knows to call out to Berkshelf when running the provisioning phase. So go ahead and do that:</p>
<blockquote>
<pre>$ vagrant plugin install berkshelf-vagrant --plugin-version 1.0.6
Installing the 'berkshelf-vagrant' plugin. This can take a few minutes...
Installed the plugin 'berkshelf-vagrant (1.0.6)'!</pre>
</blockquote>
<p><strong>Note: </strong>berkshelf-vagrant 1.1.0 won&#8217;t work until <a href="https://github.com/opscode/kitchen-vagrant/pull/14">this patch</a> gets merged to the Kitchen Vagrant driver. (Remember what I said about alpha software?)</p>
<p>We&#8217;ll install the other part of Berkshelf after we&#8217;ve installed Test Kitchen.</p>
<h2>Test Kitchen Installation</h2>
<p>Let&#8217;s install the pre-release version of Test Kitchen into Chef&#8217;s embedded Ruby:</p>
<blockquote>
<pre>$ sudo /opt/chef/embedded/bin/gem install test-kitchen --pre
Successfully installed test-kitchen-1.0.0.alpha.4
1 gem installed
Installing ri documentation for test-kitchen-1.0.0.alpha.4...
Installing RDoc documentation for test-kitchen-1.0.0.alpha.4...</pre>
</blockquote>
<p>We also need a virtualization driver for Test Kitchen; by default, no drivers are installed. Let&#8217;s install the Vagrant driver, since that&#8217;s what we&#8217;re going to use:</p>
<blockquote>
<pre>$ sudo /opt/chef/embedded/bin/gem install kitchen-vagrant
Succesfully installed kitchen-vagrant-0.7.4
1 gem installed
Installing ri documentation for kitchen-vagrant-0.7.4...
Installing RDoc documentation for kitchen-vagrant-0.7.4...</pre>
</blockquote>
<h2>Berkshelf Installation, Part 2</h2>
<p>We also need to make Test Kitchen aware that we&#8217;re using Berkshelf for cookbook artifact management, so let&#8217;s do that:</p>
<blockquote>
<pre>$ sudo /opt/chef/embedded/bin/gem install berkshelf
Successfully installed berkshelf-1.3.1
1 gem installed
Installing ri documentation for berkshelf-1.3.1...
Installing RDoc documentation for berkshelf-1.3.1...</pre>
</blockquote>
<p>That&#8217;s it! Now we&#8217;re ready to roll.</p>
<h2>Running Test Kitchen Tests</h2>
<p>Let&#8217;s not go into how to write tests for Test Kitchen just yet: let&#8217;s just get cooking using some pre-written <a href="https://github.com/calavera/minitest-chef-handler">Chef minitests</a> in the <a href="https://github.com/opscode-cookbooks/bluepill">Opscode bluepill</a> cookbook. Let&#8217;s clone that from GitHub and do some testing.</p>
<blockquote>
<pre>$ git clone https://github.com/opscode-cookbooks/bluepill.git</pre>
</blockquote>
<p>The <tt>.kitchen.yml</tt> file describes all the platforms we&#8217;re interested in testing, how to set them up to serve as a sensible test fixture for our tests, and finally, what the test suite consists of. In this situation, the test suite just sets up a couple of required attributes, and adds a <tt>bluepill_test</tt> cookbook to the test harness. You&#8217;ll see the code for that cookbook under <tt>test/cookbooks/bluepill_test</tt>. The suite also adds the <tt>minitest-handler</tt> cookbook to the run list, which is how the minitests (located in that test cookbook under <tt>files/default/tests/minitest</tt>) will actually get run.</p>
<p>Ok, so let&#8217;s start up our kitchen:</p>
<blockquote>
<pre>$ /opt/chef/embedded/bin/kitchen test
-----&gt; Starting Kitchen
-----&gt; Cleaning up any prior instances of 
-----&gt; Destroying 
       Finished destroying  (0m0.00s).
-----&gt; Testing 
-----&gt; Creating 
       [kitchen::driver::vagrant command] BEGIN (vagrant up --no-provision)
       Bringing machine 'default' up with 'virtualbox' provider...
       [default] Importing base box 'canonical-ubuntu-12.04'...</pre>
</blockquote>
<p>I&#8217;ve elided the rest of the output as it&#8217;s very long, but basically what Kitchen will do is to start up and try to converge a VM for every platform you&#8217;ve defined in the <tt>.kitchen.yml</tt>, and throw an exception if it fails on any one. Neat, huh?</p>
<h2>How Do I Write My Test Cases?</h2>
<p>The Chef Minitest framework provides you a lot of assertions out of the box; look at the documentation on <a href="https://github.com/calavera/minitest-chef-handler">GitHub</a> for some examples of how to write regular Minitest-style testcases, or spec-style testcases. There are also custom assertions bundled with Minitest.</p>
<p>As with many open-source projects, the README can be a bit lacking with respect to the features currently in Minitest Chef. The <a href="https://github.com/calavera/minitest-chef-handler/blob/v1.0.0/examples/spec_examples/files/default/tests/minitest/default_test.rb">default_test.rb</a> in the Minitest Chef Handler project shows a very comprehensive list of tests that can be made.</p>
<h2>Wrap-Up</h2>
<p>I&#8217;ve shown you how to integration test your cookbooks using Opscode Test Kitchen 1.0 Alpha, Berkshelf and Vagrant with VirtualBox as the underlying virtualization technology. Obviously, this is a field under heavy development, and some features could change between now and the actual release of Test Kitchen 1.0. But hopefully it&#8217;s enough to get you started.</p>
<h2>Additional Resources</h2>
<p>Joshua Timberman has a great <a href="http://jtimberman.housepub.org/blog/2013/03/19/anatomy-of-a-test-kitchen-1-dot-0-cookbook-part-1/">two-part series</a> on his <a href="http://jtimberman.housepub.org/">blog</a>, delving into more detail about Test Kitchen 1.0.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.juliandunn.net/2013/04/12/technology-preview-chef-cookbook-integration-testing-with-test-kitchen-1-0/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Book Review: &#8220;Instant Chef Starter&#8221;</title>
		<link>http://www.juliandunn.net/2013/04/11/book-review-instant-chef-starter/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=book-review-instant-chef-starter</link>
		<comments>http://www.juliandunn.net/2013/04/11/book-review-instant-chef-starter/#comments</comments>
		<pubDate>Thu, 11 Apr 2013 23:00:03 +0000</pubDate>
		<dc:creator>Julian Dunn</dc:creator>
				<category><![CDATA[Technology]]></category>

		<guid isPermaLink="false">http://www.juliandunn.net/?p=806</guid>
		<description><![CDATA[Packt Publishing has released &#8220;Instant Chef Starter&#8220;, a tiny (70 pages!) book on getting up and running quickly with Chef. I&#8217;ve posted a full review over at Opscode&#8217;s corporate blog.]]></description>
				<content:encoded><![CDATA[<p>Packt Publishing has released &#8220;<a href="http://t.co/g1NQwMo0lw">Instant Chef Starter</a>&#8220;, a tiny (70 pages!) book on getting up and running quickly with Chef. I&#8217;ve posted a full review over at <a href="http://www.opscode.com/blog/2013/04/11/instant-chef-starter/">Opscode&#8217;s corporate blog</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.juliandunn.net/2013/04/11/book-review-instant-chef-starter/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Reviving veewee after Vagrant 1.1</title>
		<link>http://www.juliandunn.net/2013/04/11/reviving-veewee-after-vagrant-1-1/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=reviving-veewee-after-vagrant-1-1</link>
		<comments>http://www.juliandunn.net/2013/04/11/reviving-veewee-after-vagrant-1-1/#comments</comments>
		<pubDate>Thu, 11 Apr 2013 05:04:43 +0000</pubDate>
		<dc:creator>Julian Dunn</dc:creator>
				<category><![CDATA[Information Technology]]></category>
		<category><![CDATA[chef]]></category>
		<category><![CDATA[vagrant]]></category>
		<category><![CDATA[veewee]]></category>

		<guid isPermaLink="false">http://www.juliandunn.net/?p=786</guid>
		<description><![CDATA[Recently, Mitchell Hashimoto released a major rewrite of Vagrant, the tool that lets you build, provision, and rebuild virtualized development environments at the click of a button. While the rewrite is great &#8212; it has many new features, chief amongst them the ability to use virtualization providers other than VirtualBox &#8212; it was a major [...]]]></description>
				<content:encoded><![CDATA[<p>Recently, <a href="http://twitter.com/mitchellh">Mitchell Hashimoto</a> released a major rewrite of <a href="http://docs.vagrantup.com/v2/getting-started/index.html">Vagrant</a>, the tool that lets you build, provision, and rebuild virtualized development environments at the click of a button. While the rewrite is great &#8212; it has many new features, chief amongst them the ability to use virtualization providers other than VirtualBox &#8212; it was a major architectural change, and this broke many tools that work with Vagrant. One of them is <a href="https://github.com/jedi4ever/veewee">veewee</a>, a popular tool from <a href="http://twitter.com/jedi4ever">Patrick Debois</a> that allows anyone to rebuild fresh Vagrant boxes. Here&#8217;s how I fixed my veewee installation for now. <span id="more-786"></span></p>
<p>Vagrant 1.1 represents a major rewrite. While the<a href="http://docs.vagrantup.com/v2/cli/index.html"> vagrant command-line tool</a> remains the same, the package format changes significantly. Vagrant 1.1.x is only being distributed as an &#8220;omnibus&#8221; package, which bundles Ruby and all the Rubygems that Vagrant needs. (In another post, we can argue about whether the trend towards omnibus Ruby installers is a good one or not.) Vagrant 1.1 also introduces a new plugin architecture, and developers hoping to add functionality to Vagrant must rewrite their plugins to be conformant with the new API. Some of the developers who have already rewritten their plugins include <a href="http://github.com/reset">Jamie Winsor</a>, the author of <a href="http://berkshelf.com/">Berkshelf</a>, and Cassiano Leal, the author of <a href="https://github.com/cassianoleal/vagrant-butcher">vagrant-butcher</a> (to clean up test node and client objects from <a href="http://opscode.com/">Chef</a> when using a Chef Server provisioner).</p>
<p><a href="http://github.com/jedi4ever/veewee.git">Veewee</a>, however, presents a special challenge. Veewee depends on Vagrant being available as a Rubygem, a format that Mitchell is no longer distributing officially. To solve this, we need to use Bundler to create a Gem directly from Git, and manage some of Veewee&#8217;s other bleeding-edge dependencies.</p>
<p>If you haven&#8217;t guessed already, this is a set of technologies that is in enormous flux, and my instructions here merely provide for a workaround until a more elegant solution comes about (if it does). That said, let&#8217;s write ourselves a Gemfile that&#8217;ll let us successfully install and run Veewee, based on Patrick&#8217;s own Gemfile:</p>
<blockquote>
<pre>source "https://rubygems.org"

gem "veewee", :git =&gt; 'https://github.com/jedi4ever/veewee.git', :ref =&gt; '333ffcaba291a3cca9a54ebb9bf48ef534d60cfd'

group :windows do
  gem "em-winrm", :git =&gt; 'https://github.com/hh/em-winrm.git', :ref =&gt; '31745601d3'
  gem "log4r"
end

group :test do
  gem "rake"
  gem "vagrant", :git =&gt; 'https://github.com/mitchellh/vagrant.git', :tag =&gt; 'v1.1.5'
  #gem "chef"
  #gem "knife-windows"
end</pre>
</blockquote>
<p>I&#8217;m not sure if all the groups are necessary, but I&#8217;m not familiar enough with Bundler to know what they&#8217;re used for.)</p>
<p>You&#8217;ll notice a couple key things here. First, I&#8217;m tying veewee itself to a particular commit hash &#8211; this points to HEAD at the time of writing, but since the project is under heavy development, there will be more commits after this. The reason I&#8217;m pointing to GitHub for veewee itself is because the version on Rubygems.org, 0.3.7, is quite old and a new one hasn&#8217;t been released for a while.</p>
<p>Second, in group :test, the Vagrant gem points to Mitchell&#8217;s GitHub repository with a particular tag attached to it &#8212; this represents the source code of the currently-released version, 1.1.5.</p>
<p>Now that we have a Gemfile set up, we can run <tt>bundle install</tt> to install all these Gems on our system, including the bleeding-edge ones (which won&#8217;t show up when you type <tt>gem list</tt>, but are nonetheless on your system).</p>
<p>To test, let&#8217;s try to build a <a href="http://www.centos.org/">CentOS</a> 6.4 box. Veewee&#8217;s convention is that box definitions live in a <tt>definitions</tt> directory, so let&#8217;s make a directory called <tt>definitions/CentOS-6.4-x86_64-minimal</tt> and copy the files out of <a href="https://github.com/jedi4ever/veewee/tree/master/templates/CentOS-6.4-x86_64-minimal">Patrick&#8217;s master repo</a> into there.</p>
<p>Now, we can try to build the box with the command</p>
<blockquote>
<pre>bundle exec veewee vbox build CentOS-6.4-x86_64-minimal</pre>
</blockquote>
<p>(assuming we&#8217;re going to use VirtualBox to build it). If this works, you should get a lot of output as veewee brings up a new VirtualBox machine, automates the operating system installation, and installs Chef, Puppet, and makes a few other system customizations to make it conform to the Vagrant box interface. Once done, you can type</p>
<blockquote>
<pre>bundle exec veewee vbox validate CentOS-6.4-x86_64-minimal</pre>
</blockquote>
<p>to run some basic tests against that box to ensure it meets that interface.</p>
<p>Finally, once we&#8217;re satisfied, we can then export this box using</p>
<blockquote>
<pre>bundle exec veewee vbox export CentOS-6.4-x86_64-minimal</pre>
</blockquote>
<p>Voilà, we have a box file we can use with VirtualBox and Vagrant in the usual fashion.</p>
<p>To summarize: the current interactions between Vagrant 1.1 and some older plugins are still shaky, but developers are working hard to adapt to the new plugin architecture. (Another example where heavy development is occurring is on the <a href="https://github.com/BIAINC/vagrant-windows/">vagrant-windows</a> plugin, which is <a href="https://github.com/BIAINC/vagrant-windows/issues/20">still not compatible with Vagrant 1.1</a>.) Until these problems are worked out, workaround procedures like the above, for veewee, are necessary.</p>
<p>Later in the week, I&#8217;ll talk about how to get a local Chef cookbook development environment set up using Vagrant 1.1 and Berkshelf. Stay tuned.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.juliandunn.net/2013/04/11/reviving-veewee-after-vagrant-1-1/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Autoscaling Builds with Jenkins&#8217; EC2 Plugin and Chef</title>
		<link>http://www.juliandunn.net/2013/03/04/autoscaling-builds-with-jenkins-ec2-plugin-and-chef/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=autoscaling-builds-with-jenkins-ec2-plugin-and-chef</link>
		<comments>http://www.juliandunn.net/2013/03/04/autoscaling-builds-with-jenkins-ec2-plugin-and-chef/#comments</comments>
		<pubDate>Tue, 05 Mar 2013 04:44:57 +0000</pubDate>
		<dc:creator>Julian Dunn</dc:creator>
				<category><![CDATA[Technology]]></category>

		<guid isPermaLink="false">http://www.juliandunn.net/?p=776</guid>
		<description><![CDATA[One of my last projects at SecondMarket was to automate and rebuild the Jenkins infrastructure. We&#8217;d previously had a static setup in the NYC office with a build master and three slaves that ran all the time, but this handled developer check-in storms very poorly. For example, when developers were trying to make code cutoff [...]]]></description>
				<content:encoded><![CDATA[<p>One of my last projects at <a href="https://www.secondmarket.com/">SecondMarket</a> was to automate and rebuild the Jenkins infrastructure. We&#8217;d previously had a static setup in the NYC office with a build master and three slaves that ran all the time, but this handled developer check-in storms very poorly. For example, when developers were trying to make code cutoff for a feature, many builds would be queued for lack of available executors. But at other times, these agents would be completely idle. It made more sense to move the entire setup to the cloud and implement some kind of auto-scaling for Jenkins.<span id="more-776"></span></p>
<h3>The Jenkins Amazon EC2 Plugin</h3>
<p>We decided to implement the <a href="https://wiki.jenkins-ci.org/display/JENKINS/Amazon+EC2+Plugin">Jenkins Amazon EC2 plugin</a> on the master to spin up new slaves when there are jobs waiting. After a certain configurable period of inactivity, the EC2 plugin will suspend or terminate the instances. The main problem we had to solve is that SecondMarket&#8217;s build process &amp; test suite require the presence of many packages, representing the key parts of our stack: a JDK, PostgreSQL, MongoDB, etc. We&#8217;ve spent a lot of time automating the provisioning process for these services using Chef. But we don&#8217;t want to bootstrap all these transient nodes off our Chef server and have lots of dead client and node objects lying around. How can we leverage the work we&#8217;ve done with Chef in a world where a &#8220;golden image&#8221; AMI is required?</p>
<h3>Instance Metadata to the Rescue</h3>
<p>Amazon EC2 allows you to pass in &#8220;<a href="http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/AESDG-chapter-instancedata.html">instance metadata</a>&#8221; (or just &#8220;instance data&#8221;) on bootup, so does the Jenkins plugin. By convention, instance data is a shell script run once by the target system after the machine is up. (Of course, the target system&#8217;s AMI must include some way to run it: most people have <a href="https://help.ubuntu.com/community/CloudInit">cloud-init</a> in EC2 AMIs for this reason.) Initially, I&#8217;d hoped to call <a href="http://docs.opscode.com/chef_solo.html">Chef Solo</a> directly in the instance data script, so that I could just use a bare, generic CentOS 6 AMI in Jenkins. This proved to be infeasible due to the provisioning time. In addition to the startup time for the instance (about five minutes), the first run of Chef Solo took another five to seven minutes, so it would be almost fifteen minutes before a new slave could come online.</p>
<p>Instead, I agreed on a compromise with our build master: we&#8217;d use Chef Solo to build the golden image and automate that process. If changes are required to the AMI, we could commit them to our Chef repository, create a new Chef Solo bundle, and rebuild a new AMI. (Down the road SecondMarket might even consider having Jenkins perform the whole process, which would be a strange <a href="http://www.imdb.com/title/tt0120601/">Malkovichian</a> development to this whole scheme.)</p>
<h3>The Code</h3>
<p>First we need a script to generate the Chef Solo tarball. I wrote a <a href="https://github.com/secondmarket/jenkins-ec2-autoscaling/blob/master/snapshot-cookbooks.sh">very simple one</a> to check out the master branch of every relevant cookbook and create a tarball of it, which could be put on our internal repository server, accessible by HTTP.</p>
<p>Then, we pass an <a href="https://github.com/secondmarket/jenkins-ec2-autoscaling/blob/master/instance-data.sh">instance data script</a> to the EC2 bootstrap that installs Chef, sets up a dummy role called jenkins-node-solo-role, and runs Chef Solo to provision the machine. This is done using the Amazon EC2 tools:</p>
<blockquote>
<pre><code>% ec2-run-instances -f instance-data.sh -g whatever -k some-key -t m1.small ami-XXXXXXXX</code></pre>
</blockquote>
<p>Once satisfied, we can snapshot the instance and create an AMI from it:</p>
<blockquote>
<pre><code>% ec2-create-image -n "jenkins-node-image-20130226" i-XXXXXXXX</code></pre>
</blockquote>
<p>Now just configure Jenkins to use the new AMI ID as the slave image and we&#8217;re done. (Don&#8217;t forget to kill off the temporary instance.)</p>
<h3>Conclusions and Future Work</h3>
<p>I learned a couple of lessons from doing this, chief amongst them being that if your role&#8217;s JSON doesn&#8217;t have <tt>"json_class": "Chef::Role"</tt> you get some truly bizarre error messages. That took me a half day to track down.</p>
<p>Ideally I&#8217;d love to have some BDD tests that would describe the target state of the slave machine (e.g. &#8220;must have MongoDB installed&#8221;) that could be run right after the Chef Solo run. I spent perhaps ten iterations of building AMIs using this process only for the build master to complain that something was missing on the image. It took a lot of tweaking to get the run list right.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.juliandunn.net/2013/03/04/autoscaling-builds-with-jenkins-ec2-plugin-and-chef/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>I&#8217;m joining Opscode!</title>
		<link>http://www.juliandunn.net/2013/03/03/im-joining-opscode/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=im-joining-opscode</link>
		<comments>http://www.juliandunn.net/2013/03/03/im-joining-opscode/#comments</comments>
		<pubDate>Mon, 04 Mar 2013 04:49:57 +0000</pubDate>
		<dc:creator>Julian Dunn</dc:creator>
				<category><![CDATA[Internet Services]]></category>

		<guid isPermaLink="false">http://www.juliandunn.net/?p=778</guid>
		<description><![CDATA[Tomorrow I&#8217;ll be joining Opscode as a senior consultant for Chef. My job responsibilities will be diverse, encompassing training, evangelism, and also working on projects for customers large and small. I&#8217;m extremely excited to be working for a company whose product has been revolutionizing the job responsibilities of the traditional system administrator, and even those [...]]]></description>
				<content:encoded><![CDATA[<p><a href="http://www.juliandunn.net/wp-content/uploads/2013/03/opscode.png"><img class="alignleft  wp-image-779" alt="opscode logo" src="http://www.juliandunn.net/wp-content/uploads/2013/03/opscode-300x166.png" width="180" height="100" /></a>Tomorrow I&#8217;ll be joining <a title="When Application and Library Cookbooks Fail" href="http://www.opscode.com/">Opscode</a> as a senior consultant for Chef. My job responsibilities will be diverse, encompassing training, evangelism, and also working on projects for customers large and small.</p>
<p>I&#8217;m extremely excited to be working for a company whose product has been revolutionizing the job responsibilities of the traditional system administrator, and even those of the software engineer. It&#8217;s easier to break down the walls between operations and development when all your infrastructure is code, and Chef makes that a no-brainer. Frankly, it&#8217;s also more fun for everyone &#8212; yes, it&#8217;s possible for web operations to be fun again, just like it was back in 1996 when I got into this sort of thing.</p>
<p>I&#8217;m looking forward to working with all of the really smart people at Opscode, and, if you&#8217;re part of the Chef community, with you as well. See you around, maybe at a conference, training session, or just in IRC!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.juliandunn.net/2013/03/03/im-joining-opscode/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>When Application and Library Cookbooks Fail</title>
		<link>http://www.juliandunn.net/2013/01/23/when-application-and-library-cookbooks-fail/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=when-application-and-library-cookbooks-fail</link>
		<comments>http://www.juliandunn.net/2013/01/23/when-application-and-library-cookbooks-fail/#comments</comments>
		<pubDate>Thu, 24 Jan 2013 04:40:46 +0000</pubDate>
		<dc:creator>Julian Dunn</dc:creator>
				<category><![CDATA[Technology]]></category>

		<guid isPermaLink="false">http://www.juliandunn.net/?p=768</guid>
		<description><![CDATA[Apologies in advance if you&#8217;re not interested in a post about the guts of Opscode Chef. I recently started to adopt Bryan Berry&#8217;s application &#38; library cookbook model as outlined in his excellent and funny blog post, &#34;How to Write Reusable Chef Cookbooks, Gangnam Style&#34;. But I quickly ran into a blocker, because people are [...]]]></description>
				<content:encoded><![CDATA[<p><em>Apologies in advance if you&#8217;re not interested in a post about the guts of <a href="http://www.opscode.com/">Opscode</a> Chef.</em></p>
<p>I recently started to adopt Bryan Berry&#8217;s application &amp; library cookbook model as outlined in his excellent and funny blog post, &quot;<a href="http://devopsanywhere.blogspot.com/2012/11/how-to-write-reusable-chef-cookbooks.html">How to Write Reusable Chef Cookbooks, Gangnam Style</a>&quot;. But I quickly ran into a blocker, because people are trying to solve problems using the compile phase and not the execute phase of Chef. Perhaps this calls into question the entire viability of compile-phase providers like <tt>chef_gem</tt>.<span id="more-768"></span></p>
<p>Let&#8217;s recap Bryan&#8217;s post quickly. He argues for vastly simplifying the number and complexity of bespoke cookbooks that sysadmins have to maintain by leveraging existing, high-quality community cookbooks as &#8220;libraries&#8221;. (The most common source of these library cookbooks is, of course, the <a href="https://github.com/opscode-cookbooks/">Opscode Cookbooks</a> GitHub repo.) Then, by creating a small bespoke cookbook (the &#8220;application&#8221; cookbook) that overrides certain attributes &amp; behaviors, you can achieve the desired customizations for your own environment. As a trivial example, suppose you had a popular web application called &#8220;instachef&#8221; that just got bought by <a href="http://vialstudios.com/guide-authoring-cookbooks.html">MyFace</a>, and you need to handle more traffic in the Apache <tt>VirtualHost</tt> that&#8217;s fronting it. Well, you might create an <tt>instachef::server</tt> recipe that does nothing more than</p>
<blockquote>
<pre>node.set['apache']['prefork']['maxclients'] = 31337
include_recipe "apache2"</pre>
</blockquote>
<p>thereby overriding the default attributes in the <tt>apache2</tt> cookbook but re-using all the logic that Opscode and other community members have put in there. Seems logical, right?</p>
<p>I wanted to do the same thing with the PostgreSQL cookbook: that is, I wanted to wrap the community&#8217;s with one that sets up Yum repos from the PostgreSQL Global Development Group (PGDG) and then installs PostgreSQL 9.2 instead of PostgreSQL 8.x on CentOS servers. The PGDG recipe looks something like this:</p>
<p><script src="https://gist.github.com/4617515.js"></script></p>
<p>and then the <tt>run_list</tt> in my Berkshelf-managed Vagrant VM is just &#8220;<tt>recipe[smpostgresql::pgdb], recipe[postgresql::server]</tt>&#8220;. This works great: I get PostgreSQL 9.2 installed on the VM. So far, so good.</p>
<p>Things break down, however, when I want to use the <tt>database</tt> and <tt>database_user</tt> LWRPs to manage a set of databases and users. In order to use the LWRPs which run in the execute phase, I need to have the &#8220;pg&#8221; Rubygem installed in the compile phase. But the &#8220;pg&#8221; Gem has native extensions which must be compiled against the headers of the PostgreSQL I want, and I can&#8217;t retrieve those for PostgreSQL 9.2 until the execute phase, when the <tt>pgdg</tt> recipe sets up a Yum repo for me to retrieve them from! Argh, chicken and egg problem.</p>
<p>I think the root cause of this problem is that people are abusing the compile-phase of the Chef run to do things that normally would be done in the execute phase. Just look at the source code of <a href="https://github.com/opscode-cookbooks/postgresql/blob/master/recipes/ruby.rb">postgresql::ruby</a>: it&#8217;s almost like an entire recipe, forcibly run in the compile phase. Whenever I see code that breaks the boundaries between execute and compile, I think something&#8217;s seriously wrong.</p>
<p>I don&#8217;t know the internals of Chef and I&#8217;m no Ruby expert, so I don&#8217;t know how viable my solution is. But conceptually, this would all be solved if <tt>chef_gem</tt> was an execute-time resource only. Doing so would mean that other recipes that actually belong in the execute phase &#8212; like downloading <tt>postgresql92-devel</tt> and a C compiler &#8212; could be done ahead of installing the gem. It&#8217;s almost like we need <a href="http://en.wikipedia.org/wiki/Lazy_evaluation">lazy evaluation</a> of the <tt>require "pg"</tt> call, until the execute phase, at which point the <tt>LoadError</tt> could be rescued, the Gem installation could proceed, and the <tt>require</tt> retried.</p>
<p>I&#8217;m interested to know what other Chef practitioners think. In the meantime, I&#8217;m working around the issue by simply avoiding using the LWRPs.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.juliandunn.net/2013/01/23/when-application-and-library-cookbooks-fail/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Retweets Aren&#8217;t Endorsements: Why Not?</title>
		<link>http://www.juliandunn.net/2012/12/27/retweets-arent-endorsements-why-not/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=retweets-arent-endorsements-why-not</link>
		<comments>http://www.juliandunn.net/2012/12/27/retweets-arent-endorsements-why-not/#comments</comments>
		<pubDate>Thu, 27 Dec 2012 18:17:00 +0000</pubDate>
		<dc:creator>Julian Dunn</dc:creator>
				<category><![CDATA[Culture]]></category>

		<guid isPermaLink="false">http://www.juliandunn.net/?p=759</guid>
		<description><![CDATA[After seeing yet another person whose Twitter profile says &#8220;retweets ≠ endorsements&#8221;, I feel compelled to say something. &#8220;RT ≠ endorsement&#8221; doesn&#8217;t distance you from something you&#8217;re retweeting. Rather, it&#8217;s the electronic equivalent of the annoying phrase just sayin&#8217;: a passive-aggressive way of making a statement while pretending not to have made a statement. Sorry, but I [...]]]></description>
				<content:encoded><![CDATA[<p><img class="alignleft size-full wp-image-763" alt="not equals" src="http://www.juliandunn.net/wp-content/uploads/2012/12/2131047005_62ce21d6b0_q.jpg" width="150" height="150" />After seeing yet another person whose Twitter profile says &#8220;retweets ≠ endorsements&#8221;, I feel compelled to say something. &#8220;RT ≠ endorsement&#8221; doesn&#8217;t distance you from something you&#8217;re retweeting. Rather, it&#8217;s the electronic equivalent of the annoying phrase <em>just sayin&#8217;</em>: a passive-aggressive way of making a statement while pretending not to have made a statement. Sorry, but I call shenanigans.</p>
<p>I understand that sometimes you want to comment on someone&#8217;s opinions by simply showing their own words. In that situation, why not add your voice to the conversation by prepending a couple words to the retweet, or condensing/summarizing the original tweet using a MT (Modified Tweet)? People follow you on Twitter because they want to know your perspective on things. You shouldn&#8217;t just be a mouthpiece for other people.</p>
<p>In short: If you don&#8217;t completely agree with or endorse an opinion on Twitter, don&#8217;t just blindly retweet it and think that &#8220;RT ≠ endorsement&#8221; will cover you. Add some color to the retweet to clarify where you stand. Not only will you show that you&#8217;re not afraid to have an opinion, but your followers will thank you for continuing the conversation. Isn&#8217;t that what Twitter is about, after all?</p>
<p><em>Image from <a href="http://www.flickr.com/photos/holeymoon/2131047005/">holeymoon on Flickr</a>. CC-licensed.</em></p>
]]></content:encoded>
			<wfw:commentRss>http://www.juliandunn.net/2012/12/27/retweets-arent-endorsements-why-not/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>What Your CDN Won&#8217;t Tell You: Optimizing a News Website for Speed and Stability</title>
		<link>http://www.juliandunn.net/2012/12/26/what-your-cdn-wont-tell-you-optimizing-a-news-website-for-speed-and-stability/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=what-your-cdn-wont-tell-you-optimizing-a-news-website-for-speed-and-stability</link>
		<comments>http://www.juliandunn.net/2012/12/26/what-your-cdn-wont-tell-you-optimizing-a-news-website-for-speed-and-stability/#comments</comments>
		<pubDate>Thu, 27 Dec 2012 04:08:25 +0000</pubDate>
		<dc:creator>Julian Dunn</dc:creator>
				<category><![CDATA[Internet Services]]></category>

		<guid isPermaLink="false">http://www.juliandunn.net/?p=757</guid>
		<description><![CDATA[I was recently in San Diego giving a talk at LISA &#8217;12 entitled &#8220;What Your CDN Won&#8217;t Tell You: Optimizing a News Website for Speed and Stability&#8220;. The paper was based on work my colleague Blake Crosby and I did at the Canadian Broadcasting Corporation to rearchitect their website &#38; integrate it successfully with Akamai&#8216;s [...]]]></description>
				<content:encoded><![CDATA[<p>I was recently in San Diego giving a talk at LISA &#8217;12 entitled &#8220;<a href="https://www.usenix.org/conference/lisa12/what-your-cdn-won%E2%80%99t-tell-you-optimizing-news-website-speed-and-cost">What Your CDN Won&#8217;t Tell You: Optimizing a News Website for Speed and Stability</a>&#8220;. The paper was based on work my colleague <a href="http://blog.blakecrosby.com/">Blake Crosby</a> and I did at the <a href="http://cbc.radio-canada.ca/">Canadian Broadcasting Corporation</a> to rearchitect their website &amp; integrate it successfully with <a href="http://www.akamai.com/">Akamai</a>&#8216;s EdgeSuite content delivery network, enabling it to serve over a million unique visitors daily with high availability.</p>
<p>I&#8217;m pleased to announce that the <a href="https://www.usenix.org/conference/lisa12/what-your-cdn-won%E2%80%99t-tell-you-optimizing-news-website-speed-and-cost">slides from the presentation</a> are now available, and the video (eek!) will be shortly.</p>
<p>Hope everyone&#8217;s having a great holiday and I promise there will be more blog posts in the New Year.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.juliandunn.net/2012/12/26/what-your-cdn-wont-tell-you-optimizing-a-news-website-for-speed-and-stability/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Automating Atlassian JIRA, Confluence, and Crowd Installation with Chef</title>
		<link>http://www.juliandunn.net/2012/11/20/automating-atlassian-product-installation/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=automating-atlassian-product-installation</link>
		<comments>http://www.juliandunn.net/2012/11/20/automating-atlassian-product-installation/#comments</comments>
		<pubDate>Wed, 21 Nov 2012 01:27:32 +0000</pubDate>
		<dc:creator>Julian Dunn</dc:creator>
				<category><![CDATA[Technology]]></category>
		<category><![CDATA[atlassian]]></category>
		<category><![CDATA[chef]]></category>
		<category><![CDATA[confluence]]></category>
		<category><![CDATA[crowd]]></category>
		<category><![CDATA[jira]]></category>

		<guid isPermaLink="false">http://www.juliandunn.net/?p=752</guid>
		<description><![CDATA[As a user, I&#8217;ve always been impressed with Atlassian&#8216;s products for software development, issue tracking and documentation. For companies who take these things seriously, JIRA, Greenhopper and Confluence are quickly becoming the go-to products, and with good reason: the products are easy to get started with but have the enterprise features that allow a company [...]]]></description>
				<content:encoded><![CDATA[<p>As a user, I&#8217;ve always been impressed with <a href="http://www.atlassian.com/">Atlassian</a>&#8216;s products for software development, issue tracking and documentation. For companies who take these things seriously, <a href="http://www.atlassian.com/software/jira/">JIRA</a>, <a href="http://www.atlassian.com/software/greenhopper/">Greenhopper</a> and <a href="http://www.atlassian.com/software/confluence">Confluence</a> are quickly becoming the go-to products, and with good reason: the products are easy to get started with but have the enterprise features that allow a company to customize workflows as their business changes. I hate to slam open-source products but just try doing what JIRA does with <a href="http://www.bugzilla.org/">Bugzilla</a> or <a href="http://trac.edgewall.org/">Trac</a>.</p>
<p>The products themselves, though, can be a nightmare to install, despite the fact that they are mostly just Java web applications living in a WAR file. The products have improved immensely from the days when setting them up involved hacking up a multitude of XML files in <tt>WEB-INF</tt> (though there still is some of that), and it&#8217;s still annoying that Atlassian doesn&#8217;t support running the applications as unexploded WARs within Tomcat or another servlet container, probably for the aforementioned reasons. All that aside, though, it&#8217;s satisfying when everything is working together and users can single-sign-onto the entire Atlassian suite because of the magic of <a href="https://www.atlassian.com/software/crowd">Crowd</a>, Atlassian&#8217;s SSO directory server.</p>
<p>Last week, <a href="http://engineering.secondmarket.com/post/35852260325/atlassian-cookbooks">I released a set of Chef cookbooks</a> I wrote at <a href="https://www.secondmarket.com/">SecondMarket</a> to ease the installation of the Atlassian tools on a server. I&#8217;m still looking to automate more parts of this, including the ability to edit the aforementioned XML files in-place in an idempotent way, so pull requests against our <a href="https://github.com/secondmarket-cookbooks/">GitHub repo</a> would be welcome.</p>
<h3>Special Note on Using Atlassian Products in the Amazon Cloud</h3>
<p>I should also mention that my first attempt to set up Atlassian&#8217;s products using Amazon Relational Database Service (RDS) as a backing store was a failure. To spare you the pain of finding this out yourself, I&#8217;ll just mention the reason: Crowd, JIRA and Confluence expect MySQL to be configured with <tt>READ-COMMITTED</tt> transaction isolation level, which means you <a href="https://confluence.atlassian.com/display/CROWDKB/Crowd+Doesn%27t+Start+if+Using+MySQL+with+Binary+Logging">need to configure MySQL to have row-based binary-logging</a>. Unfortunately, <tt>binlog_format</tt> is not a parameter you can configure in RDS&#8217;s DB Parameter Groups, for obvious reasons; it would affect all other clients on that MySQL instance. This has been confirmed with Amazon support, so JIRA/Crowd/Confluence with RDS is a no-go.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.juliandunn.net/2012/11/20/automating-atlassian-product-installation/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
