<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom"><title>Cryptocracy</title><link href="https://www.cryptocracy.com/" rel="alternate"/><link href="http://www.cryptocracy.com/feeds/all.atom.xml" rel="self"/><id>https://www.cryptocracy.com/</id><updated>2015-04-26T23:35:00+01:00</updated><entry><title>Amazon Linux, And The Perils Of Continuous Release</title><link href="https://www.cryptocracy.com/blog/2015/04/26/amazon-linux-continuous-release/" rel="alternate"/><published>2015-04-26T23:35:00+01:00</published><updated>2015-04-26T23:35:00+01:00</updated><author><name>Zachary Stevens</name></author><id>tag:www.cryptocracy.com,2015-04-26:/blog/2015/04/26/amazon-linux-continuous-release/</id><summary type="html">&lt;p&gt;Amazon Linux 2015.03 caused widespread problems due to its continuous release default, which silently upgrades packages across major versions. Here's how to protect yourself, and why the default is wrong.&lt;/p&gt;</summary><content type="html">&lt;p&gt;A month ago, Amazon released Amazon Linux 2015.03, their
"continuous release" Linux distribution.  Widespread sadness ensued,
and I tweeted:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Amazon Linux users! If you didn't want surprise updates, you should have locked your yum repo_releasever. See release notes for details.&lt;/p&gt;
&lt;p&gt;— Zac Stevens (@zts) &lt;a href="https://twitter.com/zts/status/580777672890036224"&gt;March 25, 2015&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;While factually correct, that's a bad tweet which I quickly
regretted.
&lt;img alt="The Dude (from The Big Lebowski) saying &amp;quot;You're not wrong, you're just an asshole&amp;quot;" src="/images/not_wrong_just_asshole.jpg"&gt;
It's bad for being counterfactual, and displaying no trace of empathy.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;"If you didn't want surprise updates" - who &lt;em&gt;does&lt;/em&gt; want surprise updates?&lt;/li&gt;
&lt;li&gt;"You should have locked repo_releasever" - I realise that &lt;em&gt;now&lt;/em&gt;, thanks a lot asshole.&lt;/li&gt;
&lt;li&gt;"See release notes for details" - ...aaaand you're making me Google it.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;It's clearly directed at the person whose day sucked because of this issue, and it's kicking them while they're down.&lt;/p&gt;
&lt;p&gt;Worse still, it wasn't really without empathy; I had a bad day following the 2014.03 update a year ago, so I know full well what it feels like.  I guess I'm still kicking myself for my lack of foresight, and made a frustrated tweet aimed in the wrong direction.  Sorry, people of Twitter.&lt;/p&gt;
&lt;h2&gt;The Constructive Part&lt;/h2&gt;
&lt;p&gt;Amazon says:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;"Beginning with the 2011.09 release of the Amazon Linux AMI, the repository structure is configured to deliver a continuous flow of updates that allow you to roll from one version of the Amazon Linux AMI to the next.
...
In other words, Amazon Linux AMIs are treated as snapshots in time, with a repository and update structure that gives you the latest packages that we have built and pushed into the repository."&lt;/p&gt;
&lt;p&gt;— "Amazon Linux FAQ", &lt;a href="http://aws.amazon.com/amazon-linux-ami/faqs/"&gt;http://aws.amazon.com/amazon-linux-ami/faqs/&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;This means, by default, that an instance built using the Amazon Linux 2014.09 AMI will now upgrade packages to those in 2015.03.  Some of these upgrades will be harmless, while others will break your stuff.  Since computers lack a "don't break my stuff" option, you either live with that risk or disable these updates.&lt;/p&gt;
&lt;p&gt;The way to disable these updates is by pinning a Yum variable called &lt;code&gt;repo_releasever&lt;/code&gt;.  If you want to do this on a running instance, the file to edit is &lt;code&gt;/etc/yum.conf&lt;/code&gt;.  You can set this when starting new instances by providing this userdata:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="gh"&gt;#&lt;/span&gt;cloud-config
repo_releasever: 2015.03
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;See "How do I lock my AMI to a specific version?" in &lt;a href="http://aws.amazon.com/amazon-linux-ami/faqs/#lock"&gt;the Amazon Linux FAQs&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;The Critical Part&lt;/h2&gt;
&lt;p&gt;Amazon employs loads of smart people, and I'm sure there was a robust debate when considering the appropriate default to this setting.  But since I can't find a public justification for this decision, I will be blunt: they screwed this one up.  It's not hard to think of ways this default will end up ruining your day, and I struggle to find even tenuous arguments in support of it.&lt;/p&gt;
&lt;p&gt;I don't recall the specifics of my issues with 2014.03 - the default ruby changed from 1.8 to 2.0, and that definitely screwed up the mcollective packages I was using.  I also recall that the mysql gem I compiled for use with Chef broke, perhaps because the glibc version changed.&lt;/p&gt;
&lt;p&gt;2015.03 took greater care when changing the default python version; running systems updated from 2014.09 would install 2.7 alongside 2.6, but would not change the default.  This caused problems for anyone invoking the default python and expecting to interact with the yum repository (as all the system tooling was updated to use 2.7).&lt;/p&gt;
&lt;p&gt;The idea of "immutable infrastructure" is something of a fiction at the best of times, but I don't imagine anyone bakes an AMI expecting it will boot up with a certain set of packages on one day, and a different set of packages on another.  Similarly, I don't imagine anyone expects a CM run on their system to upgrade glibc or language runtimes unless they've explicitly configured it to do so.&lt;/p&gt;
&lt;h2&gt;tl;dr&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;The Amazon Linux AMIs ship with a default upgrade policy that thoroughly violates the principle of least surprise.&lt;/li&gt;
&lt;li&gt;This can be easily corrected by setting appropriate userdata (for new instances) or updating &lt;code&gt;yum.conf&lt;/code&gt; (for running instances).&lt;/li&gt;
&lt;li&gt;I'll be linking to this post in August to avoid looking like an asshole again in September.&lt;/li&gt;
&lt;/ul&gt;</content><category term="Blog"/><category term="aws"/></entry><entry><title>Dry Run CloudFormation Updates Using Ansible</title><link href="https://www.cryptocracy.com/blog/2015/04/03/dry-run-cloudformation-updates-using-ansible/" rel="alternate"/><published>2015-04-03T00:15:00+01:00</published><updated>2015-04-03T00:15:00+01:00</updated><author><name>Zachary Stevens</name></author><id>tag:www.cryptocracy.com,2015-04-03:/blog/2015/04/03/dry-run-cloudformation-updates-using-ansible/</id><summary type="html">&lt;p&gt;Unreleased patches to Ansible's CloudFormation module that implement a dry-run mode, comparing planned inputs against previous updates to show what would change.&lt;/p&gt;</summary><content type="html">&lt;p&gt;At &lt;a href="http://www.scalesummit.org"&gt;ScaleSummit&lt;/a&gt; last week, I mentioned
that I had some unreleased patches to Ansible's Cloudformation module
to implement a dry-run mode.  This piqued some interest, so I've
cleaned it up a little and am sharing it here.&lt;/p&gt;
&lt;p&gt;First, a disclaimer: I've spent precious little time with Python in
the last decade, and my primary goal was to write code that worked.
I wouldn't say I'm happy with it, but it works well enough for me.
Feel free to take it and run with it.&lt;/p&gt;
&lt;p&gt;If you just want the code, you'll
&lt;a href="https://github.com/zts/ansible-modules-core/commits/zts-cloudformation"&gt;find it on this branch&lt;/a&gt;;
otherwise read on for details...&lt;/p&gt;
&lt;h2&gt;Dry-Run Mode, You Say?&lt;/h2&gt;
&lt;p&gt;CloudFormation (the web service) doesn't have a dry-run mode - you
can't pass it a set of inputs and find out what it would do.  Still,
we can build a useful approximation by taking inspiration from Chef's
naming of this feature, "Why-Run?"  CloudFormation records the inputs
(template and parameters) used for each update, and we can compare
these to the inputs we plan to use.  The changes we find are the
reasons &lt;em&gt;why&lt;/em&gt; CloudFormation might do something during an update.&lt;/p&gt;
&lt;p&gt;What this can't tell us is what resources will be updated&lt;sup id="fnref:1"&gt;&lt;a class="footnote-ref" href="#fn:1"&gt;1&lt;/a&gt;&lt;/sup&gt;, whether
those updates will involve replacement of the resource, whether our
template is nonsense&lt;sup id="fnref:2"&gt;&lt;a class="footnote-ref" href="#fn:2"&gt;2&lt;/a&gt;&lt;/sup&gt;, etc.&lt;/p&gt;
&lt;p&gt;Will this be useful to you?  If your templates are simple enough that
a list of modified inputs is enough for you to reason about the
outcome, you'll find this useful.&lt;/p&gt;
&lt;h2&gt;What Does It Do?&lt;/h2&gt;
&lt;p&gt;When run in check mode (&lt;code&gt;ansible-playbook --check&lt;/code&gt;), a CloudFormation
task will be output like so:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="nl"&gt;TASK&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;create example-test cfn stack&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;**************************************&lt;/span&gt;
&lt;span class="nl"&gt;changed&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;example&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;{&lt;/span&gt;&lt;span class="ss"&gt;&amp;quot;changed&amp;quot;&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ss"&gt;&amp;quot;output&amp;quot;&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ss"&gt;&amp;quot;Stack would be updated, changes: [{&amp;#39;Template&amp;#39;: {u&amp;#39;Resources&amp;#39;: {u&amp;#39;DummyWaitHandle2&amp;#39;: &amp;#39;Added&amp;#39;, u&amp;#39;DummyWaitHandle&amp;#39;: &amp;#39;Removed&amp;#39;}}}, {u&amp;#39;SnapshotID&amp;#39;: {&amp;#39;to&amp;#39;: u&amp;#39;test-20150329&amp;#39;, &amp;#39;from&amp;#39;: u&amp;#39;test-20150330&amp;#39;}}]&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ss"&gt;&amp;quot;stack_outputs&amp;quot;&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;{&lt;/span&gt;&lt;span class="ss"&gt;&amp;quot;DBInstanceId&amp;quot;&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ss"&gt;&amp;quot;rdz5lp9i8ovmog&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ss"&gt;&amp;quot;FrontendELB&amp;quot;&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ss"&gt;&amp;quot;example-Frontend-1VIHBAZL8WUA1&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ss"&gt;&amp;quot;FrontendHostname&amp;quot;&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ss"&gt;&amp;quot;example-Frontend-1VIHBAZL8WUA1-1582281064.eu-west-1.elb.amazonaws.com&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ss"&gt;&amp;quot;SecurityGroup&amp;quot;&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ss"&gt;&amp;quot;example-test-SecurityGroup-16PP0KV5SCAS9&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ss"&gt;&amp;quot;SecurityGroup2&amp;quot;&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ss"&gt;&amp;quot;example-test-SecurityGroup2-I2ENEANIVZPF&amp;quot;&lt;/span&gt;&lt;span class="err"&gt;}}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;This is not particularly readable when wrapped in a terminal window -
still, it's an improvement on nothing.  I couldn't readily find any
way of producing nicely formatted output.  I originally wanted to show
a unified diff of the template changes, but that was completely
unreadable.  I did find a &lt;code&gt;--diff&lt;/code&gt; option in Ansible, but this
apparently only works for template changes and I couldn't figure out
how to use that here.&lt;/p&gt;
&lt;p&gt;I've also added a &lt;code&gt;described&lt;/code&gt; state, which just exposes a stack's
parameters.  I believe the idiomatic solution to this in Ansible would
be a lookup plugin&lt;sup id="fnref:3"&gt;&lt;a class="footnote-ref" href="#fn:3"&gt;3&lt;/a&gt;&lt;/sup&gt;, but I prefer this way.&lt;/p&gt;
&lt;h2&gt;What (Else) Does It Do Badly?&lt;/h2&gt;
&lt;p&gt;When I mentioned this at ScaleSummit, I didn't include a diff of the
template - only an indication that the template had changed.
Verifying parameter changes was valuable to me, but ScaleSummit
prodded me into taking another look at template comparison.&lt;/p&gt;
&lt;p&gt;So, the template diff mindlessly compares two json documents - it
doesn't understand anything about the semantics of CloudFormation
templates.  It descends recursively into dicts to find changes, &lt;s&gt;but
arrays are shown as the stringified before/after copies. This makes
changes to some resource types (eg, security groups) very noisy&lt;/s&gt;.&lt;/p&gt;
&lt;h2&gt;Room For Improvement&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;s&gt;Show only added/removed/changed array elements&lt;/s&gt;&lt;/li&gt;
&lt;li&gt;Limit template diff to a certain depth&lt;/li&gt;
&lt;li&gt;Show unified diff via &lt;code&gt;--diff&lt;/code&gt; option (if possible)&lt;/li&gt;
&lt;li&gt;Validate local template&lt;/li&gt;
&lt;li&gt;&lt;s&gt;Check mode for stack creation should show the parameters which will be used&lt;/s&gt;&lt;/li&gt;
&lt;li&gt;&lt;s&gt;Fake up outputs that will be created by a stack&lt;/s&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;EDIT:&lt;/strong&gt; I found the motivation to fix a few of those warts.&lt;/p&gt;
&lt;h2&gt;What's Next?&lt;/h2&gt;
&lt;p&gt;I mostly improve this as something annoys me when I happen to have
time for a diversion. While Ansible has made my use of CloudFormation
somewhat less vexing, it's not a huge step forward and I'm hoping to
replace this with Terraform in the near future.&lt;/p&gt;
&lt;p&gt;My gut feeling is that this won't be accepted upstream as-is, but I
haven't tried.  Leave a comment if you want to encourage me to
upstream it, or feel free to tidy it up and open a PR yourself.&lt;/p&gt;
&lt;div class="footnote"&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id="fn:1"&gt;
&lt;p&gt;We can be confident that any resources with template changes will update, but we don't know what others will be updated in consequence. ie, we suffer from false negatives.&amp;#160;&lt;a class="footnote-backref" href="#fnref:1" title="Jump back to footnote 1 in the text"&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id="fn:2"&gt;
&lt;p&gt;Though we could use the &lt;a href="http://boto.readthedocs.org/en/latest/ref/cloudformation.html#boto.cloudformation.connection.CloudFormationConnection.validate_template"&gt;validate_template&lt;/a&gt; function for this.&amp;#160;&lt;a class="footnote-backref" href="#fnref:2" title="Jump back to footnote 2 in the text"&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id="fn:3"&gt;
&lt;p&gt;See &lt;a href="http://www.unixdaemon.net/tools/ansible/ansible-cloudformation-lookups.html"&gt;this post&lt;/a&gt; by Dean Wilson.&amp;#160;&lt;a class="footnote-backref" href="#fnref:3" title="Jump back to footnote 3 in the text"&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;</content><category term="Blog"/><category term="aws"/><category term="ansible"/></entry><entry><title>Increasing Jenkins Executors With Chef</title><link href="https://www.cryptocracy.com/blog/2014/09/20/increasing-jenkins-executors-with-chef/" rel="alternate"/><published>2014-09-20T16:03:00+01:00</published><updated>2014-09-20T16:03:00+01:00</updated><author><name>Zachary Stevens</name></author><id>tag:www.cryptocracy.com,2014-09-20:/blog/2014/09/20/increasing-jenkins-executors-with-chef/</id><summary type="html">&lt;p&gt;A short Groovy script using the Jenkins cookbook's jenkins_script resource to set the number of build executors to twice the CPU core count.&lt;/p&gt;</summary><content type="html">&lt;p&gt;By default, Jenkins is configured to run one "build executor" for each
core in the server.  This is a reasonable default for CPU-bound
workloads (like most compile/test jobs), but it's a bit pessimistic in
my case - CI pipelines for my Chef cookbooks.&lt;/p&gt;
&lt;p&gt;Fortunately, the executor count can be increased with a small Groovy
script -
&lt;a href="http://stackoverflow.com/questions/21995606/setting-number-of-executors-in-jenkins-using-groovy"&gt;this thread on StackOverflow&lt;/a&gt;
told me what I needed to know.&lt;/p&gt;
&lt;p&gt;If you're already using
&lt;a href="https://supermarket.getchef.com/cookbooks/jenkins"&gt;the Jenkins cookbook&lt;/a&gt;
to manage your Jenkins server, you can run two executors per core like so:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="n"&gt;jenkins_script&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;set number of executors&amp;#39;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;do&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;command&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&amp;lt;-&lt;/span&gt;&lt;span class="dl"&gt;EOF&lt;/span&gt;
&lt;span class="sh"&gt;import hudson.model.*&lt;/span&gt;

&lt;span class="sh"&gt;// Set executors to twice the number of CPU cores&lt;/span&gt;
&lt;span class="sh"&gt;Hudson hudson = Hudson.getInstance()&lt;/span&gt;
&lt;span class="sh"&gt;hudson.setNumExecutors(#{node[&amp;#39;cpu&amp;#39;][&amp;#39;total&amp;#39;] * 2})&lt;/span&gt;
&lt;span class="sh"&gt;hudson.setNodes(hudson.getNodes())&lt;/span&gt;
&lt;span class="sh"&gt;hudson.save()&lt;/span&gt;
&lt;span class="dl"&gt;  EOF&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</content><category term="Blog"/><category term="chef"/></entry><entry><title>Five Things I Hate About Chef</title><link href="https://www.cryptocracy.com/blog/2014/04/29/five-things-i-hate-about-chef/" rel="alternate"/><published>2014-04-29T14:00:00+01:00</published><updated>2014-04-29T14:00:00+01:00</updated><author><name>Zachary Stevens</name></author><id>tag:www.cryptocracy.com,2014-04-29:/blog/2014/04/29/five-things-i-hate-about-chef/</id><summary type="html">&lt;p&gt;Inspired by brian d foy's challenge to language advocates, here are five things I hate about Chef -- my favourite configuration management tool -- after several years of daily use.&lt;/p&gt;</summary><content type="html">&lt;p&gt;Seven years ago, brian d foy proposed a question for would-be language
advocates:
&lt;a href="http://web.archive.org/web/20110818051637/http://use.perl.org/~brian_d_foy/journal/32556"&gt;"What do you hate most about your language?"&lt;/a&gt;.
His point was that if you're not familiar enough with something to hate
parts of it, you don't know it well enough to be an effective
advocate.  At the time, it inspired some great posts in a few
programming language communities.  More recently, I was reminded of
the question after reading one too many posts praising some new config
management tool that went something like this:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;I've been using X for two weeks, and it's awesome!
I used Chef/Puppet before and it took me weeks to understand it.
X was so easy to use, I did [some trivial task] in my first half hour!
I thoroughly recommend it.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Such advocacy is profoundly uninteresting.  Beyond the fact that you
only get started with a tool once, the consequences of a tool's design
decisions often take time to make themselves apparent.  The magic that
made your first hour easy as a solo user might make life difficult
working in a team; or the elegant simplicity in your pilot project
might require a pile of hacks six months later at scale.  One person's
minor irritations are another's dealbreakers, so I love hearing what
folks think of their preferred tools after they've had to live with
them for a while.&lt;/p&gt;
&lt;p&gt;I've been using Chef for the last few years, and it's currently my
favourite tool, so here's five things I hate about it:&lt;/p&gt;
&lt;h2&gt;1. No partial updates to node data in the Chef server&lt;/h2&gt;
&lt;p&gt;Chef doesn't provide any way to update a subset of a node's data -
each update replaces the copy on the server, and the last writer
wins.  This means that if you update the server while a node is in the
middle of a Chef run, you may find your changes are reverted when
chef-client saves the node at the end of the run.&lt;/p&gt;
&lt;p&gt;Related to this, &lt;code&gt;knife node from file&lt;/code&gt; should have a big disclaimer
attached to it.  Some folks want to keep their basic node data in
version control, and use that subcommand to upload changes.  This
erases almost everything about the node from the server, so any
searches relying on computed or saved attributes will fail until
the next chef-client run saves the full node again.&lt;/p&gt;
&lt;p&gt;This is not an easy problem to solve.  Fortunately, you're allowed to
hate things that can't be easily fixed.&lt;/p&gt;
&lt;h2&gt;2. No standard solution for secure attributes&lt;/h2&gt;
&lt;p&gt;The standard way of parameterising recipes is attributes.  The
standard way of securing secrets for use by Chef is encrypted
databags.  Databags and attributes are entirely separate mechanisms,
and different methods are used to load encrypted and regular
databags.  This means that the only cookbooks that load secrets from
encrypted databags &lt;em&gt;only&lt;/em&gt; do that (they can implement their own
fallback through these mechanisms, but Chef doesn't offer any help).&lt;/p&gt;
&lt;p&gt;But wait, wrapper cookbooks!  You could write a wrapper to load your
secrets from your encrypted databag, override the appropriate node
attributes, then include the original recipe.  This works, but now
your secrets are recorded in node attributes and will be saved to the
Chef server in the clear.&lt;/p&gt;
&lt;p&gt;But wait, Chef handlers!  You could write a Chef handler to remove the
sensitive attributes from the node before it's saved!  Maybe - I forget
whether report handlers are actually called before the node is saved
at the run - and anyway, recipes can (and do) save the node at any
point.&lt;/p&gt;
&lt;p&gt;I guess you could monkey-patch &lt;code&gt;node.save&lt;/code&gt; (or something), but the
point is you're on your own.&lt;/p&gt;
&lt;h2&gt;3. Underdevelopment of the Recipe DSL&lt;/h2&gt;
&lt;p&gt;The &lt;a href="http://docs.opscode.com/chef/dsl_recipe.html"&gt;Recipe DSL&lt;/a&gt; hasn't
changed much in the last couple of years, barring the addition of
some helpers for Windows platforms.&lt;/p&gt;
&lt;p&gt;The most glaring example is the absence of a helper for Encrypted Data
Bags.  Here's how you'd load a regular, unencrypted databag:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;item = data_bag_item(&amp;#39;users&amp;#39;, &amp;#39;zts&amp;#39;)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Here's how you'd load the same databag if it was encrypted with the
default secret:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="n"&gt;item&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Chef&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;EncryptedDataBagItem&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;load&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;users&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;zts&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Alright, it's only a small thing - but it sticks out like a sore
thumb, and I know the glaring rubyism rubs some people up the wrong
way.  Seth Vargo's excellent
&lt;a href="https://github.com/sethvargo/chef-sugar"&gt;Chef Sugar&lt;/a&gt; gem provides a
load of enhancements to the recipe DSL (including an
&lt;code&gt;encrypted_data_bag_item&lt;/code&gt; method), many of which should be part of
core Chef.  Dumping &lt;em&gt;every&lt;/em&gt; last idea into the recipe DSL might be
worse than never adding anything at all, but the lack of love shown to
such a core part of the Chef user experience makes me sad.&lt;/p&gt;
&lt;h2&gt;4. No local storage&lt;/h2&gt;
&lt;p&gt;Why would I need local storage?  Loads of reasons.  A big one is that
I do a lot of work with &lt;code&gt;chef-solo&lt;/code&gt;, which can't save any state at all
(&lt;code&gt;chef-client -z&lt;/code&gt; might fix this for me, but it's not quite a drop-in
replacement).&lt;/p&gt;
&lt;p&gt;Still, node-local storage would be useful for chef-client too. One
application would be storage of secrets generated by Chef for services
it installs and manages (eg, a mysql service).  Another would be to
enable chef-client to detect when node attributes have been changed on
the server - or something like the
&lt;a href="http://dan.carley.co/blog/2012/10/01/unautomating-with-puppet/"&gt;immutable attributes&lt;/a&gt;,
Dan Carley prototyped for Puppet some time ago.&lt;/p&gt;
&lt;h2&gt;5. Two-Phase Runs and the Resource Queue&lt;/h2&gt;
&lt;p&gt;In principle, a Chef run has two phases.  In the first phase, recipes
are "compiled", a process which pushes resources into a queue.  In the
second phase, the compiled resources are "converged" one by one.  As
resources are queued in the order they're declared, the order of
actions is easy to predict.  This is simple, elegant, and - in
practice - a great big lie.&lt;/p&gt;
&lt;p&gt;Cracks first start to appear in the two-phase ideal when you want to
extend Chef - say, adding resources to manage mysql databases. To
manage mysql using Ruby, we'll want to install the mysql gem.  Before
we can do that, we will first need to install the mysql libraries and
a toolchain to compile the gem.  Chef can do all these things, but it
won't do any of them until it gets to the converge phase - and that
means, we won't be able to use our shiny new mysql resource until the
&lt;em&gt;next&lt;/em&gt; time we run Chef.&lt;/p&gt;
&lt;p&gt;Fortunately(?), it's possible to converge a specific resource during
the compile phase using &lt;code&gt;resource.run_action()&lt;/code&gt; and that's the go-to
solution to this problem.  That breaks the expectation that resources
will be converged in the order they're declared, but at least the
syntax makes it obvious - except in the case of &lt;code&gt;chef_gem&lt;/code&gt;, which does
converges in the compile phase without any visual indication in your
recipe.&lt;/p&gt;
&lt;p&gt;The upshot is that extending Chef with gems is a monumental pain.
Seth Vargo's post
&lt;a href="https://sethvargo.com/using-gems-with-chef/"&gt;"Using Gems With Chef"&lt;/a&gt;
post explores some more options.&lt;/p&gt;
&lt;p&gt;The waters are further muddied by LWRPs using
&lt;a href="http://docs.opscode.com/lwrp_common_inline_compile.html"&gt;inline compile mode&lt;/a&gt;.
This creates additional, disconnected run_contexts which are compiled
and converged when the LWRP is converged.  This makes LWRPs work
better, at the cost of obscuring the Chef resources they used to do
their thing - &lt;code&gt;run_context.resource_collection.all_resources&lt;/code&gt; won't
contain those nested resources.  (I suspect you can write a custom
event subscriber to collect this information for yourself.)&lt;/p&gt;
&lt;p&gt;Once again, I don't know what the solution looks like here (though I
believe people are talking about doing something for Chef 12).&lt;/p&gt;
&lt;h2&gt;What about you?&lt;/h2&gt;
&lt;p&gt;So, that's five things I hate about Chef.  I hope a few of you will be
motivated to share five things you hate about your favourite tool.
I'm not working in a large team at the moment, so I've mostly been
thinking about technical niggles - but I'd love to hear perspectives
on the human side of tool use, too.&lt;/p&gt;</content><category term="Blog"/><category term="chef"/></entry><entry><title>Gonzo: Increasing Agility by Understanding Risk</title><link href="https://www.cryptocracy.com/blog/2014/04/26/increasing-agility-by-understanding-risk/" rel="alternate"/><published>2014-04-26T12:45:00+01:00</published><updated>2014-04-26T12:45:00+01:00</updated><author><name>Zachary Stevens</name></author><id>tag:www.cryptocracy.com,2014-04-26:/blog/2014/04/26/increasing-agility-by-understanding-risk/</id><summary type="html">&lt;p&gt;Simon Croome's talk on increasing agility by understanding risk introduces Gonzo, a tool for identifying and reviewing pending changes across Puppet infrastructure.&lt;/p&gt;</summary><content type="html">&lt;p&gt;In my &lt;a href="/blog/2014/03/23/scale-summit-2014/"&gt;writeup of Scale Summit&lt;/a&gt;,
I referred to a talk that
&lt;a href="https://twitter.com/simoncroome"&gt;Simon Croome&lt;/a&gt; would be giving at
Puppet Camp London, and promised to link to it when it was online. The
slides and video are now online, so check out
&lt;a href="https://puppetlabs.com/presentations/puppet-camp-london-2014-increasing-agility-understanding-risk"&gt;"Increasing Agility by Understanding Risk"&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;The back half of the presentation introduces
&lt;a href="https://github.com/croomes/gonzo"&gt;Gonzo (github)&lt;/a&gt;, a tool Simon
wrote to identify and review pending changes in his Puppet manifests,
and it's this that piqued my interest at Scale Summit.&lt;/p&gt;
&lt;p&gt;Whether or not they're using a configuration management tool, "What
was changed?" is one of the first questions people ask when something
goes wrong. The desire to have prompt answers to that question is one
of the drivers behind change management processes, and Chef and Puppet
both offering reporting features to help with this.  If our only
desire was to respond more quickly when things went wrong, that would
be enough.&lt;/p&gt;
&lt;p&gt;However, "move fast and break things" notwithstanding, most businesses
would prefer to avoid incidents caused by planned changes.  This is
usually the primary motivation for introducing change control
processes, and involves (at the very least) identification of the
proposed changes, an assessment of the associated risk, and review of
these before deciding whether to proceed.&lt;/p&gt;
&lt;p&gt;Humans aren't great at assessing risk, particularly when making an
off-the-cuff assessment of something they're about to do.  As
sysadmins, we're often over-confident about changes we're going to
make by hand - after all, we're smart!  If something goes wrong in the
middle of the change, we'll notice it and react with our cat-like
reflexes.&lt;/p&gt;
&lt;p&gt;When moving to "fly-by-wire system administration" using tools like
Chef and Puppet, this attitude often shifts dramatically in the other
direction.  Misplaced confidence in our own control of the situation
is replaced by fear.  We admit that we aren't &lt;em&gt;really&lt;/em&gt; certain we
know what effect a change will have - and we're sure the system will
inflict any mistake at scale, without a second thought.&lt;sup id="fnref:1"&gt;&lt;a class="footnote-ref" href="#fn:1"&gt;1&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;Gonzo is the first tool I've seen that helps users of a modern
configuration management tool to identify and review pending changes
across their entire infrastructure.  Even in environments without
formal change control processes, this visibility can help to avoid
unexpected changes and improve confidence and comfort with the tools
being used.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://blog.afistfulofservers.net/post/2012/12/21/promises-lies-and-dryrun-mode/"&gt;No-op/why-run modes are necessarily imperfect&lt;/a&gt;,
but they're not worthless.  As a Chef user, Gonzo gives me another
reason to be jealous of Puppet and I hope its ideas make their way
into the Chef ecosystem before long.&lt;/p&gt;
&lt;div class="footnote"&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id="fn:1"&gt;
&lt;p&gt;The unthinking application of changes is itself a problem - we need &lt;a href="http://www.velaction.com/lean-jidoka-definition/"&gt;autonomation&lt;/a&gt;, not automation.  But that's a subject for another post.&amp;#160;&lt;a class="footnote-backref" href="#fnref:1" title="Jump back to footnote 1 in the text"&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;</content><category term="Blog"/><category term="devops"/></entry><entry><title>Scale Summit 2014</title><link href="https://www.cryptocracy.com/blog/2014/03/23/scale-summit-2014/" rel="alternate"/><published>2014-03-23T01:00:00+00:00</published><updated>2014-03-23T01:00:00+00:00</updated><author><name>Zachary Stevens</name></author><id>tag:www.cryptocracy.com,2014-03-23:/blog/2014/03/23/scale-summit-2014/</id><summary type="html">&lt;p&gt;Scale Summit was an unconference for people interested in web scalability, and while it was a really good event, there is room for improvement in introductions, scheduling, and session facilitation.&lt;/p&gt;</summary><content type="html">&lt;p&gt;So, &lt;a href="http://www.scalesummit.org"&gt;Scale Summit&lt;/a&gt; has now been and gone.
As the spiritual descendant of UK Scale Camp (which remains my
unconference benchmark) I'd been looking forward to this one since I
heard about it.  An
&lt;a href="http://en.wikipedia.org/wiki/Unconference"&gt;unconference&lt;/a&gt;, if you
haven't been to one, puts the content in the hands of the
participants.  The general idea is to gather a bunch of folks with a
shared interest, keep them fed and watered, and give them space to
talk.  On the day, participants propose topics to discuss, set a
schedule, then make it happen.&lt;/p&gt;
&lt;p&gt;As you might expect, this is a bit of a gamble - sometimes magic
happens, sometimes you get a damp squib.&lt;/p&gt;
&lt;h2&gt;What Was Good?&lt;/h2&gt;
&lt;p&gt;The venue was easy to get to, the catering was top notch, and wifi
worked everywhere (which was just as well, as cellphone reception was
abysmal).  I also appreciated the wifi having a single password for
all attendees.&lt;/p&gt;
&lt;p&gt;I liked that the
&lt;a href="http://www.chathamhouse.org/about-us/chathamhouserule"&gt;Chatham House&lt;/a&gt;
rule applied by default, and that a code of conduct was circulated
ahead of the event (and called out in the introduction).  For that
matter, communication ahead of the event did a good job explaining
what to expect.&lt;/p&gt;
&lt;p&gt;The event was about the right size (~130 people), if perhaps a little
too large.&lt;/p&gt;
&lt;h2&gt;What Could Improve?&lt;/h2&gt;
&lt;h3&gt;Introductions&lt;/h3&gt;
&lt;p&gt;After &lt;a href="https://twitter.com/bruntonspall"&gt;Michael Brunton-Spall's&lt;/a&gt;
welcomed everyone to the conference, a microphone was passed around
the room for everyone to introduce themselves in a "What's your name?
What do you want to learn? What are you good at?" format.  Despite
providing some moments of hilarity (eg, "I think I'm at the wrong
conference, I came to learn about scaling mountains.") this didn't
really work for me.&lt;/p&gt;
&lt;p&gt;One benefit of introductions (beyond their value as a basic
icebreaker) is to help foster conversations through the rest of the
day - if I say I'm good at Chef, and you say you're interested in
learning about Chef, perhaps we'll have a chat during the day. Perhaps
I was insufficiently caffeinated, but with so many people in
attendance (and poor visibility, as we remained seated for the
introductions), I didn't really manage to keep track of the folks I
thought I might like to speak to.&lt;/p&gt;
&lt;p&gt;I'm not sure how to improve this.  One idea might be to do the
introductions online ahead of the event - this would avoid putting
people on the spot, and foster opportunities for people to connect in
some way before they get into the room.&lt;/p&gt;
&lt;p&gt;Another thought is to ask people to come up and introduce themselves
on the morning, but only if they want to encourage other participants
to start conversations with them during the day.  This could be seen
as an odd perversion of mst's
&lt;a href="http://shadow.cat/blog/matt-s-trout/announcing-hallway-plusplus/"&gt;Hallway++&lt;/a&gt;
idea, and I haven't particularly thought it through.  Perhaps I really
just want to see Hallway++ spread to more conferences.&lt;/p&gt;
&lt;h3&gt;Topics and Scheduling&lt;/h3&gt;
&lt;p&gt;The session board filled up fairly quickly, it wasn't necessarily
clear what folks had in mind for the proposed sessions, and there
wasn't any useful way to have conversations about it (due to lack of
time, and lack of space around the board).  It didn't feel like the
schedule was a collaborative effort of the participants, so much as a
bunch of individuals throwing thoughts at a wall.&lt;/p&gt;
&lt;p&gt;Funnily enough, the introductions segment I've just complained about
was provides some input to the scheduling process - eg, if several
people mention AWS CloudFormation in their introductions, it's
probably a good topic to propose a session around.  (Several people
did, and apparently the "Cloud Orchestration" session was an
interesting one).  On the flip side, the
&lt;a href="http://www.scalesummit.org/schedule/"&gt;events schedule&lt;/a&gt; originally
gave half an hour to "Collaboration over the sessions grid for the
day", so it would seem the time spent on introductions came at the
expense of something more focused on producing a good schedule.&lt;/p&gt;
&lt;p&gt;At London DevOpsDays, the open spaces schedule was built in several
phases.  First, folks proposing topics got up and told the rest of the
participants what they had in mind.  Second, participants noted which
topics they were interested in.  Finally, topics were assigned to
rooms suitable for the level of interest.  I'm unfamiliar with other
approaches to solving this problem, though I daresay they exist.  This
is the area I'd most like to see improve for the next Scale Summit.&lt;/p&gt;
&lt;h3&gt;Room Sizes and Engagement&lt;/h3&gt;
&lt;p&gt;The available rooms were relatively large - 3 for 60 people and 2 for
30 people, although another small room (~8 people) was employed when
splinter groups decided to talk in the lobby.  This lead to some large
sessions with half a dozen people speaking and ~40 listening, which
didn't feel ideal.  Conversely, Scale Camp at the Guardian offices had
a greater number (I seem to recall) of much smaller rooms, and one big
one.  This resulted in serious overcrowding in many of the sessions,
which wasn't ideal either.&lt;/p&gt;
&lt;p&gt;I suspect that any arrangement of rooms will have some kind of
drawback (particularly for an unconference), so perhaps the answer is
a little more structure or facilitation of the sessions.  Michael did
suggest some techniques in the day's introduction, though I didn't
witness any of them being used.  I'd like to have heard from more
voices during the day - even if the majority have come to a session to
learn, they could still be asking questions or providing prompts for
the folks bringing the experience; conversely, if more folks would
like to participate, the structure of the session should facilitate
that.&lt;/p&gt;
&lt;h2&gt;Takeaways&lt;/h2&gt;
&lt;p&gt;&lt;a href="https://twitter.com/unixdaemon"&gt;Dean Wilson&lt;/a&gt; has previous tweeted
about using Ansible to provision AWS resources, but the lightbulb
hadn't turned on for me - I need to explore that idea as an
alternative to CloudFormation.&lt;/p&gt;
&lt;p&gt;On that note, I regret not joining the "Cloud Orchestration" session,
but it was scheduled against a session I proposed on the subject of
Scaling Config Management (testing, processes, teams, etc).  The
latter was well attended, so I hope people got some value out of it.
I think I could have done a better job of introducing it, but I'll
reflect on that another time.&lt;/p&gt;
&lt;p&gt;Another lightbulb moment came when Simon Croome gave me a sneak
preview of the work he'll be presenting at Puppet Camp London in his
session "Increasing Agility By Understanding Risk".  I'll be linking
to that as soon as it's online (and I plan to incorporate some of his
ideas in my Chef CD pipeline).&lt;/p&gt;
&lt;p&gt;I went into the day wanting some more suggestions for host monitoring
in elastic environments, or at least reassurance that
&lt;a href="http://sensuapp.org"&gt;Sensu&lt;/a&gt; was the best thing to play with.
Apparently it is.  A few folks who had spent a little time with
&lt;a href="http://riemann.io"&gt;Riemann&lt;/a&gt; were enthusiastic about it too, so that's
now higher up my list than it was at the start of the day.&lt;/p&gt;
&lt;p&gt;If you ever need to goad people into giving lightning talks,
&lt;a href="https://twitter.com/jonty"&gt;Jonty&lt;/a&gt; is remarkably effective at doing
so.&lt;/p&gt;
&lt;p&gt;Here's &lt;a href="http://mudge.name/2014/03/22/a-summit-for-scaling.html"&gt;three&lt;/a&gt;
&lt;a href="http://words.volant.is/articles/notes-scale-summit/"&gt;good&lt;/a&gt;
&lt;a href="https://gist.github.com/philandstuff/9684513"&gt;posts&lt;/a&gt; with far more
notes about the topics discussed.&lt;/p&gt;
&lt;h2&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;I really enjoyed the day, got plenty of value out of it, and I'm
already looking forward to the next one.  There's room for
improvement but (for me, at least) that could only elevate the day
from "really good" to "utterly awesome".&lt;/p&gt;
&lt;p&gt;Special thanks to organisers Jon Topper (and the rest of the crew at
&lt;a href="http://scalefactory.com/"&gt;The Scale Factory&lt;/a&gt;),
&lt;a href="http://twitter.com/bruntonspall"&gt;Michael Brunton-Spall&lt;/a&gt;, and
&lt;a href="http://www.linkedin.com/pub/sarah-hakewill/21/498/300"&gt;Sarah Hakewill&lt;/a&gt;,
and to &lt;a href="http://www.scalesummit.org"&gt;all the sponsors&lt;/a&gt; who helped keep
the price affordable.&lt;/p&gt;</content><category term="Blog"/><category term="devops"/></entry><entry><title>cfgmgmtcamp.eu 2014</title><link href="https://www.cryptocracy.com/blog/2014/02/11/cfgmgmtcamp-dot-eu-2014/" rel="alternate"/><published>2014-02-11T18:30:00+00:00</published><updated>2014-02-11T18:30:00+00:00</updated><author><name>Zachary Stevens</name></author><id>tag:www.cryptocracy.com,2014-02-11:/blog/2014/02/11/cfgmgmtcamp-dot-eu-2014/</id><summary type="html">&lt;p&gt;A recap of cfgmgmtcamp.eu, a two-day configuration management conference in Gent bringing together Puppet, Chef, CFEngine, Ansible, Saltstack, and Juju communities.&lt;/p&gt;</summary><content type="html">&lt;p&gt;Last week I went to Gent for &lt;a href="http://cfgmgmtcamp.eu"&gt;cfgmgmtcamp.eu&lt;/a&gt;,
a two day conference bringing together various config management
communities.  Around 300 people attended, representing (at least)
Puppet, Chef, CFEngine, Ansible, Saltstack, and Juju.  It was a great
conference, with loads of interesting talks (no video, unfortunately)
and a fantastic hallway track.&lt;/p&gt;
&lt;p&gt;There were a bunch of good sessions in the
&lt;a href="http://lanyrd.com/2014/cfgmgmtcamp/schedule/?spaces=ryqd"&gt;Chef community room&lt;/a&gt;,
and that (plus the hallway conversations) got in the way of spending
any time in the other community rooms.  I'm a little disappointed
about that, though I'm sure the same would be true if I'd missed out
on the Chef sessions.&lt;/p&gt;
&lt;p&gt;I presented a talk about
&lt;a href="http://www.slideshare.net/zts/using-mcollective-with-chef-cfgmgmtcampeu-2014"&gt;Orchestrating Chef with MCollective&lt;/a&gt;.
It's been a long time since I spoke, and I wasn't particularly happy
with how it went - this was the one session where I was glad to have
no video!  I personally learned a lot in the process, and would like
to give a few (shorter) talks this year to work on this skill.
Hopefully the folks who sat through it learned a thing or two as well.&lt;/p&gt;
&lt;p&gt;Common themes in presentations and discussion were continuous
delivery, testing (and TDD) for infracode, and orchestration.  In
&lt;a href="http://cfgmgmtcamp.eu/Chef/MichaelDucy.html"&gt;"Be More Pushy"&lt;/a&gt;,
Michael Ducy talked about Opscode's orchestration system, which I'm
looking forward to using.
&lt;a href="http://www.slideshare.net/ulfmansson/an-almost-complete-continuous-delivery-pipeline-including-configuration-management"&gt;Ulf Mansson&lt;/a&gt;
and
&lt;a href="http://www.slideshare.net/gmiranda23/cfg-mgmtcamp-cdwithchef"&gt;George Miranda&lt;/a&gt;
both talking about building continuous delivery pipelines, and
&lt;a href="http://cfgmgmtcamp.eu/Chef/AndrewCrump.html"&gt;Andrew Crump&lt;/a&gt; explained
how Foodcritic works (and how to extend it).&lt;/p&gt;
&lt;p&gt;There were no talks scheduled in the Chef room for the final few
hours, so this became a space for hacking and lightning talks.
Highlights were Andrew Crump showing me how to fix a couple of bugs in
Foodcritic, Adam Jacob demonstrating test-driven development, and a
lightning talk (I didn't catch the presenter's name, sorry) about community
cookbook governance, which spurred a much longer conversation on the
subject.&lt;/p&gt;
&lt;p&gt;I departed the conference wishing it had been longer, and looking
forward to the next one.  Now that I'm home, I'm wishing I had more
time to apply the various things I learnt while I was there.  All in
all, highly recommended.&lt;/p&gt;</content><category term="Blog"/><category term="devops"/><category term="chef"/></entry><entry><title>Cooking With Jenkins (and Test-Kitchen, and Docker)</title><link href="https://www.cryptocracy.com/blog/2014/01/03/cooking-with-jenkins-test-kitchen-and-docker/" rel="alternate"/><published>2014-01-03T01:00:00+00:00</published><updated>2014-01-03T01:00:00+00:00</updated><author><name>Zachary Stevens</name></author><id>tag:www.cryptocracy.com,2014-01-03:/blog/2014/01/03/cooking-with-jenkins-test-kitchen-and-docker/</id><summary type="html">&lt;p&gt;Using the 1.0 release of test-kitchen and kitchen-docker to run Chef cookbook tests with Jenkins, with a demo cookbook and Vagrantfile to help you get started.&lt;/p&gt;</summary><content type="html">&lt;p&gt;The recent 1.0 release of &lt;a href="http://kitchen.ci"&gt;test-kitchen&lt;/a&gt; (and the
existence of
&lt;a href="https://github.com/portertech/kitchen-docker"&gt;kitchen-docker&lt;/a&gt;) gave
me the push I needed to start using
&lt;a href="http://jenkins-ci.org"&gt;Jenkins&lt;/a&gt; to test my Chef cookbooks.  Although I've
heard plenty of people talk about doing this, I struggled to find
much in the way of guidance or detailed descriptions.&lt;/p&gt;
&lt;p&gt;Finding nothing to crib from, I decided to first build a &lt;a href="http://www.jamesshore.com/Agile-Book/spike_solutions.html"&gt;spike&lt;/a&gt; to
better understand what was involved.  The result is
&lt;a href="https://github.com/zts/cooking-with-jenkins"&gt;Cooking With Jenkins&lt;/a&gt;, a
cookbook and Vagrantfile that installs Docker and Jenkins, configured
to run tests on a few cookbooks.  If you're new to these tools, I hope
it will be a useful example to help you get started.  If you're
already using them, your suggestions for improvement will be rewarded
with thanks and beverages.&lt;/p&gt;
&lt;h2&gt;What's In The Box?&lt;/h2&gt;
&lt;p&gt;&lt;img alt="Jenkins Frontpage" src="/images/cooking-with-jenkins/cwj-front-after-3-builds.png"&gt;&lt;/p&gt;
&lt;p&gt;The base system is Ubuntu 13.04 (from a Bento box).  Jenkins and
Docker are installed via the &lt;code&gt;jenkins&lt;/code&gt; and &lt;code&gt;docker&lt;/code&gt; cookbooks, and
ruby1.9.3 comes from a system package.&lt;/p&gt;
&lt;p&gt;The cookbook installs and configures various Jenkins plugins
&lt;a href="https://github.com/zts/cooking-with-jenkins/blob/master/recipes/configure-jenkins.rb"&gt;A recipe&lt;/a&gt;
installs and configures various Jenkins plugins, including &lt;code&gt;git&lt;/code&gt;,
&lt;code&gt;warnings&lt;/code&gt; (to parse Foodcritic output), &lt;code&gt;ansicolor&lt;/code&gt; (to colourise
console output), and &lt;code&gt;config-file-provider&lt;/code&gt; (to add static files to
the job workspace before testing).&lt;/p&gt;
&lt;p&gt;A Chef definition wraps up the details of Jenkins job creation, and it
assumes that the cookbook repo provides a Gemfile and Rakefile similar
to those in
&lt;a href="https://github.com/mlafeldt/skeleton-cookbook.git"&gt;mlafeldt's skeleton-cookbook&lt;/a&gt;.
You can see the definition in use in
&lt;a href="https://github.com/zts/cooking-with-jenkins/blob/master/recipes/define-jenkins-jobs.rb"&gt;this recipe&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;Questions To Consider&lt;/h2&gt;
&lt;p&gt;You'll find a lot of questions when building a Jenkins system for
cookbook testing, and most have more than one right answer - you'll
need to consider the trade-offs, and choose what's best for you.&lt;/p&gt;
&lt;p&gt;The Jenkins server I'm building will only be used for testing a
private set of Chef cookbooks deployed in a homogeneous
environment.  This is as simple as it gets, so I've avoided some
complexity that might be essential in other environments.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;How should I install Ruby?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;If you need to test your cookbook with multiple rubies, you'll
probably want to use something like
&lt;a href="http://community.opscode.com/cookbooks/rbenv"&gt;rbenv&lt;/a&gt; or
&lt;a href="https://github.com/fnichol/chef-rvm"&gt;rvm&lt;/a&gt;.  I only need to worry
about 1.9, which I installed with a system package.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Where should I install gems?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;The tools we'll use to test our cookbooks are packaged as gems, and
they need to be installed somewhere before we can use them.  The
generally recommended option is to include
&lt;a href="https://github.com/zts/chef-cookbook-managed_directory/blob/master/Gemfile"&gt;a Gemfile&lt;/a&gt;
in each of our cookbooks, and use &lt;a href="http://bundler.io"&gt;Bundler&lt;/a&gt; to
install a local copy of the gems for each Jenkins job.  Another option
is to install all the tools once, in your system gem location.&lt;/p&gt;
&lt;p&gt;If you use system gems, you'll save some time and disk space (they
only need to be installed once), and you won't have to manage a
Gemfile in each of your cookbook repositories.  On the other hand, you
can't use different gems (or versions) on a case-by-case basis.&lt;/p&gt;
&lt;p&gt;Using Bundler means more boilerplate in your cookbook repositories,
but it has the advantage of being explicit about your requirements.
This makes life easier for other people developing your cookbooks, and
it's absolutely essential if you'll also be testing them on something
like &lt;a href="https://travis-ci.org"&gt;Travis CI&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Where should I define the test commands?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;When we define jobs in Jenkins to test our cookbooks, we'll need to
specify the commands used to run the tests.  An obvious approach is to
use the command-line tools (eg, foodcritic) directly, but many people
wrap the tasks up in a Rakefile and call everything through rake.&lt;/p&gt;
&lt;p&gt;The main advantage of using the tools directly is that you don't need
to maintain a (possibly identical) Rakefile in each of your cookbook
repositories.  On the other hand, you'll still want to run tests in
your development environment, and a good Rakefile saves you from
remembering the precise options you need for each command.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;How should I map cookbook tests to Jenkins jobs?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;A Jenkins "job" involves a workspace (a directory containing the
revision of code you're testing), one or more build commands (for us,
that's test commands), and zero or more actions to run following the
build.  Jenkins also supports chaining jobs, so that one job finishing
schedules a second job.  This allows you to build pipelines of
activities, contingent on the success or failure of earlier jobs.
Various plugins exist to extend the core functionality, such as the
&lt;a href="https://wiki.jenkins-ci.org/display/JENKINS/Build+Pipeline+Plugin"&gt;Build Pipeline Plugin&lt;/a&gt;
and the
&lt;a href="https://wiki.jenkins-ci.org/display/JENKINS/Multijob+Plugin"&gt;Multijob Plugin&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;That's a lot of complexity, which I opted to ignore by creating a
single job (for each cookbook) that runs all of the required tests.  I
will certainly revisit this in the next iteration.&lt;/p&gt;
&lt;h2&gt;Installation Instructions&lt;/h2&gt;
&lt;p&gt;The Vagrantfile specifies a
&lt;a href="https://github.com/opscode/bento"&gt;"Bento"&lt;/a&gt; basebox, which doesn't
include a provisioner - so you'll need the "vagrant-omnibus" plugin
installed if you want to try it out.  It should work fine under
Virtualbox, but I've been using VMware as it seems to cope better
under load.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;git clone https://github.com/zts/cooking-with-jenkins
cd cooking-with-jenkins
vagrant up
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;When Vagrant finishes provisioning the machine, Jenkins will be
available on &lt;a href="http://localhost:8080/"&gt;http://localhost:8080/&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Known Issue:&lt;/em&gt; The machine creates test jobs for three cookbooks, and
the first test run for each (during provisioning) fails, so when you
first load Jenkins you'll see something like
&lt;a href="/images/cooking-with-jenkins/cwj-front-after-provision.png"&gt;this&lt;/a&gt;.  I
suspect this would be fixed by restarting Jenkins after adding plugins
(the "configure-jenkins" recipe) and before defining the jobs, but it
didn't bother me enough to add the necessary hackery.&lt;/p&gt;
&lt;p&gt;Click "Build Now" on each job and you'll see them work correctly.&lt;/p&gt;
&lt;h2&gt;What Does It Look Like?&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Cookbook overview&lt;/strong&gt;
&lt;img alt="job summary page for a test cookbook" src="/images/cooking-with-jenkins/cwj-cookbook-test-summary.png"&gt;
As this cookbook has a single foodcritic warning, and a single "pending"
chefspec test, the graphs are uninteresting yellow rectangles.
Clicking the Foodcritic link on the left takes you to...&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Foodcritic report&lt;/strong&gt;
&lt;img alt="sample foodcritic report" src="/images/cooking-with-jenkins/cwj-foodcritic-report.png"&gt;
Again, this would look more interesting if a bunch of problems were
being reported, instead of just one example.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Colourised job console output&lt;/strong&gt;
&lt;img alt="sample test-kitchen output" src="/images/cooking-with-jenkins/cwj-kitchen-console-output.png"&gt;
This shows the bottom of the console output for a job that ran
test-kitchen.  It's not the easiest on the eyes, but I think it's
better than raw ANSI colour codes in your browser.  Also, note that
the time to test this (admittedly simple) kitchen instance was just
under 43 seconds.  Test Kitchen with kitchen-docker is awesome.&lt;/p&gt;
&lt;h2&gt;What's Missing? What's Next?&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;In this demo, you always need to click "Build Now" to run tests for
   a cookbook - Jenkins doesn't even poll github to see if the repo has
   changed.  A better solution would be to use commit hooks to notify
   the Jenkins API that a new revision is available for testing.&lt;/li&gt;
&lt;li&gt;test-kitchen instances are currently tested sequentially, but using
   docker lowers the overhead enough that a few could be run in parallel.&lt;/li&gt;
&lt;li&gt;Nothing happens after the tests pass.  I plan to add another step
   that uses Berkshelf to publish the cookbook to a Chef server.
   Tagging the git repository might also be a nice touch.&lt;/li&gt;
&lt;li&gt;Instead of running all the tests in a single job, a more
   sophisticated pipeline would first run ruby/erb syntax checks, then
   foodcritic and chefspec in parallel, then test-kitchen if both of
   those passed, before finally uploading the cookbook using Berkshelf.&lt;/li&gt;
&lt;li&gt;When test-kitchen fails, you'll need to look at the console output
   to see why - it can't currently export test results the way that
   chefspec can.  Keep an eye on
   &lt;a href="https://github.com/test-kitchen/test-kitchen/pull/130"&gt;this pull request&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;For my use case (running identical tests for internal cookbooks),
   I'm not convinced about maintaing a Gemfile+Rakefile in each
   cookbook.  This feels like a violation of the
   &lt;a href="http://c2.com/cgi/wiki?DontRepeatYourself"&gt;DRY principle&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Other References&lt;/h2&gt;
&lt;p&gt;Although I didn't really find anything offering a detailed, end-to-end
walk through setting up Jenkins for cookbook testing, I did find some
clues in these posts:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;http://blog.bscott.me/2012/12/08/Chef-Testing-Part-2.html&lt;/li&gt;
&lt;li&gt;http://blog.safariflow.com/2013/06/26/continuous-integration-for-chef-with-vagrant-jenkins-and-gitlab/&lt;/li&gt;
&lt;li&gt;http://jtimberman.housepub.org/blog/2013/05/08/test-kitchen-and-jenkins&lt;/li&gt;
&lt;/ul&gt;</content><category term="Blog"/><category term="chef"/></entry><entry><title>Vagrant, VMware, and Berkshelf</title><link href="https://www.cryptocracy.com/blog/2013/12/27/vagrant-vmware-and-berkshelf/" rel="alternate"/><published>2013-12-27T16:00:00+00:00</published><updated>2013-12-27T16:00:00+00:00</updated><author><name>Zachary Stevens</name></author><id>tag:www.cryptocracy.com,2013-12-27:/blog/2013/12/27/vagrant-vmware-and-berkshelf/</id><summary type="html">&lt;p&gt;Debugging a shared folder issue when using Vagrant with the VMware provider and Berkshelf, where the cookbook directory disappears after reprovisioning.&lt;/p&gt;</summary><content type="html">&lt;p&gt;So, &lt;a href="http://www.vagrantup.com"&gt;Vagrant&lt;/a&gt; is a great tool, which costs
you nothing to use if you pair it with Virtualbox.  Unfortunately,
Virtualbox is somewhat less awesome in heavy use. VMware does a better
job of things, and Vagrant added support for it with a paid-for
plugin.  As the first commercial product of Hashicorp (Vagrant's
developer), this is a nice way to say thankyou for Vagrant while
getting a better user experience too.&lt;/p&gt;
&lt;p&gt;In theory.&lt;/p&gt;
&lt;p&gt;While Vagrant generally does a great job of hiding the differences
between the various "providers" (virtualisation systems) it supports,
some still leak through.  I ran into the following problem when
running "vagrant provision" to re-run Chef in the guest system after
making some changes:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;default&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Running&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;provisioner&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;chef_solo&lt;/span&gt;&lt;span class="p"&gt;...&lt;/span&gt;
&lt;span class="n"&gt;Shared&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;folders&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;that&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Chef&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;requires&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;are&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;missing&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;on&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;the&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;virtual&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;machine&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;
&lt;span class="n"&gt;This&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;is&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;usually&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;due&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;to&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;configuration&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;changing&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;after&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;already&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;booting&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;the&lt;/span&gt;
&lt;span class="n"&gt;machine&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;The&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;fix&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;is&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;to&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;run&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;`&lt;/span&gt;&lt;span class="n"&gt;vagrant&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;reload&lt;/span&gt;&lt;span class="err"&gt;`&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;so&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;that&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;the&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;proper&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;shared&lt;/span&gt;
&lt;span class="n"&gt;folders&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;will&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;be&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;prepared&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ow"&gt;and&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;mounted&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;on&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;the&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;VM&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Contrary to the message, &lt;code&gt;vagrant reload&lt;/code&gt; didn't help.&lt;sup id="fnref:1"&gt;&lt;a class="footnote-ref" href="#fn:1"&gt;1&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;When I looked at the guest system, I found that the directory that
should have contained my Chef cookbooks (managed by Berkshelf) no
longer appeared - the mountpoint was still listed, but it no longer
worked.  Eventually, that lead me to
&lt;a href="https://github.com/berkshelf/vagrant-berkshelf/issues/88"&gt;issue #88&lt;/a&gt;
on the vagrant-berkshelf repo, which explains the cause - that
directory is deleted and recreated on every run, which breaks the
"vmware" and "nfs" methods of sharing folders under Vagrant.&lt;/p&gt;
&lt;p&gt;In lieu of a proper fix, I bodged one together that relies on rsync
being available on your path. If you're
having the same problem and want to give it a try, check out
&lt;a href="https://github.com/zts/vagrant-berkshelf/commit/cb27afb4d95a1d56a87a9777814716e36650265e"&gt;this branch on github&lt;/a&gt;.&lt;/p&gt;
&lt;div class="footnote"&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id="fn:1"&gt;
&lt;p&gt;It turns out that this would have worked on Vagrant releases prior to 1.3.0.  After that, &lt;code&gt;vagrant reload --provision&lt;/code&gt; would have worked.  In both cases, this workaround is very slow as it restarts the VM.&amp;#160;&lt;a class="footnote-backref" href="#fnref:1" title="Jump back to footnote 1 in the text"&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;</content><category term="Blog"/><category term="misc"/><category term="chef"/></entry><entry><title>Dick Jokes and DevOps, Redux</title><link href="https://www.cryptocracy.com/blog/2013/12/02/dick-jokes-and-devops-redux/" rel="alternate"/><published>2013-12-02T11:25:00+00:00</published><updated>2013-12-02T11:25:00+00:00</updated><author><name>Zachary Stevens</name></author><id>tag:www.cryptocracy.com,2013-12-02:/blog/2013/12/02/dick-jokes-and-devops-redux/</id><summary type="html">&lt;p&gt;A follow-up revisiting the original "Dick Jokes and DevOps" post, correcting its gender-focused framing and presenting gender-neutral reasons why off-topic crude humor doesn't belong in professional discussions.&lt;/p&gt;</summary><content type="html">&lt;p&gt;Last week, I wrote
&lt;a href="http://www.cryptocracy.com/blog/2013/11/23/dick-jokes-and-devops/"&gt;"Dick Jokes and DevOps"&lt;/a&gt;
after someone was called out for making a dick joke on a devops
mailing list.  Although the reaction was largely positive, some valid
criticisms highlighted flaws in the piece that I hope to correct in
revisiting the topic.&lt;/p&gt;
&lt;p&gt;The first suggestion that I may have done something wrong was a
comment on Twitter:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;I really think THAT is sexist. "we must protect the delicate womens!"&lt;/p&gt;
&lt;p&gt;— @amyhoy, &lt;a href="https://twitter.com/amyhoy/status/404270049332322304"&gt;https://twitter.com/amyhoy/status/404270049332322304&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;She wasn't alone.  Comments from others (male and female) complained
that "crude" was being equated with "sexist", and that it shouldn't be
assumed that all dick jokes were offensive to all women.&lt;/p&gt;
&lt;p&gt;I felt a bit bad about this, as it wasn't where I was coming from when
I wrote the post.  Nonetheless, you see what I wrote, not what I was
thinking when I did it, so I figured the problem must be somewhere on
the page.  Sure enough, when I re-read it with that interpretation in
mind, I saw that I did draw the issue along gender lines - fairly
explicitly at the top of the post, still implicitly towards the end.
Mea culpa.&lt;/p&gt;
&lt;p&gt;Another criticism concerned my choice not to link to the original
mailing list thread.  While that choice was motivated by a desire to
avoid reviving a thread that had run its course, the comments it
provoked were interesting.  People were unhappy that they couldn't
look at the joke and make their own judgement about whether or not it
was offensive.&lt;/p&gt;
&lt;p&gt;Maybe it's a stretch, but I see a certain symmetry in these two
criticisms.  The first group was concerned that I was judging what
they would be offended by, while the second group was concerned that I
was denying them the power to judge what other people should be
offended by.  I'll blame my framing for both these concerns, and hope
that this restatement brings a few more people on-side.&lt;/p&gt;
&lt;h2&gt;It's Not A Gender Thing&lt;/h2&gt;
&lt;p&gt;I don't think that all women want or need to be protected from seeing
dick jokes.  Beyond fundamental biological needs, like eating and
breathing, I don't think there's much that is true of &lt;em&gt;all&lt;/em&gt; women, or
&lt;em&gt;all&lt;/em&gt; men, or &lt;em&gt;all&lt;/em&gt; people.&lt;/p&gt;
&lt;p&gt;I know women who are comfortable hearing and making obscene jokes
anywhere, any time.  I know men who feel the same way.&lt;/p&gt;
&lt;p&gt;I know men who are uncomfortable hearing crude jokes anywhere, any
time.  I know women who feel the same way.&lt;/p&gt;
&lt;p&gt;I know people of all stripes who are comfortable discussing some
things in a close group of friends, but uncomfortable having the exact
same discussions in other contexts.&lt;/p&gt;
&lt;p&gt;To the best of my knowledge, none of these positions has any bearing
upon one's ability to operate a computer.&lt;/p&gt;
&lt;h2&gt;It's Not About Protecting Another Group&lt;/h2&gt;
&lt;p&gt;Everyone gets to own their own offence - it's condescending and
disempowering to behave as though they need you to step in on their
behalf.  Beyond that, if they weren't actually offended in the first
place you will have created a problem where none existed.  Don't be
offended for somebody else.&lt;/p&gt;
&lt;p&gt;I opened the original post by describing the dick joke as "pretty
benign".  Doesn't that mean I was being offended on behalf of some
unidentified others?&lt;/p&gt;
&lt;p&gt;No.&lt;/p&gt;
&lt;p&gt;Although I wasn't offended by the content of the joke, I was offended
by the context - making the joke on a professional mailing list of
nearly 800 people who have come together "to discuss technology,
process and enabling harmonious DevOps."&lt;sup id="fnref:1"&gt;&lt;a class="footnote-ref" href="#fn:1"&gt;1&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;h2&gt;A Gender-Neutral Frame&lt;/h2&gt;
&lt;p&gt;Here's two gender-neutral reasons why dick jokes have no place in a
devops discussion:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;1) They're off-topic&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Dick jokes are not intrinsic to building or maintaining software,
infrastructures, or teams.  This is not a value judgement, and it says
nothing about whether dick jokes are good, bad, or otherwise.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;2) They alienate part of the audience&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Some people on the list don't appreciate dick jokes.  There are a
range of reasons for this, none of which should matter to you.  They
joined the list to discuss devops - you did, too.  The barrier to
participation should be no higher than a desire to talk about that
topic, and enabling the discussion is the most important thing we can
do.&lt;/p&gt;
&lt;p&gt;That's it.&lt;/p&gt;
&lt;p&gt;Note that people who love dick jokes are just as welcome in the
discussion as people who loathe them, and people without a strong
opinion either way.  When you leave the dick jokes out of the
conversation, nobody needs to know or care where you stand.&lt;/p&gt;
&lt;h2&gt;Tell Me I'm Wrong&lt;/h2&gt;
&lt;p&gt;Telling dick jokes doesn't make you sexist, but &lt;em&gt;insisting&lt;/em&gt; on your
right to tell dick jokes when you know they're alienating your
audience is the act of an asshole.  Don't act like an asshole.  You're
better than that.&lt;/p&gt;
&lt;p&gt;I struggle to see why this issue is contentious, and yet it seems to
be.  If you think I'm wrong, I will appreciate your good-faith effort
to explain why.&lt;/p&gt;
&lt;div class="footnote"&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id="fn:1"&gt;
&lt;p&gt;https://groups.google.com/forum/#!aboutgroup/devops&amp;#160;&lt;a class="footnote-backref" href="#fnref:1" title="Jump back to footnote 1 in the text"&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;</content><category term="Blog"/><category term="devops"/></entry><entry><title>Premature Publication, and Other Problems</title><link href="https://www.cryptocracy.com/blog/2013/11/28/premature-publication-and-other-problems/" rel="alternate"/><published>2013-11-28T10:45:00+00:00</published><updated>2013-11-28T10:45:00+00:00</updated><author><name>Zachary Stevens</name></author><id>tag:www.cryptocracy.com,2013-11-28:/blog/2013/11/28/premature-publication-and-other-problems/</id><summary type="html">&lt;p&gt;A reflection on the fear of publishing imperfect work, the struggle between perfectionism and procrastination, and a lesson learned about soliciting feedback before hitting publish.&lt;/p&gt;</summary><content type="html">&lt;blockquote&gt;
&lt;p&gt;It happened some time during primary school, I'm not sure exactly
when.  I was old enough to be given homework, but not so old that
failing to do it had real consequences.  I was already a bit of a
goody two-shoes, and getting good marks was pretty important to me.&lt;/p&gt;
&lt;p&gt;So, I'd been given some homework, and I got into trouble for not doing
it.  The truth was that I had done it, but I didn't think I'd done it
very well - so I lied, and said I hadn't done it at all.  I figured it
was better to look like I hadn't even tried, than to have given it a
good shot and come up short.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;I shared that anecdote with a few people over drinks at DevOpsDays,
the outward expression of a train of thought concerning my failure to
blog.  It even occurred to me as a neat framing device for a post
reflecting on that failure, considered as part of an ongoing struggle
with perfectionism.  Neat, but disingenuous.&lt;/p&gt;
&lt;p&gt;Over the years, I've produced unexceptional work for various reasons -
sometimes I've been focussed on some other subject, other times I just
haven't been particularly interested in the task at hand.  When
neither of those has played a part, procrastination has often been to
blame.  When facing a deadline, pedestrian effort in hand, you can
choose between turning in something that may reflect badly on you,
or turning in nothing (that definitely will).  Both perfectionism and
procrastination are counterproductive traits, and their battle for my
mind has brought about a grudging acceptance of adequacy.&lt;/p&gt;
&lt;p&gt;The real reason I fail to publish is not that I'm striving for
excellence, but simply that I fear embarrassing myself.  Without
deadlines, or anyone calling me to account, the easiest way to avoid
embarrassing myself through my writing is not to do any.  Sometimes,
I'll write 90% of an article before deciding the whole idea was
stupid, other times it's no more than an outline.  I've thrown out
some drafts for failing to address every possible objection, and
others for saying too much.&lt;/p&gt;
&lt;p&gt;So, I decided that I needed to tackle this by making a conscious
effort to publish things that I thought might be a little flawed - a
vague sense that I &lt;em&gt;might&lt;/em&gt; do better wouldn't be reason enough to hold
back.  That seemed like a fair compromise.  I'll generally have mulled
an idea over a little before I start writing, and I've never been able
to resist editing and reworking as I go.  After getting the whole idea
out, and re-reading it a couple of times, I'll generally know whether
I'm uncomfortable with the way I've presented, or with the idea of
sharing it.  Release early, release often!  It's easy to
write a follow-up if you need to.&lt;/p&gt;
&lt;p&gt;You might recognise this as a false dichotomy.  While "publish
prematurely" is an improvement over "publish never", they are not the
only strategies I could have adopted.&lt;/p&gt;
&lt;p&gt;I'm not particularly ashamed of my last post, but it has some serious
flaws.  The conclusion is fine (and is the idea I wanted to share),
but the build up to it was a bit sloppy - indeed, it could have
supported a different argument entirely.  This invited some readers to
miss the point I was trying to make - and that's my fault, not theirs.
The first few comments I read were enough to show me what I'd done
wrong, and I started outlining a follow-up.  Around that time, Matt S
Trout saw the original and immediately pointed out every issue I'd
belatedly noticed.  I'd have saved a lot of time (and a little
personal embarrassment) if I'd asked for some other people to review
it in the first place.&lt;/p&gt;
&lt;p&gt;So, lesson learned.  In future, I'll be soliciting feedback before
publishing material that could be misunderstood, or risks preaching to
the client.  Although my honest motivation will be to avoid looking
stupid in public, I expect this will also help me to communicate more
effectively.  Seems like a win-win to me.&lt;/p&gt;</content><category term="Blog"/></entry><entry><title>Dick Jokes and DevOps</title><link href="https://www.cryptocracy.com/blog/2013/11/23/dick-jokes-and-devops/" rel="alternate"/><published>2013-11-23T15:00:00+00:00</published><updated>2013-11-23T15:00:00+00:00</updated><author><name>Zachary Stevens</name></author><id>tag:www.cryptocracy.com,2013-11-23:/blog/2013/11/23/dick-jokes-and-devops/</id><summary type="html">&lt;p&gt;After someone made a dick joke on a devops mailing list, a discussion about inclusivity and professionalism in the DevOps community ensued. Here's why it matters.&lt;/p&gt;</summary><content type="html">&lt;p&gt;&lt;strong&gt;Update:&lt;/strong&gt; This post has flaws that are addressed in &lt;a href="http://www.cryptocracy.com/blog/2013/12/02/dick-jokes-and-devops-redux/"&gt;a follow-up article&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;So, someone made a dick joke on a devops mailing list.&lt;sup id="fnref:1"&gt;&lt;a class="footnote-ref" href="#fn:1"&gt;1&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;It was pretty benign, as such things go - an allusion to penis
enlargement in the context of a discussion about managing spam.  I'd
have made the same joke in a group of friends, though perhaps not in
front of my mother.  Certainly not in front of a nun, or on a global
mailing list largely populated by people who I do not know, and who do
not know me.&lt;/p&gt;
&lt;p&gt;Mark Imbriaco politely called this out with a reply that could be gold
standard for such things:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;I just wanted to point out that your dick joke, which
I'm quite certain isn't intended to be malicious in any way, doesn't
do anything whatsoever to help the gender diversity problem that we
have in technology, and most especially in technical operations.&lt;/p&gt;
&lt;p&gt;I've been guilty of making jokes like that in the past myself, so I
understand that they don't come from a desire to exclude anyone from
the group. That said, the only way we make things better is by being
aware that they &lt;u&gt;do&lt;/u&gt; result in making some people feel
excluded. And the only way we improve the situation is by eliminating
that kind of thing from our discourse. And by having our friends
remind us when we miss the mark, as I'm quite certain I will in the
future.&lt;/p&gt;
&lt;p&gt;— Mark Imbriaco&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Note that Mark explained why the comment was bad without accusing the
author of being bad.  Conscious malice isn't required to say something
exclusionary - thoughtlessness is often enough.&lt;/p&gt;
&lt;p&gt;Matt Trout's advice shares the same spirit, while being somewhat more
direct:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;"Tell them they sound like an asshole. Don't accuse them of
being one, because your enemy never believes he's an evil man. Just
tell them they sound like one."&lt;/p&gt;
&lt;p&gt;— Matt S Trout, &lt;a href="http://shadow.cat/blog/matt-s-trout/on-being-part-of-the-solution/"&gt;On Being Part Of The Solution&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;In a perfect world, the joke's author would have responded
&lt;a href="https://twitter.com/jacobian/status/402635743777939456/photo/1"&gt;the way Anil Dash did&lt;/a&gt;
when he was recently called out on Twitter.  In our actual world, he
instead replied thus:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;"Yeah, I'm not really into subjecting myself to your morality."&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Alas.&lt;/p&gt;
&lt;h2&gt;Discussion Ensues&lt;/h2&gt;
&lt;p&gt;When a predominantly male mailing list dives into this kind of
discussion, its membership can appear to separate into three groups.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;1) "Help! Help! I'm being repressed!"&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;This group doesn't see anything wrong with whatever was said, and
therefore nobody else should either.  &lt;em&gt;"The world is a cruel and
unforgiving place, and delicate flowers need to toughen up a little.
Anyway, this is censorship, and censorship is evil."&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;2) "How can you think this is appropriate?"&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;This group might not have been personally offended by the comment, but
they don't believe it has any place on the list.  Maybe the wider
world is cruel and unforgiving, but that doesn't mean we have to be.
&lt;em&gt;"Be the change you wish to see in the world."&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;3) "Not another one of these threads.  Can't we just get back on topic?"&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Some in this group think the comment shouldn't have been made, others
think it was no big deal, and the rest don't particularly care either
way.  They might feel that the discussion is uncomfortable, or just
plain tedious, but wholly off-topic either way.  &lt;em&gt;"You've all shared
your opinions, now shut up and let's move on."&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;While the third group aren't actively causing the problem, they're
certainly not part of the solution.  They also offer a small
illustration of privilege: if you can feel just as comfortable
ignoring the problem as fixing it, you're probably part of the
privileged group.&lt;/p&gt;
&lt;p&gt;Despite actively contributing to the problem, folks in the first group
often don't see any misogyny in their position.  &lt;em&gt;"I don't hate women.
I'd say the same things to my female friends, and they wouldn't have a
problem with it."&lt;/em&gt; Perhaps that's fair.  I don't know whether dick
jokes are inherently misogynistic, but I do know that this line of
reasoning entirely misses the point.&lt;/p&gt;
&lt;h2&gt;The Point&lt;/h2&gt;
&lt;p&gt;The DevOps movement is inclusive.  It recognises that we suffer in our
own lives when we scorn the people whose professional choices differ
from our own, and that we benefit from putting a little effort into
getting along.&lt;/p&gt;
&lt;p&gt;If you can build bridges with someone working in a different job, how
can you insist that people with a different gender (or sexual
preference, or skin colour, or religion) are the ones who need to
change if we are going work together?  Those personal attributes are
far less relevant than the job they do.  If they are impediments to
someone's involvement in a professional group, the group has made it
so.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;"tl;dr - Don't do it, not because you are being censored, but because
it makes part of your audience uncomfortable, and if your job is
getting people on the same page, that's pretty much the worst thing
you can do."&lt;/p&gt;
&lt;p&gt;— Eric Shamow&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Be mindful of your audience, try not to exclude anyone, and listen
when someone suggests you've slipped up.  If you see someone slip up,
let them know that their comment falls short of the aspirations of the
DevOps movement.&lt;/p&gt;
&lt;p&gt;It isn't asking much, and we all benefit from the inclusive community
that results.&lt;/p&gt;
&lt;div class="footnote"&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id="fn:1"&gt;
&lt;p&gt;I haven't linked to it, because I don't think giving it more publicity is going to help anything.  Am I wrong?  Let me know.&amp;#160;&lt;a class="footnote-backref" href="#fnref:1" title="Jump back to footnote 1 in the text"&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;</content><category term="Blog"/><category term="devops"/></entry><entry><title>Errata for Test-Driven Infrastructure with Chef (2nd Ed)</title><link href="https://www.cryptocracy.com/blog/2013/11/18/errata-for-tdiwc2e/" rel="alternate"/><published>2013-11-18T21:30:00+00:00</published><updated>2013-11-18T21:30:00+00:00</updated><author><name>Zachary Stevens</name></author><id>tag:www.cryptocracy.com,2013-11-18:/blog/2013/11/18/errata-for-tdiwc2e/</id><summary type="html">&lt;p&gt;Notes on workarounds for issues in Test-Driven Infrastructure with Chef (2nd Edition), caused by Test Kitchen not yet having a 1.0 release at time of writing.&lt;/p&gt;</summary><content type="html">&lt;p&gt;&lt;strong&gt;Update:&lt;/strong&gt; I'm very happy to update this post to note that Test
Kitchen 1.0 has been released.  See the announcement on
&lt;a href="http://www.opscode.com/blog/2013/12/03/announcing-the-release-of-test-kitchen-1-0-0/"&gt;the Opscode blog&lt;/a&gt;,
and check out the &lt;a href="http://kitchen.ci/"&gt;KitchenCI home page&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;A couple of years ago,
&lt;a href="https://twitter.com/LordCope"&gt;Stephen Nelson-Smith&lt;/a&gt; wrote a little
book called
&lt;a href="http://shop.oreilly.com/product/0636920030973.do"&gt;Test-Driven Infrastructure with Chef&lt;/a&gt;.
Somewhat ahead of its time, it gave a brief introduction to the idea of
outside-in, test-driven development, in the context of infrastructure
code.  Since then, the rest of the world has started to catch up, and
a variety of tools and community practices have grown up around the
idea.&lt;/p&gt;
&lt;p&gt;Last month, the greatly revised and expanded second edition of the
book was released.  I mean to write a full review when I've spent some
more time with the book, but here's the short version: if you use
Chef, buy it.&lt;/p&gt;
&lt;p&gt;That having been said, nothing in life is perfect, and that's true
here.  The book optimistically assumes that Opscode (or whoever) would
have managed to make a 1.0 release of
&lt;a href="http://www.opscode.com/blog/2012/08/17/announcing-test-kitchen/"&gt;Test-Kitchen&lt;/a&gt;
by now.  They haven't, so you'll currently have issues following some of
the instructions when the recommended toolchain is introduced in
Chapter 7.&lt;/p&gt;
&lt;h2&gt;Berkshelf and Test Kitchen Installation&lt;/h2&gt;
&lt;p&gt;The book assumes that Berkshelf (installed with &lt;code&gt;gem install
berkshelf&lt;/code&gt;) will also install the test-kitchen gem.  As of Berkshelf
2.0.10, that's not the case - and if you don't install it yourself,
Berkshelf won't generate the Gemfile you'll see next.&lt;/p&gt;
&lt;p&gt;You can fix this by installing test-kitchen yourself, but be warned -
if you just run &lt;code&gt;gem install test-kitchen&lt;/code&gt;, you'll get a prehistoric
version.  You can tell gem to install the latest pre-release version
by running &lt;code&gt;gem install test-kitchen --pre&lt;/code&gt;.  This won't be required
after the final 1.0 release is made.&lt;/p&gt;
&lt;h2&gt;Berkshelf - Gemfile&lt;/h2&gt;
&lt;p&gt;The book looks at the Gemfile created by &lt;code&gt;berks init&lt;/code&gt;, which adds
dependencies on test-kitchen and kitchen-vagrant.  If you follow the
output's instructions to run &lt;code&gt;bundle install&lt;/code&gt;, you'll get a failure:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nv"&gt;Bundler&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;could&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;not&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;find&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;compatible&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;versions&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;gem&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;test-kitchen&amp;quot;&lt;/span&gt;:
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="nv"&gt;In&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;Gemfile&lt;/span&gt;:
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="nv"&gt;kitchen&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nv"&gt;vagrant&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ss"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="ss"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;ruby&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;depends&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;on&lt;/span&gt;
&lt;span class="w"&gt;          &lt;/span&gt;&lt;span class="nv"&gt;test&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nv"&gt;kitchen&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ss"&gt;(&lt;/span&gt;&lt;span class="o"&gt;~&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;.&lt;span class="mi"&gt;0&lt;/span&gt;.&lt;span class="mi"&gt;0&lt;/span&gt;.&lt;span class="nv"&gt;alpha&lt;/span&gt;.&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="ss"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;ruby&lt;/span&gt;

&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="nv"&gt;test&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nv"&gt;kitchen&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ss"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;.&lt;span class="mi"&gt;5&lt;/span&gt;.&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="ss"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Again, this won't be a problem after test-kitchen gets a a 1.0
release.  Today, you'll need to manually update the Gemfile to add a
version constraint like so:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="n"&gt;source&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;https://rubygems.org&amp;#39;&lt;/span&gt;

&lt;span class="n"&gt;gem&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;berkshelf&amp;#39;&lt;/span&gt;

&lt;span class="c1"&gt;# gem &amp;#39;test-kitchen&amp;#39;, :group =&amp;gt; :integration&lt;/span&gt;
&lt;span class="n"&gt;gem&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;test-kitchen&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;~&amp;gt; 1.0.0.beta.4&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ss"&gt;:group&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ss"&gt;:integration&lt;/span&gt;
&lt;span class="n"&gt;gem&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;kitchen-vagrant&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ss"&gt;:group&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ss"&gt;:integration&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;With that change, &lt;code&gt;bundle install&lt;/code&gt; will run to completion.&lt;/p&gt;
&lt;h2&gt;Parting Thought&lt;/h2&gt;
&lt;p&gt;It's a fact of life that books about software tools go out of date as
those tools are improved, so it's only a mild irritation that this
book looks forward to a release that has yet to arrive.&lt;/p&gt;
&lt;p&gt;Test Kitchen was discussed at Opscode's "Chef Summit" last week, and
&lt;a href="https://github.com/opscode/opscode-summit-2013/wiki/Tuesday-E-1600"&gt;the notes of that session&lt;/a&gt;
suggest that a release is now waiting for documentation.  That's a
well-intentioned reason, but a lousy excuse.  A 1.0 release with
documentation would be vastly superior to a 1.0 release without, but
the current situation impedes the community's ability to move forward
and help each other out.  This is particularly frustrating when I keep
hearing that the software itself is awesome, stable, and generally
ready for use.&lt;/p&gt;
&lt;p&gt;I look forward to updating this post to note that it should be ignored
in its entirety.&lt;/p&gt;</content><category term="Blog"/><category term="chef"/></entry><entry><title>DevOpsDays London - November 2013</title><link href="https://www.cryptocracy.com/blog/2013/11/16/devopsdays-london-november-2013/" rel="alternate"/><published>2013-11-16T21:30:00+00:00</published><updated>2013-11-16T21:30:00+00:00</updated><author><name>Zachary Stevens</name></author><id>tag:www.cryptocracy.com,2013-11-16:/blog/2013/11/16/devopsdays-london-november-2013/</id><summary type="html">&lt;p&gt;Thoughts on the second London DevOpsDays conference of 2013, including three recommended video talks and some reflections on the open spaces format.&lt;/p&gt;</summary><content type="html">&lt;p&gt;Last week saw the second London DevOpsDays conference for 2013.  BMC
sponsored video of the plenary sessions, all of which are now
&lt;a href="http://vimeo.com/album/2594031"&gt;on Vimeo&lt;/a&gt;.  I think the videos look
better than the sessions did in person (the lighting in the venue
wasn't great).  Read on for my thoughts...&lt;/p&gt;
&lt;h2&gt;Three Recommended Videos&lt;/h2&gt;
&lt;p&gt;Mark Burgess introduced his talk,
&lt;a href="http://vimeo.com/album/2594031/video/79377098"&gt;"What Science Tells Us About Information Infrastructure"&lt;/a&gt;,
as attempting to condense the essence of his new book into a brief
lecture.  The start is a little rough owing to technical hiccoughs,
but it's worth sticking with it.  While practical development is often
more art than science, operations still struggles to grow beyond
finger-painting.  On the one hand, it's great that mugs like me can
produce useful operationally-focussed work without learning the
lessons of the development profession; on the other, it's depressing
that this is par for the course.&lt;/p&gt;
&lt;p&gt;Mark stands out from the crowd by bringing a reasoned, academic
approach to his work in operations over the last two decades.
&lt;a href="http://www.amazon.co.uk/In-Search-Certainty-Information-Infrastructure-ebook/dp/B00ENEEWYO/"&gt;"In Search of Certainty"&lt;/a&gt;
is cheap enough that you should probably just buy it, but watch the
video if you'd like a taster.&lt;/p&gt;
&lt;p&gt;Ben Hughes gave us
&lt;a href="http://vimeo.com/album/2594031/video/79378300"&gt;"That's Mr. The Plague to you!  Security and this Devops Thing"&lt;/a&gt;.
A fun talk, peppered with geek cultural references, this session took
a look at the current reality of advanced security threats, and showed
how Etsy's security folks work to manage risk.  If you believe
security means saying "no" to everything, watch this to hear about a
cooperative, pragmatic approach.&lt;/p&gt;
&lt;p&gt;Jeffrey Fredrick described the title for his talk as "possibly the
worst he'd ever come up with".
&lt;a href="http://vimeo.com/album/2594031/video/79375237"&gt;"Crossing the Uncanny Valley of Culture Through Mutual Learning"&lt;/a&gt;
is a bit of a mouthful, but this was my favourite session of the
conference.  As the title suggests, it isn't a technical talk -
instead, it introduces a variety of cultural and psychological ideas
that have yet to really make it into the DevOps echo chamber.  If
you've appreciated &lt;a href="http://www.kitchensoap.com"&gt;John Allspaw's&lt;/a&gt;
writing about human error investigation, this one's for you.&lt;/p&gt;
&lt;p&gt;However, the breadth of ideas (and limited time) precluded depth in
some areas.  In particular, the section on Chris Argyris' work deserves
(at least) a session of its own.  I hope to see more of that at a future
DevOpsDays.  Until then, I'd recommend reading Benjamin Mitchell's
post about
&lt;a href="http://blog.benjaminm.net/argyris/the-ladder-of-inference/"&gt;"The Ladder of Inference"&lt;/a&gt;,
and William Noonan's book,
&lt;a href="http://www.discussingtheundiscussable.com"&gt;"Discussing the Undiscussable"&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;Not So Awesome&lt;/h2&gt;
&lt;p&gt;There was an Ignite session likening Game of Thrones to IT
stereotypes, or something.  I haven't read or watched GoT so this was
never going to grab me, but I was disappointed that one of the final
slides was a picture of an comely woman from the show that the speaker
openly described as "gratuitous".  While this was on screen, he
explained that he had delivered the deck without that picture at
Velocity NYC, and the feedback was that it needed a picture of her.&lt;/p&gt;
&lt;p&gt;Honestly, what the fuck?&lt;/p&gt;
&lt;p&gt;How much attention does this kind of shit need to get before people
cut it out?  Even if you personally can't see anything wrong with it,
haven't the reactions to similarly gratuitous conference
presentations over the last couple of years done enough to make you
realise that maybe you should reassess your opinions?&lt;/p&gt;
&lt;p&gt;Shame on whoever suggested the addition of a gratuitous slide, and
shame on the speaker for listening to them.  And shame on me for
failing to call it out at the time.&lt;/p&gt;
&lt;h2&gt;Open Spaces&lt;/h2&gt;
&lt;p&gt;Both afternoons at DevOpsDays are open spaces, where the attendees
propose topics of discussion, gather together, follow things where
they lead.  I have to confess that I can't review this part of the
conference, as I eschewed it in favour of off-site sessions (cough) at
the Euston Tap.&lt;/p&gt;
&lt;p&gt;I can report that the Euston Tap offered a broad selection of
delicious beers, and provided a suitable forum for extended
conversations with friends both old and new.  I had a great time, but
feel more than a little guilty for wasting the opportunity afforded by
the conference.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;If at any time during our time together you find yourself in any
situation where you are neither learning nor contributing, use your
two feet, go someplace else.&lt;/p&gt;
&lt;p&gt;— Harrison Owen, &lt;a href="http://en.wikipedia.org/wiki/Open_Space_Technology#Law_of_two_feet"&gt;The Law of Two Feet&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;I did go to the open spaces at DevOpsDays in March, and was left a
little underwhelmed.  This isn't a knock against open spaces in
general; &lt;a href="http://www.scalecamp.org.uk"&gt;Scale Camp&lt;/a&gt; embraced the
format, and blew my mind.  I'm not entirely sure why the DevOpsDays
didn't work for me in March (though I have a few ideas), but the Law
of Two Feet didn't really help me.  I might argue that I simply
applied it more thoroughly this time around, but that's a bit of a
cop-out.&lt;/p&gt;
&lt;p&gt;Having spoken to some other attendees, I suspect I would have been
disappointed again this time around - but I can't know that, and I
regret not going to find out.  In the worst case, I might have
developed a better understanding of what wasn't working for me, in
service of more constructive suggestions.&lt;/p&gt;
&lt;p&gt;On the flip side, other folks I spoke to clearly got value out of the
open space sessions, and I hope that most people fell into that camp.&lt;/p&gt;
&lt;h2&gt;Final Thoughts&lt;/h2&gt;
&lt;p&gt;Next time, I will aim to be more involved with the conference.  If my
opinions represent a wider group, then constructive contribution
serves a greater good.  If I'm alone in my opinions, perhaps greater
engagement will lead me to some kind of enlightenment.&lt;/p&gt;
&lt;p&gt;In any case, DevOpsDays remains worthy of a recommendation.  "DevOps"
still means a lot of different things to a lot of different people,
and few conferences bring so many of them together and give them the
opportunity to work it out.&lt;/p&gt;</content><category term="Blog"/><category term="devops"/></entry><entry><title>(Dis)Proof of Concept: MCollective SQS/SNS Connector</title><link href="https://www.cryptocracy.com/blog/2013/11/16/disproof-of-concept-mcollective-sqs-sns-connector/" rel="alternate"/><published>2013-11-16T03:30:00+00:00</published><updated>2013-11-16T03:30:00+00:00</updated><author><name>Zachary Stevens</name></author><id>tag:www.cryptocracy.com,2013-11-16:/blog/2013/11/16/disproof-of-concept-mcollective-sqs-sns-connector/</id><summary type="html">&lt;p&gt;An experiment in connecting MCollective to Amazon SQS and SNS, and why it turned out to be a poor fit for orchestration use cases.&lt;/p&gt;</summary><content type="html">&lt;p&gt;Yesterday, someone joined the #mcollective IRC channel to
ask how to connect MCollective to Amazon's &lt;a href="http://aws.amazon.com/sqs/"&gt;Simple Queue Service&lt;/a&gt;.
I explored that idea earlier this year, and decided not to pursue it,
but it seems I didn't get around to sharing the results of the
experiment.  Until now.&lt;/p&gt;
&lt;h2&gt;Context&lt;/h2&gt;
&lt;p&gt;I was setting up a small infrastructure in EC2, but I wanted to have
MCollective available.  I couldn't justify the cost of the extra
capacity required to run ActiveMQ - I didn't want the extra hassle,
either.  On the face of it, SQS seemed like a good place to start my
investigation.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Amazon Simple Queue Service (SQS) is a fast, reliable, scalable, fully
managed message queuing service. SQS makes it simple and
cost-effective to decouple the components of a cloud application.&lt;/p&gt;
&lt;p&gt;— Amazon, &lt;a href="http://aws.amazon.com/sqs/"&gt;SQS Overview&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;As the name implies, SQS just provides queues - to have something
analogous to pub-sub topics, we're pointed towards the
&lt;a href="http://aws.amazon.com/sns/"&gt;Simple Notification Service&lt;/a&gt;.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;When combined with Amazon Simple Notification Service (SNS),
developers can 'fanout' identical messages to multiple SQS queues in
parallel. When developers want to process the messages in multiple
passes, fanout helps complete this more quickly, and with fewer delays
due to bottlenecks at any one stage. Fanout also makes it easier to
record duplicate copies of your messages, for example in different
databases.&lt;/p&gt;
&lt;p&gt;— Amazon, &lt;a href="http://aws.amazon.com/sqs/"&gt;SQS Overview&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Fast, reliable, simple - what's not to like?&lt;/p&gt;
&lt;h2&gt;Experiment&lt;/h2&gt;
&lt;p&gt;Though I maintain that I'm not much of a programmer, I thought I could
take a shot at writing a suitable MCollective connector plugin.  There
were enough examples of working connectors for me to refer to, and it
only had to be good enough to prove a point - I figured I could get
someone to help tidy it up if it worked.&lt;/p&gt;
&lt;p&gt;You can find
&lt;a href="https://github.com/zts/mcollective-snssqs-connector"&gt;the code on my Github&lt;/a&gt;,
but don't expect to use it.  It's state is somewhere between "doesn't
work very well" and "doesn't work at all".  To be fair, most of that
is down to my code - but I came to the conclusion that I would not be
able to make it work well enough that I'd want to use it.&lt;/p&gt;
&lt;p&gt;Unhelpful characteristics of SQS:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;messages may not be delivered in FIFO order&lt;/li&gt;
&lt;li&gt;messages may be delivered more than once&lt;/li&gt;
&lt;li&gt;deleted messages may be redelivered under some circumstances&lt;/li&gt;
&lt;li&gt;the standard polling behaviour might not return all available
   message - and if there's fewer than 1000 messages in the queue, it
   may return nothing at all!&lt;/li&gt;
&lt;li&gt;"long polling" guarantees that if messages are in the queue, at
   least 1 will be returned - but the definition of this behaviour is
   pretty vague.&lt;/li&gt;
&lt;li&gt;"long polling" can wait a maximum of 20 seconds for a message.&lt;/li&gt;
&lt;li&gt;SQS is charged per-request - polling (and receiving nothing) is
   chargeable.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I also ran into trouble automating subscriptions of SQS queues to SNS
topics - while it worked, it was possible to end up with duplicate
subscriptions that eventually resulted in silent failures.&lt;/p&gt;
&lt;p&gt;None of the issues is a show-stopper as long as you can accept
mcollective latency being measured in seconds instead of
milliseconds.&lt;/p&gt;
&lt;h2&gt;Future Possibilities?&lt;/h2&gt;
&lt;p&gt;I'm not planning to spend any more time on this.  If I was, I'd look
at the following:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Add a thread to handle long polling messages from SQS into a buffer&lt;/li&gt;
&lt;li&gt;Dedupe received messages to ensure each is delivered to mco only
   once&lt;/li&gt;
&lt;li&gt;Potentially fiddle order of received messages (whether or not this
   really matters will depend on your use)&lt;/li&gt;
&lt;li&gt;Carefully groom SNS topics and subscriptions&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Alternatives&lt;/h2&gt;
&lt;p&gt;I found a project on Github called
&lt;a href="https://github.com/andersdyekjaerhansen/ec2_collective"&gt;ec2_collective&lt;/a&gt;,
which aims to build something like MCollective on top of SQS.  It
claims arbitrary command execution as a feature, and I suspect it
underestimates usage charges, but it's worth a look.&lt;/p&gt;
&lt;p&gt;As for me, I'm looking at MCollective's redis connector.  That
involves its own tradeoffs, which I'll save for another post.&lt;/p&gt;
&lt;h2&gt;Summary&lt;/h2&gt;
&lt;p&gt;You can certainly build solid, scalable applications around SNS and
SQS - but they're not a straight replacement for a traditional STOMP
or AMQP message broker.  Fire-and-forget and loosely-coupled
asynchronous messaging patterns should work out alright -
orchestration, not so much.&lt;/p&gt;</content><category term="Blog"/><category term="mcollective"/><category term="aws"/></entry><entry><title>MCollective Chef cookbook updated to 0.11.0</title><link href="https://www.cryptocracy.com/blog/2013/04/21/chef-mcollective-cookbook-v-0-11-0/" rel="alternate"/><published>2013-04-21T23:00:00+01:00</published><updated>2013-04-21T23:00:00+01:00</updated><author><name>Zachary Stevens</name></author><id>tag:www.cryptocracy.com,2013-04-21:/blog/2013/04/21/chef-mcollective-cookbook-v-0-11-0/</id><summary type="html">&lt;p&gt;Version 0.11.0 of the MCollective Chef cookbook brings improved configuration flexibility, updated defaults for MCollective 2.2, and configurable identity.&lt;/p&gt;</summary><content type="html">&lt;p&gt;The recent release of an
&lt;a href="https://github.com/VendaTech/mcollective-x509-security"&gt;x509 security provider&lt;/a&gt;
for MCollective has motivated me to do some more work on the
&lt;a href="http://community.opscode.com/cookbooks/mcollective"&gt;mcollective cookbook&lt;/a&gt;.
Although it worked well enough to play around with, the configuration
was not especially flexible and the cookbook did not lend itself to wrapping.&lt;/p&gt;
&lt;p&gt;MCollective 1.2 was the current release when I originally wrote the
cookbook, and the configuration reflected that.  New features
introduced in later releases of MCollective weren't enabled - it
worked, but not at its best.  The configuration defaults now reflect
MCollective 2.2.&lt;/p&gt;
&lt;p&gt;Configuration is almost entirely parameterised.  If you have need to
override the cookbook's templates to implement your configuration,
I'd like to improve this further.&lt;/p&gt;
&lt;p&gt;The MCollective "identity" is now configurable via an attribute, but
continues to default to &lt;code&gt;node['fqdn']&lt;/code&gt;.  When your node name and your
identity match, you can use the
&lt;a href="https://github.com/zts/mcollective-chef-discovery"&gt;chef-server discovery plugin&lt;/a&gt;
- so this default may change in the next major release.&lt;/p&gt;
&lt;p&gt;Version 0.11.0 of the cookbook is now available
&lt;a href="http://community.opscode.com/cookbooks/mcollective"&gt;on the community site&lt;/a&gt;
and &lt;a href="https://github.com/zts/cookbook-mcollective"&gt;on Github&lt;/a&gt;.  If you
find it doesn't do what you need, or you have suggestions to improve
it, please open issues on github.&lt;/p&gt;</content><category term="Blog"/><category term="mcollective"/><category term="chef"/></entry><entry><title>(Very) Simple x509 PKI with Chef</title><link href="https://www.cryptocracy.com/blog/2013/04/20/very-simple-x509-pki-with-chef/" rel="alternate"/><published>2013-04-20T21:00:00+01:00</published><updated>2013-04-20T21:00:00+01:00</updated><author><name>Zachary Stevens</name></author><id>tag:www.cryptocracy.com,2013-04-20:/blog/2013/04/20/very-simple-x509-pki-with-chef/</id><summary type="html">&lt;p&gt;The x509 cookbook and chef-ssl-client gem automate creating a private Certificate Authority, generating certificate signing requests on Chef nodes, and installing the signed certificates.&lt;/p&gt;</summary><content type="html">&lt;p&gt;Last year, Venda released a project to create and manage a simple x509
PKI using Chef and  Chris Andrews introduced it with his blog post,
&lt;a href="http://chrisa.github.com/blog/2012/07/22/deploying-a-pki-with-chef/"&gt;"Deploying a PKI With Chef"&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;A few people tried out it out after the initial release
(and submitted patches or bug reports - thankyou!), and it has since
been renamed to become the x509 cookbook, which you can find
&lt;a href="http://community.opscode.com/cookbooks/x509"&gt;on the community site&lt;/a&gt;
or &lt;a href="https://github.com/VendaTech/chef-cookbook-ssl"&gt;on github&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;I've found it useful of late, so let's take another look.&lt;/p&gt;
&lt;h2&gt;What's The Problem?&lt;/h2&gt;
&lt;p&gt;You've decided to SSL-enable one of your internal services, and that
means you need an x509 certificate.  The cheapest and easiest option
is to
&lt;a href="https://devcenter.heroku.com/articles/ssl-certificate-self"&gt;generate a self-signed certificate&lt;/a&gt;,
but this option is not without drawbacks.&lt;/p&gt;
&lt;p&gt;When you connect to a service using a self-signed certificate, you can
be confident that your communication is encrypted, but you &lt;em&gt;can't&lt;/em&gt; be
sure who you're communicating with.  You are protected from attackers
"sniffing" data from an insecure network, but not from attackers
creating a fake service in front of the one you expect to connect to (a
man-in-the-middle attack).&lt;/p&gt;
&lt;p&gt;It's also annoying to users, as most software will (rightly!) warn you
that self-signed certificates are not to be trusted.&lt;/p&gt;
&lt;p&gt;A better option is to run an internal Certificate Authority, and use
that to sign the certificates for your SSL-enabled services.  You can
import your CA's certificate into your browser (or OS), which will
then trust services using certificates that it has signed.&lt;/p&gt;
&lt;p&gt;It's not hard to make your own CA, but getting a signed certificate
for your service necessarily involves a number of steps:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;On the host, generate a secret key and a certificate signing request (CSR)&lt;/li&gt;
&lt;li&gt;Get the CSR to the internal CA&lt;/li&gt;
&lt;li&gt;Create a signed certificate using the CSR and the internal CA&lt;/li&gt;
&lt;li&gt;Get the signed certificate to the host&lt;/li&gt;
&lt;li&gt;Install the signed certificate&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Venda wanted to automate this process and the result is the &lt;code&gt;x509&lt;/code&gt;
cookbook, and the &lt;code&gt;chef-ssl-client&lt;/code&gt; gem.&lt;/p&gt;
&lt;h2&gt;1. Installation&lt;/h2&gt;
&lt;p&gt;Note: these tools work with &lt;code&gt;chef-client&lt;/code&gt; and the Chef server -
&lt;code&gt;chef-solo&lt;/code&gt; is not supported.&lt;/p&gt;
&lt;h3&gt;Certificate Authority&lt;/h3&gt;
&lt;p&gt;To create and manage a CA, we will be using the &lt;code&gt;chef-ssl&lt;/code&gt; utility.
It loads your &lt;code&gt;knife&lt;/code&gt; configuration to determine how to connect to the
Chef server, so you'll have to install it somewhere you can already
use knife.&lt;/p&gt;
&lt;p&gt;The chef-ssl utility is provided by the &lt;code&gt;chef-ssl-client&lt;/code&gt; gem.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;gem&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;install&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;chef&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;ssl&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="k"&gt;no&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;rdoc&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="k"&gt;no&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;ri&lt;/span&gt;
&lt;span class="nl"&gt;Fetching&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;chef&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;ssl&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mf"&gt;1.0.5&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;gem&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;Successfully&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;installed&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;chef&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;ssl&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mf"&gt;1.0.5&lt;/span&gt;

&lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;chef&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;ssl&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;help&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;chef&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;ssl&lt;/span&gt;

&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;Chef&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;automated&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;SSL&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;certificate&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;signing&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;tool&lt;/span&gt;

&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nl"&gt;Commands&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;autosign&lt;/span&gt;&lt;span class="w"&gt;             &lt;/span&gt;&lt;span class="k"&gt;Search&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;CSRs&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ow"&gt;and&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;sign&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;them&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;with&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;the&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;given&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;CA&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;help&lt;/span&gt;&lt;span class="w"&gt;                 &lt;/span&gt;&lt;span class="n"&gt;Display&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;global&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ow"&gt;or&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;command&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;help&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;documentation&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;issue&lt;/span&gt;&lt;span class="w"&gt;                &lt;/span&gt;&lt;span class="n"&gt;Issue&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;an&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;ad&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;hoc&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;certificate&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;makeca&lt;/span&gt;&lt;span class="w"&gt;               &lt;/span&gt;&lt;span class="n"&gt;Creates&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;CA&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;search&lt;/span&gt;&lt;span class="w"&gt;               &lt;/span&gt;&lt;span class="n"&gt;Searches&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;outstanding&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;CSRs&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nf"&gt;sign&lt;/span&gt;&lt;span class="w"&gt;                 &lt;/span&gt;&lt;span class="k"&gt;Search&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;the&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;given&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;CSR&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;by&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ow"&gt;and&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;provide&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;signed&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;certificate&lt;/span&gt;

&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="k"&gt;Global&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;Options&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;h&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;help&lt;/span&gt;&lt;span class="w"&gt;           &lt;/span&gt;&lt;span class="n"&gt;Display&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;help&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;documentation&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;v&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;version&lt;/span&gt;&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="n"&gt;Display&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;version&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;information&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;--trace          Display backtrace when an error occurs&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h3&gt;Chef&lt;/h3&gt;
&lt;p&gt;To create certificates, we'll need the &lt;code&gt;x509&lt;/code&gt; cookbook on our Chef
server.  Some of this cookbook's functionality relies on the &lt;code&gt;vt-gpg&lt;/code&gt;
cookbook, which is listed as a dependency.  We won't be using that
functionality today, but Chef will insist that we upload both.&lt;/p&gt;
&lt;p&gt;Both cookbooks are available on the community site, so downloading
and installing them using Knife might look like this:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="o"&gt;$&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;knife&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;cookbook&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;site&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;install&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;x509&lt;/span&gt;
&lt;span class="n"&gt;Installing&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;x509&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;to&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;Users&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;zts&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;code&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;chef&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;repo&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;cookbooks&lt;/span&gt;
&lt;span class="n"&gt;Checking&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;out&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;the&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;master&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;branch&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;
&lt;span class="n"&gt;Creating&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;pristine&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;copy&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;branch&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;chef&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;vendor&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;x509&lt;/span&gt;
&lt;span class="o"&gt;...&lt;/span&gt;
&lt;span class="n"&gt;Cookbook&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;x509&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;version&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;1.0&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;successfully&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;installed&lt;/span&gt;
&lt;span class="n"&gt;Installing&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;vt&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;gpg&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;to&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;Users&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;zts&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;code&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;chef&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;repo&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;cookbooks&lt;/span&gt;
&lt;span class="n"&gt;Checking&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;out&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;the&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;master&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;branch&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;
&lt;span class="n"&gt;Creating&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;pristine&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;copy&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;branch&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;chef&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;vendor&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;vt&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;gpg&lt;/span&gt;
&lt;span class="o"&gt;...&lt;/span&gt;
&lt;span class="n"&gt;Cookbook&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;vt&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;gpg&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;version&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;1.0&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;successfully&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;installed&lt;/span&gt;
&lt;span class="o"&gt;$&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;knife&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;cookbook&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;upload&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;x509&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;vt&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;gpg&lt;/span&gt;
&lt;span class="n"&gt;Uploading&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;vt&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;gpg&lt;/span&gt;&lt;span class="w"&gt;         &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mf"&gt;1.0&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="n"&gt;Uploading&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;x509&lt;/span&gt;&lt;span class="w"&gt;           &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mf"&gt;1.0&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="n"&gt;Uploaded&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;cookbooks&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h2&gt;2. Usage&lt;/h2&gt;
&lt;h3&gt;Creating a Certificate Authority&lt;/h3&gt;
&lt;p&gt;To sign certificates, we're going to need a CA.  This is accomplished
using the &lt;code&gt;chef-ssl makeca&lt;/code&gt; command on the host where you installed
&lt;code&gt;chef-ssl-client&lt;/code&gt;.  The required arguments are &lt;code&gt;--dn&lt;/code&gt; (the
Distinguished Name of the CA), and &lt;code&gt;--ca-path&lt;/code&gt;, the place where the
CA's files will be stored.  The DN will be visible in the CA
certificate, and any certificates it signs.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt; $ chef-ssl makeca --dn &amp;#39;/CN=My Test CA&amp;#39; --ca-path ./testCA
New CA DN: /CN=My Test CA
Enter new CA passphrase:
Re-enter new CA passphrase:

Creating new CA: done
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h3&gt;Defining a certificate&lt;/h3&gt;
&lt;p&gt;To create a certificate on one of our Chef nodes, we use the
&lt;code&gt;x509_certificate&lt;/code&gt; LWRP provided by the &lt;code&gt;x509&lt;/code&gt; cookbook.  This LWRP
has some dependencies, which are installed by the default recipe - but
this means that &lt;code&gt;recipe[x509::default]&lt;/code&gt; needs to be applied.  It
doesn't matter whether you put it on the run_list or load it using
&lt;code&gt;include_recipe&lt;/code&gt;, but listing it as a dependency in another cookbook's
&lt;code&gt;metadata.rb&lt;/code&gt; is not enough.&lt;/p&gt;
&lt;p&gt;In this example, we're creating a server certificate for
"www.example.com", and indicating that we'd like it to be signed by
"testCA".&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="n"&gt;include_recipe&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;x509::default&amp;quot;&lt;/span&gt;

&lt;span class="n"&gt;x509_certificate&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;www.example.com&amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;do&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;certificate&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;/etc/ssl/www.example.com.cert&amp;quot;&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="w"&gt;          &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;/etc/ssl/www.example.com.key&amp;quot;&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;ca&lt;/span&gt;&lt;span class="w"&gt;           &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;testCA&amp;quot;&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;type&lt;/span&gt;&lt;span class="w"&gt;         &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;server&amp;quot;&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;bits&lt;/span&gt;&lt;span class="w"&gt;         &lt;/span&gt;&lt;span class="mi"&gt;2048&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;days&lt;/span&gt;&lt;span class="w"&gt;         &lt;/span&gt;&lt;span class="mi"&gt;365&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The first time we run chef-client with this recipe, we'll see logs
similar to this:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;zts&lt;/span&gt;&lt;span class="err"&gt;@&lt;/span&gt;&lt;span class="n"&gt;test&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;centos6&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="o"&gt;~%&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;sudo&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;chef&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;force&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;logger&lt;/span&gt;
&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;2013&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;04&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="n"&gt;T19&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;14&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;35&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="mi"&gt;00&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;00&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;INFO&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;***&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Chef&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;11.4&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;***&lt;/span&gt;
&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;2013&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;04&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="n"&gt;T19&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;14&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;36&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="mi"&gt;00&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;00&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;INFO&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Run&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;List&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;is&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;recipe&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;x509&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;example&lt;/span&gt;&lt;span class="p"&gt;]]&lt;/span&gt;
&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;2013&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;04&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="n"&gt;T19&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;14&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;36&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="mi"&gt;00&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;00&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;INFO&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Run&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;List&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;expands&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;to&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;x509&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;example&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;2013&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;04&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="n"&gt;T19&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;14&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;36&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="mi"&gt;00&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;00&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;INFO&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Starting&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Chef&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Run&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;test&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;centos6&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;nat0&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;cryptocracy&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;com&lt;/span&gt;
&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;2013&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;04&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="n"&gt;T19&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;14&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;36&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="mi"&gt;00&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;00&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;INFO&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Running&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;start&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;handlers&lt;/span&gt;
&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;2013&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;04&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="n"&gt;T19&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;14&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;36&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="mi"&gt;00&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;00&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;INFO&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Start&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;handlers&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;complete&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;
&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;2013&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;04&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="n"&gt;T19&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;14&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;36&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="mi"&gt;00&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;00&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;INFO&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Loading&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;cookbooks&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;vt&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;gpg&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;x509&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;2013&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;04&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="n"&gt;T19&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;14&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;36&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="mi"&gt;00&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;00&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;WARN&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;X509&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;library&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;dependency&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;eassl&amp;#39;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ow"&gt;not&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;loaded&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;cannot&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;load&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;such&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;file&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;eassl&lt;/span&gt;
&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;2013&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;04&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="n"&gt;T19&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;14&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;36&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="mi"&gt;00&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;00&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;INFO&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Processing&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;chef_gem&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;eassl2&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;action&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;nothing&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x509&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;default&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;line&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;25&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;2013&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;04&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="n"&gt;T19&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;14&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;36&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="mi"&gt;00&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;00&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;INFO&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Processing&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;chef_gem&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;eassl2&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;action&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;upgrade&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x509&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;default&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;line&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;25&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;2013&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;04&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="n"&gt;T19&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;16&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;21&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="mi"&gt;00&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;00&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;INFO&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;chef_gem&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;eassl2&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;upgraded&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;from&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;uninstalled&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;to&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;2.0&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;
&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;2013&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;04&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="n"&gt;T19&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;16&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;21&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="mi"&gt;00&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;00&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;INFO&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Processing&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;chef_gem&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;eassl2&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;action&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;nothing&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x509&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;default&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;line&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;25&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;2013&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;04&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="n"&gt;T19&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;16&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;21&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="mi"&gt;00&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;00&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;INFO&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Processing&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;x509_certificate&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;www&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;example&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;com&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;action&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;create&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x509&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;example&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;line&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;2013&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;04&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="n"&gt;T19&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;16&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;21&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="mi"&gt;00&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;00&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;INFO&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Processing&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;file&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;etc&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;ssl&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;www&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;example&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;com&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;cert&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;action&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;create&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="k"&gt;var&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;cache&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;chef&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;cookbooks&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;x509&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;providers&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;certificate&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;rb&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;line&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;2013&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;04&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="n"&gt;T19&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;16&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;21&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="mi"&gt;00&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;00&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;INFO&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;entered&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;create&lt;/span&gt;
&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;2013&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;04&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="n"&gt;T19&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;16&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;21&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="mi"&gt;00&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;00&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;INFO&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;file&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;etc&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;ssl&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;www&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;example&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;com&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;cert&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;owner&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;changed&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;to&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;
&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;2013&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;04&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="n"&gt;T19&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;16&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;21&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="mi"&gt;00&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;00&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;INFO&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;file&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;etc&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;ssl&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;www&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;example&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;com&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;cert&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;group&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;changed&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;to&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;
&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;2013&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;04&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="n"&gt;T19&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;16&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;21&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="mi"&gt;00&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;00&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;INFO&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;file&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;etc&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;ssl&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;www&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;example&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;com&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;cert&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;mode&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;changed&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;to&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;644&lt;/span&gt;
&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;2013&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;04&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="n"&gt;T19&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;16&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;21&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="mi"&gt;00&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;00&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;INFO&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;file&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;etc&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;ssl&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;www&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;example&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;com&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;cert&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;created&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;file&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;etc&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;ssl&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;www&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;example&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;com&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;cert&lt;/span&gt;
&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;2013&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;04&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="n"&gt;T19&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;16&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;21&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="mi"&gt;00&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;00&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;INFO&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Processing&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;file&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;etc&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;ssl&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;www&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;example&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;com&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;action&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;create&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="k"&gt;var&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;cache&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;chef&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;cookbooks&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;x509&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;providers&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;certificate&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;rb&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;line&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;11&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;2013&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;04&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="n"&gt;T19&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;16&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;21&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="mi"&gt;00&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;00&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;INFO&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;entered&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;create&lt;/span&gt;
&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;2013&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;04&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="n"&gt;T19&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;16&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;21&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="mi"&gt;00&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;00&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;INFO&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;file&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;etc&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;ssl&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;www&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;example&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;com&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;owner&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;changed&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;to&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;
&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;2013&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;04&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="n"&gt;T19&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;16&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;21&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="mi"&gt;00&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;00&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;INFO&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;file&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;etc&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;ssl&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;www&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;example&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;com&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;group&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;changed&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;to&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;
&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;2013&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;04&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="n"&gt;T19&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;16&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;21&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="mi"&gt;00&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;00&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;INFO&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;file&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;etc&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;ssl&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;www&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;example&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;com&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;mode&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;changed&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;to&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;600&lt;/span&gt;
&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;2013&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;04&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="n"&gt;T19&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;16&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;21&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="mi"&gt;00&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;00&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;INFO&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;file&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;etc&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;ssl&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;www&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;example&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;com&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;created&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;file&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;etc&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;ssl&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;www&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;example&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;com&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt;
&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;2013&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;04&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="n"&gt;T19&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;16&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;22&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="mi"&gt;00&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;00&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;INFO&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Chef&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Run&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;complete&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ow"&gt;in&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;106.180117863&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;seconds&lt;/span&gt;
&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;2013&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;04&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="n"&gt;T19&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;16&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;22&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="mi"&gt;00&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;00&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;INFO&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Running&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;report&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;handlers&lt;/span&gt;
&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;2013&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;04&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="n"&gt;T19&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;16&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;22&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="mi"&gt;00&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;00&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;INFO&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Report&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;handlers&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;complete&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Three things have happened during this run.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;The &lt;code&gt;eassl&lt;/code&gt; gem is installed, required by the &lt;code&gt;x509_certificate&lt;/code&gt;
LWRP.&lt;/li&gt;
&lt;li&gt;A self-signed certificate is generated and installed.&lt;/li&gt;
&lt;li&gt;A Certificate Signing Request (CSR) is created and saved in the
&lt;code&gt;csr_outbox&lt;/code&gt; attribute on the node.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;We can check the last action using &lt;code&gt;knife node show&lt;/code&gt;:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;knife&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;node&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;show&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;test&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;centos6&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;nat0&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;cryptocracy&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;com&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;csr_outbox&lt;/span&gt;
&lt;span class="nx"&gt;test&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;centos6&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;nat0&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;cryptocracy&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;com&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nx"&gt;csr_outbox&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nx"&gt;www&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;example&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;com&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="nx"&gt;ca&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;   &lt;/span&gt;&lt;span class="nx"&gt;testCA&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="nx"&gt;csr&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="o"&gt;-----&lt;/span&gt;&lt;span class="nx"&gt;BEGIN&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;CERTIFICATE&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;REQUEST&lt;/span&gt;&lt;span class="o"&gt;-----&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="nx"&gt;MIIC7DCCAdQCAQAwgaYxCzAJBgNVBAYTAkdCMQ8wDQYDVQQIEwZMb25kb24xDzAN&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="nx"&gt;BgNVBAcTBkxvbmRvbjEUMBIGA1UEChMLRXhhbXBsZSBMdGQxHzAdBgNVBAsTFkNl&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="nx"&gt;cnRpZmljYXRlIEF1dG9tYXRpb24xGDAWBgNVBAMTD3d3dy5leGFtcGxlLmNvbTEk&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="nx"&gt;MCIGCSqGSIb3DQEJARMVeDUwOS1hdXRvQGV4YW1wbGUuY29tMIIBIjANBgkqhkiG&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="mi"&gt;9&lt;/span&gt;&lt;span class="nx"&gt;w0BAQEFAAOCAQ8AMIIBCgKCAQEAv6N6WZIiwwuOcFIni9b7lEcbd&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;Djpe00TZ7B&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="nx"&gt;mB8dJa3pFZM3Le5MsUtswwIMe9GpFyDNBImYb0ebTsOwGykqWg4qjG0&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;tNu0DARt&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="mi"&gt;9&lt;/span&gt;&lt;span class="nx"&gt;JX3SKeC31h9ShUt2XOL5ZpGqMlDWQY2qdKZnA0ge&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="nx"&gt;vmV1UW2fyb1e0Wwyi&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="nx"&gt;CgUK&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="nx"&gt;fZd6A3JWMd1TykVHZQJwt3xuTYiu&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="nx"&gt;wZbOj9OLlNqOFjEtnIstXgKTBhI3qs3Zuj&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="nx"&gt;lQU6FEWdqghzwaPSXG1&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;tNQn6Ql1wKsnbflONlzQbjLdaItDRnYzj5KlYroXChjH&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="nx"&gt;tE4Y4f6KC&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;BhQlENfytSgGOC9W&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="nx"&gt;KWtaAfIIg&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;E&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="nx"&gt;YLHFa8QmqLwIDAQABoAAwDQYJ&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="nx"&gt;KoZIhvcNAQEFBQADggEBAIW3og6ARIJFs4Ipj7AEebN0E8YYMsgBhqtAlg7DkLZt&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="nx"&gt;myQeCpL8Gn04tkCYYkvh&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="nx"&gt;BoaE0PZ7wvFRkdphQ6Fvxji4CaDoeItSppM&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="nx"&gt;C79nqo&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="nx"&gt;gfi1xmufb1d0RKwDua8nLN428SddWeTMGw65X7GfXkl9JQcEpmA4ecKmVMDUUgNo&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="nx"&gt;dNRRJpSKT&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="nx"&gt;OPT&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="mi"&gt;9&lt;/span&gt;&lt;span class="nx"&gt;PFXY9ApSKENOSkJn&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;XtF8Dnx1xI5WBL7eYzRyM1es44RcuN&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="nx"&gt;OtKdA1u&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;qtFAX1gRrvTvlqmVbevC1kI5Wx7tAmvNCkQ2RrhI9vdwFS3pGpiNpKRx&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="nx"&gt;eENUk&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;N&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;rhOPXO9&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;v0JHZX455UZh5EqINoZ7eGrY4hE&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="o"&gt;-----&lt;/span&gt;&lt;span class="nx"&gt;END&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;CERTIFICATE&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;REQUEST&lt;/span&gt;&lt;span class="o"&gt;-----&lt;/span&gt;

&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="nx"&gt;date&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;2013&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;04&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;19&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;16&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;21&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="mi"&gt;0000&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="nx"&gt;days&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;365&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;   &lt;/span&gt;&lt;span class="mi"&gt;80&lt;/span&gt;&lt;span class="nx"&gt;fc0fb9266db7b83f85850fa0e6548b6d70ee68c8b5b412f1deea6ebdef0404&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="k"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;server&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h3&gt;Signing a CSR (chef-ssl)&lt;/h3&gt;
&lt;p&gt;After our node has created a signing request, we return to the
&lt;code&gt;chef-ssl&lt;/code&gt; utility to process it.  The &lt;code&gt;chef-ssl autosign&lt;/code&gt; command
finds pending CSRs for a given CA by matching the &lt;code&gt;--ca-name&lt;/code&gt; argument
against the &lt;code&gt;ca&lt;/code&gt; parameter used in the &lt;code&gt;x509_certificate&lt;/code&gt; resource.
You'll be asked whether you'd like to sign each request it finds.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;chef&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;ssl&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;autosign&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;ca&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="ss"&gt;&amp;quot;testCA&amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;ca&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="k"&gt;path&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;testCA&lt;/span&gt;
&lt;span class="n"&gt;Enter&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;CA&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;passphrase&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="k"&gt;Search&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;CA&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;testCA&lt;/span&gt;
&lt;span class="w"&gt;     &lt;/span&gt;&lt;span class="n"&gt;Node&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;Hostname&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;test&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;centos6&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;nat0&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;cryptocracy&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;com&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;Certificate&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;Type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;server&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;Certificate&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;DN&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;C&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;GB&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;ST&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;London&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;L&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;London&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;O&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;Example&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Ltd&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;OU&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;Certificate&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Automation&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;CN&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;www&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;example&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;com&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;emailAddress&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;x509&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;auto&lt;/span&gt;&lt;span class="nv"&gt;@example&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;com&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="n"&gt;Requested&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;CA&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;testCA&lt;/span&gt;
&lt;span class="n"&gt;Requested&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;Validity&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;365&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;days&lt;/span&gt;
&lt;span class="o"&gt;-----&lt;/span&gt;&lt;span class="k"&gt;BEGIN&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;CERTIFICATE&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;REQUEST&lt;/span&gt;&lt;span class="o"&gt;-----&lt;/span&gt;
&lt;span class="n"&gt;MIIC7DCCAdQCAQAwgaYxCzAJBgNVBAYTAkdCMQ8wDQYDVQQIEwZMb25kb24xDzAN&lt;/span&gt;
&lt;span class="n"&gt;BgNVBAcTBkxvbmRvbjEUMBIGA1UEChMLRXhhbXBsZSBMdGQxHzAdBgNVBAsTFkNl&lt;/span&gt;
&lt;span class="n"&gt;cnRpZmljYXRlIEF1dG9tYXRpb24xGDAWBgNVBAMTD3d3dy5leGFtcGxlLmNvbTEk&lt;/span&gt;
&lt;span class="n"&gt;MCIGCSqGSIb3DQEJARMVeDUwOS1hdXRvQGV4YW1wbGUuY29tMIIBIjANBgkqhkiG&lt;/span&gt;
&lt;span class="mi"&gt;9&lt;/span&gt;&lt;span class="n"&gt;w0BAQEFAAOCAQ8AMIIBCgKCAQEAv6N6WZIiwwuOcFIni9b7lEcbd&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;Djpe00TZ7B&lt;/span&gt;
&lt;span class="n"&gt;mB8dJa3pFZM3Le5MsUtswwIMe9GpFyDNBImYb0ebTsOwGykqWg4qjG0&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;tNu0DARt&lt;/span&gt;
&lt;span class="mi"&gt;9&lt;/span&gt;&lt;span class="n"&gt;JX3SKeC31h9ShUt2XOL5ZpGqMlDWQY2qdKZnA0ge&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="n"&gt;vmV1UW2fyb1e0Wwyi&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="n"&gt;CgUK&lt;/span&gt;
&lt;span class="n"&gt;fZd6A3JWMd1TykVHZQJwt3xuTYiu&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="n"&gt;wZbOj9OLlNqOFjEtnIstXgKTBhI3qs3Zuj&lt;/span&gt;
&lt;span class="n"&gt;lQU6FEWdqghzwaPSXG1&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;tNQn6Ql1wKsnbflONlzQbjLdaItDRnYzj5KlYroXChjH&lt;/span&gt;
&lt;span class="n"&gt;tE4Y4f6KC&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;BhQlENfytSgGOC9W&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="n"&gt;KWtaAfIIg&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;E&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="n"&gt;YLHFa8QmqLwIDAQABoAAwDQYJ&lt;/span&gt;
&lt;span class="n"&gt;KoZIhvcNAQEFBQADggEBAIW3og6ARIJFs4Ipj7AEebN0E8YYMsgBhqtAlg7DkLZt&lt;/span&gt;
&lt;span class="n"&gt;myQeCpL8Gn04tkCYYkvh&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="n"&gt;BoaE0PZ7wvFRkdphQ6Fvxji4CaDoeItSppM&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="n"&gt;C79nqo&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;
&lt;span class="n"&gt;gfi1xmufb1d0RKwDua8nLN428SddWeTMGw65X7GfXkl9JQcEpmA4ecKmVMDUUgNo&lt;/span&gt;
&lt;span class="n"&gt;dNRRJpSKT&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="n"&gt;OPT&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="mi"&gt;9&lt;/span&gt;&lt;span class="n"&gt;PFXY9ApSKENOSkJn&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;XtF8Dnx1xI5WBL7eYzRyM1es44RcuN&lt;/span&gt;
&lt;span class="n"&gt;OtKdA1u&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;qtFAX1gRrvTvlqmVbevC1kI5Wx7tAmvNCkQ2RrhI9vdwFS3pGpiNpKRx&lt;/span&gt;
&lt;span class="n"&gt;eENUk&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;N&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;rhOPXO9&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;v0JHZX455UZh5EqINoZ7eGrY4hE&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;
&lt;span class="o"&gt;-----&lt;/span&gt;&lt;span class="k"&gt;END&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;CERTIFICATE&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;REQUEST&lt;/span&gt;&lt;span class="o"&gt;-----&lt;/span&gt;

&lt;span class="nf"&gt;Sign&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;with&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;CN&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;My&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Test&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;CA&lt;/span&gt;
&lt;span class="nf"&gt;Sign&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;this&lt;/span&gt;&lt;span class="vm"&gt;?&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;yes&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ow"&gt;or&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;no&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;yes&lt;/span&gt;
&lt;span class="nl"&gt;Signed&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;SHA1&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Fingerprint&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;67&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;39&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;44&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;79&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;31&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;74&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt;&lt;span class="nl"&gt;E5&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="nl"&gt;D0&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;54&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="nl"&gt;F&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="nl"&gt;E&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="nl"&gt;B&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="nl"&gt;E5&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="nl"&gt;E5&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="nl"&gt;DB&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="nl"&gt;A&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="nl"&gt;E8&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;7&lt;/span&gt;&lt;span class="nl"&gt;F&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;
&lt;span class="o"&gt;-----&lt;/span&gt;&lt;span class="k"&gt;BEGIN&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;CERTIFICATE&lt;/span&gt;&lt;span class="o"&gt;-----&lt;/span&gt;
&lt;span class="n"&gt;MIIDfjCCAuegAwIBAgIBBDANBgkqhkiG9w0BAQUFADAVMRMwEQYDVQQDDApNeSBU&lt;/span&gt;
&lt;span class="n"&gt;ZXN0IENBMB4XDTEzMDQyMDE5MjAxMFoXDTE0MDQyMDE5MjAxMFowgaYxCzAJBgNV&lt;/span&gt;
&lt;span class="n"&gt;BAYTAkdCMQ8wDQYDVQQIEwZMb25kb24xDzANBgNVBAcTBkxvbmRvbjEUMBIGA1UE&lt;/span&gt;
&lt;span class="n"&gt;ChMLRXhhbXBsZSBMdGQxHzAdBgNVBAsTFkNlcnRpZmljYXRlIEF1dG9tYXRpb24x&lt;/span&gt;
&lt;span class="n"&gt;GDAWBgNVBAMTD3d3dy5leGFtcGxlLmNvbTEkMCIGCSqGSIb3DQEJARMVeDUwOS1h&lt;/span&gt;
&lt;span class="n"&gt;dXRvQGV4YW1wbGUuY29tMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA&lt;/span&gt;
&lt;span class="n"&gt;v6N6WZIiwwuOcFIni9b7lEcbd&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;Djpe00TZ7BmB8dJa3pFZM3Le5MsUtswwIMe9Gp&lt;/span&gt;
&lt;span class="n"&gt;FyDNBImYb0ebTsOwGykqWg4qjG0&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;tNu0DARt9JX3SKeC31h9ShUt2XOL5ZpGqMlD&lt;/span&gt;
&lt;span class="n"&gt;WQY2qdKZnA0ge&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="n"&gt;vmV1UW2fyb1e0Wwyi&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="n"&gt;CgUKfZd6A3JWMd1TykVHZQJwt3xuTYiu&lt;/span&gt;
&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="n"&gt;wZbOj9OLlNqOFjEtnIstXgKTBhI3qs3ZujlQU6FEWdqghzwaPSXG1&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;tNQn6Ql1&lt;/span&gt;
&lt;span class="n"&gt;wKsnbflONlzQbjLdaItDRnYzj5KlYroXChjHtE4Y4f6KC&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;BhQlENfytSgGOC9W&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="n"&gt;K&lt;/span&gt;
&lt;span class="n"&gt;WtaAfIIg&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;E&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="n"&gt;YLHFa8QmqLwIDAQABo4HHMIHEMAkGA1UdEwQCMAAwHQYDVR0OBBYE&lt;/span&gt;
&lt;span class="n"&gt;FOuq7ztithiBI1Al05&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;OrAliIVV7MDcGCWCGSAGG&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="n"&gt;EIBDQQqFihSdWJ5L09wZW5T&lt;/span&gt;
&lt;span class="n"&gt;U0wvRWFTU0wgR2VuZXJhdGVkIENlcnRpZmljYXRlMD0GA1UdIwQ2MDSAFA6&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;VF54&lt;/span&gt;
&lt;span class="n"&gt;PUt7pkF5z9ZYUOOS7iDtoRmkFzAVMRMwEQYDVQQDDApNeSBUZXN0IENBggEAMAsG&lt;/span&gt;
&lt;span class="n"&gt;A1UdDwQEAwIFoDATBgNVHSUEDDAKBggrBgEFBQcDATANBgkqhkiG9w0BAQUFAAOB&lt;/span&gt;
&lt;span class="n"&gt;gQA73eaeESHnYeWjk8uOg5qq4VL&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="n"&gt;rLk&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="n"&gt;M&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;MB3rON4g6lUzBVBUzTEULU&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="n"&gt;ziGEnWw&lt;/span&gt;
&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="n"&gt;f8EO99GVPf1hAywcfycj2GskkPbg4JgBHFQ3EeQVYEBzQcKCLqboRaUsgXqpDlg&lt;/span&gt;
&lt;span class="n"&gt;OGd5BpT33Jh2E8u&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="n"&gt;G81WGhCScIVHpH1JwGyAkwvsnyokw&lt;/span&gt;&lt;span class="o"&gt;==&lt;/span&gt;
&lt;span class="o"&gt;-----&lt;/span&gt;&lt;span class="k"&gt;END&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;CERTIFICATE&lt;/span&gt;&lt;span class="o"&gt;-----&lt;/span&gt;

&lt;span class="n"&gt;Saved&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;OK&lt;/span&gt;
&lt;span class="ow"&gt;All&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;CSRs&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;processed&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Signed certificates are saved to the "certificates" data bag on the
Chef server.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;knife&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;search&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;certificates&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ss"&gt;&amp;quot;host:test-centos6.nat0.cryptocracy.com&amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;dn&lt;/span&gt;
&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;items&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;found&lt;/span&gt;

&lt;span class="nl"&gt;data_bag_item_certificates_80fc0fb9266db7b83f85850fa0e6548b6d70ee68c8b5b412f1deea6ebdef0404&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nl"&gt;dn&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;C&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;GB&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;ST&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;London&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;L&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;London&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;O&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;Example&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Ltd&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;OU&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;Certificate&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Automation&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;CN&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;www&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;example&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;com&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;emailAddress&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;x509&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;auto&lt;/span&gt;&lt;span class="nv"&gt;@example&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;com&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h3&gt;Installing the signed certificate&lt;/h3&gt;
&lt;p&gt;To update the node with our newly-issued certificate, we run
&lt;code&gt;chef-client&lt;/code&gt; once again.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;zts@test-centos6&lt;/span&gt;&lt;span class="o"&gt;]~%&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;sudo&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;chef&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;force&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;logger&lt;/span&gt;
&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;2013-04-20T19:36:45+00:00&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;INFO&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;***&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Chef&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;11.4.0&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;***&lt;/span&gt;
&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;2013-04-20T19:36:45+00:00&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;INFO&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Run&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;List&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;is&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;recipe[x509::example&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="err"&gt;]&lt;/span&gt;
&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;2013-04-20T19:36:45+00:00&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;INFO&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Run&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;List&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;expands&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;to&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;x509::example&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;
&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;2013-04-20T19:36:45+00:00&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;INFO&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Starting&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Chef&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Run&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;test&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;centos6&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;nat0&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;cryptocracy&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;com&lt;/span&gt;
&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;2013-04-20T19:36:45+00:00&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;INFO&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Running&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;start&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;handlers&lt;/span&gt;
&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;2013-04-20T19:36:45+00:00&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;INFO&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;Start&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;handlers&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;complete&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;
&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;2013-04-20T19:36:45+00:00&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;INFO&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Loading&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;cookbooks&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;vt-gpg, x509&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;
&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;2013-04-20T19:36:45+00:00&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;INFO&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Processing&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;chef_gem&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;eassl2&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;action&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;nothing&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nl"&gt;x509&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt;&lt;span class="k"&gt;default&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;line&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;25&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;2013-04-20T19:36:45+00:00&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;INFO&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Processing&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;chef_gem&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;eassl2&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;action&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;upgrade&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nl"&gt;x509&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt;&lt;span class="k"&gt;default&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;line&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;25&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;2013-04-20T19:36:45+00:00&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;INFO&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Processing&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;chef_gem&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;eassl2&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;action&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;nothing&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nl"&gt;x509&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt;&lt;span class="k"&gt;default&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;line&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;25&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;2013-04-20T19:36:45+00:00&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;INFO&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Processing&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;x509_certificate&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;www.example.com&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;action&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;create&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nl"&gt;x509&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt;&lt;span class="n"&gt;example&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;line&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;2013-04-20T19:36:45+00:00&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;INFO&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;installing&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;certificate&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;www&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;example&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;com&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;80&lt;/span&gt;&lt;span class="n"&gt;fc0fb9266db7b83f85850fa0e6548b6d70ee68c8b5b412f1deea6ebdef0404&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;2013-04-20T19:36:45+00:00&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;INFO&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Processing&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;file&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;/etc/ssl/www.example.com.cert&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;action&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;create&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nf"&gt;var&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;cache&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;chef&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;cookbooks&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;x509&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;providers&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;certificate&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;rb&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;line&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;2013-04-20T19:36:45+00:00&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;INFO&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;file&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;/etc/ssl/www.example.com.cert&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;backed&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;up&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;to&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nf"&gt;var&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;lib&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;chef&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;etc&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;ssl&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;www&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;example&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;com&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;cert&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;chef&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;20130420193645&lt;/span&gt;
&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;2013-04-20T19:36:45+00:00&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;INFO&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;file&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;/etc/ssl/www.example.com.cert&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;contents&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;updated&lt;/span&gt;
&lt;span class="n"&gt;v&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;2013-04-20T19:36:45+00:00&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;INFO&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Processing&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;file&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;/etc/ssl/www.example.com.key&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;action&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;nothing&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nf"&gt;var&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;cache&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;chef&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;cookbooks&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;x509&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;providers&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;certificate&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;rb&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;line&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;11&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;2013-04-20T19:36:45+00:00&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;INFO&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Chef&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Run&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;complete&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ow"&gt;in&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;0.351435563&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;seconds&lt;/span&gt;
&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;2013-04-20T19:36:45+00:00&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;INFO&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Running&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;report&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;handlers&lt;/span&gt;
&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;2013-04-20T19:36:45+00:00&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;INFO&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Report&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;handlers&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;complete&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;We can use &lt;code&gt;openssl&lt;/code&gt; to confirm that the certicate was signed by the
CA we requested:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;zts@test-centos6&lt;/span&gt;&lt;span class="o"&gt;]~%&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;openssl&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;x509&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="ow"&gt;in&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;etc&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;ssl&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;www&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;example&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;com&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;cert&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;issuer&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;head&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;
&lt;span class="n"&gt;issuer&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;CN&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;My&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Test&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;CA&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h2&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;The &lt;code&gt;x509&lt;/code&gt; cookbook takes some of the pain out of generating SSL
certificates, signing them with a private CA, and installing them on
your nodes.&lt;/p&gt;
&lt;p&gt;There's room for improvement, but I already find it useful.  Bug
reports, feature requests, and PRs will all be warmly received.&lt;/p&gt;</content><category term="Blog"/><category term="chef"/></entry><entry><title>HOWTO perlbrew a 32-bit Perl on a 64-bit Centos</title><link href="https://www.cryptocracy.com/blog/2012/09/16/HOWTO-perlbrew-a-32-bit-perl-on-a-64-bit-centos/" rel="alternate"/><published>2012-09-16T22:00:00+01:00</published><updated>2012-09-16T22:00:00+01:00</updated><author><name>Zachary Stevens</name></author><id>tag:www.cryptocracy.com,2012-09-16:/blog/2012/09/16/HOWTO-perlbrew-a-32-bit-perl-on-a-64-bit-centos/</id><summary type="html">&lt;p&gt;A step-by-step guide to building a 32-bit Perl 5.8 on 64-bit CentOS 6 using perlbrew, including the required 32-bit libraries and compiler flags.&lt;/p&gt;</summary><content type="html">&lt;p&gt;I recently needed to run 32-bit Perl 5.8 on a 64-bit Centos 6 system.
Initial research suggested that
&lt;a href="http://search.cpan.org/perldoc?App::perlbrew"&gt;perlbrew&lt;/a&gt; would be the easiest
way of achieving this, but I wasn't able to find a walkthrough.&lt;/p&gt;
&lt;p&gt;Here's what worked for me...&lt;/p&gt;
&lt;h2&gt;1. Install perlbrew&lt;/h2&gt;
&lt;p&gt;You'll need to install perlbrew from the CPAN, and it has a load of
dependencies.  The wonderful
&lt;a href="http://search.cpan.org/perldoc?App::cpanminus"&gt;App::cpanminus&lt;/a&gt; makes
this experience as painless as possible, so I installed it before
moving onto perlbrew itself.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;$&lt;span class="w"&gt; &lt;/span&gt;sudo&lt;span class="w"&gt; &lt;/span&gt;yum&lt;span class="w"&gt; &lt;/span&gt;install&lt;span class="w"&gt; &lt;/span&gt;perl-CPAN
$&lt;span class="w"&gt; &lt;/span&gt;sudo&lt;span class="w"&gt; &lt;/span&gt;cpan&lt;span class="w"&gt; &lt;/span&gt;App::cpanminus
$&lt;span class="w"&gt; &lt;/span&gt;sudo&lt;span class="w"&gt; &lt;/span&gt;cpanm&lt;span class="w"&gt; &lt;/span&gt;install&lt;span class="w"&gt; &lt;/span&gt;App::perlbrew
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h2&gt;1. Initialise perlbrew&lt;/h2&gt;
&lt;p&gt;Next, get perlbrew ready for use.  Pay attention to the output of the
&lt;code&gt;init&lt;/code&gt; step - it will direct you to make a change to your shell configuration.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;$&lt;span class="w"&gt; &lt;/span&gt;perlbrew&lt;span class="w"&gt; &lt;/span&gt;init
$&lt;span class="w"&gt; &lt;/span&gt;perlbrew&lt;span class="w"&gt; &lt;/span&gt;install-patchperl
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h2&gt;2. Install 32-bit Libraries&lt;/h2&gt;
&lt;p&gt;Installing these two packages was enough to build a 32-bit perl core.
If you're building additional XS modules against the 32-bit perl, they
may require other 32-bit libraries to be installed.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;$&lt;span class="w"&gt; &lt;/span&gt;sudo&lt;span class="w"&gt; &lt;/span&gt;yum&lt;span class="w"&gt; &lt;/span&gt;install&lt;span class="w"&gt; &lt;/span&gt;glibc-devel.i686&lt;span class="w"&gt; &lt;/span&gt;libgcc.i686
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h2&gt;3. Build A Perl&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;$&lt;span class="w"&gt; &lt;/span&gt;perlbrew&lt;span class="w"&gt; &lt;/span&gt;install&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;5&lt;/span&gt;.8.9&lt;span class="w"&gt; &lt;/span&gt;-Accflags&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;-m32 -march=i686&amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;-Aldflags&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;-m32 -march=i686&amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;-Alddlflags&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;-shared -m32 -march=i686&amp;quot;&lt;/span&gt;
Fetching&lt;span class="w"&gt; &lt;/span&gt;perl-5.8.9&lt;span class="w"&gt; &lt;/span&gt;as&lt;span class="w"&gt; &lt;/span&gt;/home/zts/perl5/perlbrew/dists/perl-5.8.9.tar.bz2
Installing&lt;span class="w"&gt; &lt;/span&gt;/home/zts/perl5/perlbrew/build/perl-5.8.9&lt;span class="w"&gt; &lt;/span&gt;into&lt;span class="w"&gt; &lt;/span&gt;~/perl5/perlbrew/perls/perl-5.8.9

This&lt;span class="w"&gt; &lt;/span&gt;could&lt;span class="w"&gt; &lt;/span&gt;take&lt;span class="w"&gt; &lt;/span&gt;a&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;while&lt;/span&gt;.&lt;span class="w"&gt; &lt;/span&gt;You&lt;span class="w"&gt; &lt;/span&gt;can&lt;span class="w"&gt; &lt;/span&gt;run&lt;span class="w"&gt; &lt;/span&gt;the&lt;span class="w"&gt; &lt;/span&gt;following&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;command&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;on&lt;span class="w"&gt; &lt;/span&gt;another&lt;span class="w"&gt; &lt;/span&gt;shell&lt;span class="w"&gt; &lt;/span&gt;to&lt;span class="w"&gt; &lt;/span&gt;track&lt;span class="w"&gt; &lt;/span&gt;the&lt;span class="w"&gt; &lt;/span&gt;status:

&lt;span class="w"&gt;  &lt;/span&gt;tail&lt;span class="w"&gt; &lt;/span&gt;-f&lt;span class="w"&gt; &lt;/span&gt;~/perl5/perlbrew/build.perl-5.8.9.log

perl-5.8.9&lt;span class="w"&gt; &lt;/span&gt;is&lt;span class="w"&gt; &lt;/span&gt;successfully&lt;span class="w"&gt; &lt;/span&gt;installed.
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;That's all there is to it, though the result isn't quite perfect.
While the above invocation builds a 32-bit perl, it doesn't override
the system's archname - so the resulting @INC looks like this:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nv"&gt;@INC&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;home&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;zts&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;perl5&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;perlbrew&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;perls&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;perl&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mf"&gt;5.8.9&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;lib&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mf"&gt;5.8.9&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;x86_64&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;linux&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;home&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;zts&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;perl5&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;perlbrew&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;perls&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;perl&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mf"&gt;5.8.9&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;lib&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mf"&gt;5.8.9&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;home&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;zts&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;perl5&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;perlbrew&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;perls&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;perl&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mf"&gt;5.8.9&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;lib&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;site_perl&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mf"&gt;5.8.9&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;x86_64&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;linux&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;home&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;zts&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;perl5&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;perlbrew&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;perls&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;perl&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mf"&gt;5.8.9&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;lib&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;site_perl&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mf"&gt;5.8.9&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;For my purposes, this is simply an aesthetic issue - the
x86_64-linux directories contain 32-bit shared objects - and I chose
not to spend any more time perfecting it.  If you happen to know which
option(s) I'm missing, please leave a comment below.&lt;/p&gt;</content><category term="Blog"/><category term="sysadmin"/></entry><entry><title>Cookbook Reusability In Practice</title><link href="https://www.cryptocracy.com/blog/2012/06/09/cookbook-reusability-in-practice/" rel="alternate"/><published>2012-06-09T22:35:00+01:00</published><updated>2012-06-09T22:35:00+01:00</updated><author><name>Zachary Stevens</name></author><id>tag:www.cryptocracy.com,2012-06-09:/blog/2012/06/09/cookbook-reusability-in-practice/</id><summary type="html">&lt;p&gt;A practical test of Chef cookbook reusability, attempting to provision Jenkins, Graphite, and Sensu from community cookbooks on Ubuntu 12.04.&lt;/p&gt;</summary><content type="html">&lt;p&gt;I recently attempted to use Chef to configure several VMs with
software I wanted to play with.  My goal only went as far as
provisioning a minimally useful instance of each application - it
didn't need to be production-ready, but it did need to start.&lt;/p&gt;
&lt;p&gt;The applications were:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="http://jenkins-ci.org/"&gt;Jenkins&lt;/a&gt;, a CI tool written in Java,&lt;/li&gt;
&lt;li&gt;&lt;a href="http://graphite.wikidot.com/"&gt;Graphite&lt;/a&gt;, graphing tool written in
   Python, and,&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.sonian.com/cloud-monitoring-sensu/"&gt;Sensu&lt;/a&gt;, a
   monitoring tool written in Ruby.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Additionally, Sensu requires:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="http://www.rabbitmq.com/"&gt;RabbitMQ&lt;/a&gt;, a message broker written in
 Erlang, and,&lt;/li&gt;
&lt;li&gt;&lt;a href="http://redis.io/"&gt;Redis&lt;/a&gt;, a key-value store written in C.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;None of the dependencies are particular esoteric in a modern
environment, though the variety seen here underscores the need for
good configuration management.  The guest OS was Ubuntu 12.04, as many
community-contributed Chef cookbooks prefer or require Ubuntu and I
wanted things to proceed as smoothly as possible.&lt;/p&gt;
&lt;h2&gt;Results&lt;/h2&gt;
&lt;h3&gt;Jenkins&lt;/h3&gt;
&lt;p&gt;My experience installing Jenkins was not without issues, but it came
closest to meeting my expectations.  Adding &lt;code&gt;recipe[jenkins]&lt;/code&gt; to the
run_list will also pull in &lt;code&gt;recipe[java::default]&lt;/code&gt;, which will install
openjdk unless configured otherwise using node attributes.  I used the
defaults.&lt;/p&gt;
&lt;p&gt;The first chef-client run failed with the following unhelpful error in
the Java cookbook:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;[Sat, 09 Jun 2012 17:27:41 +0000] ERROR: TypeError: ruby_block[update-java-alternatives] (java::openjdk line 43) had an error: TypeError: can&amp;#39;t convert nil into String
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Without fixing or changing anything, I ran chef-client again - this
second time, it completed without error, leaving Jenkins available on
port 8080.&lt;/p&gt;
&lt;h3&gt;Graphite&lt;/h3&gt;
&lt;p&gt;For the next VM, I added &lt;code&gt;recipe[graphite]&lt;/code&gt; to my run_list without
overriding any attributes - the README suggested that an override was
required on Ubuntu 11.10, but I decided to try my luck with the
defaults on 12.04.&lt;/p&gt;
&lt;p&gt;The graphite cookbook pulls in &lt;code&gt;recipe[python::default]&lt;/code&gt;, which is
currently broken on Chef 0.10.10 and later.  I had to patch my local
copy of the cookbook (see
&lt;a href="https://github.com/opscode-cookbooks/python/pull/13"&gt;this pull request&lt;/a&gt;
for the fix) before re-running chef-client.&lt;/p&gt;
&lt;p&gt;The second run completed without error, leaving Graphite running on
port 80.  But for the bug in the Python cookbook, this would have
worked on the first go, without any manual tweaks.&lt;/p&gt;
&lt;h3&gt;Sensu&lt;/h3&gt;
&lt;p&gt;Bringing up a VM to try out Sensu was a yak shaving saga.  The Sensu
cookbook tries to make the process easy by shipping example roles,
which show how to install and configure the tool in various ways.  To
simply install of the dependencies (Redis and RabbitMQ), recipes are
provided which wrap their respective cookbooks, configuring the
software for use by Sensu.&lt;/p&gt;
&lt;p&gt;The cookbook's docs specify where to get each of its cookbook
dependencies from, and even includes a Cheffile (for use with
librarian-chef) that will take care of it for you.  I downloaded the
dependencies by hand, and got the wrong version of the Redis cookbook
in the process.&lt;/p&gt;
&lt;p&gt;That's how I learned that the Redis cookbook on the community site
depends on metachef, which only works on Ruby 1.9 and is therefore off
limits to most people running Chef on the Ruby shipped with their OS.
That's pretty weak.  (The redis cookbook referred to by the
documentation does not depend on metachef)&lt;/p&gt;
&lt;p&gt;After that, I was blocked installing RabbitMQ as their website was
down, and stayed down for most of the four-day weekend the UK had for
the Queen's Silver Jubilee.&lt;/p&gt;
&lt;p&gt;Eventually, everything installed successfully and Sensu started, but
didn't appear to work as intended.  I'm still working on this, and
have yet to determine whether it's an error on my part.&lt;/p&gt;
&lt;h2&gt;Credit Where Due&lt;/h2&gt;
&lt;p&gt;Despite the problems described above, I want to sincerely thank
everyone who shared the code and cookbooks I'm using.  It sounds
ungrateful to complain when things don't quite work, given just how
much did work.  I'm bothered by this state of affairs, because I know
I'm not immune to it - the cookbooks I share work for me, but I'd like
them to work for everyone else.  I doubt they do, and I have no way of
knowing.&lt;/p&gt;
&lt;p&gt;Re-use in the large is a hard problem, and one that we need to solve
as a community.  We have not yet done so.  Until we do, individual
cookbook authors can only do so much.&lt;/p&gt;
&lt;h2&gt;A possible future&lt;/h2&gt;
&lt;p&gt;The perl community does a lot of work to support code re-use via
&lt;a href="http://www.cpan.org/"&gt;CPAN&lt;/a&gt;, the Comprehensive Perl Archive
Network.  CPAN is more than a package index - mirrors and testers are
key features.&lt;/p&gt;
&lt;p&gt;Like Chef, perl runs on many platforms, and many different releases
can be found in the wild.  When something goes wrong, it's valuable to
know whether it's only going wrong for you, or whether a given module
is known not to work on your class of system.&lt;/p&gt;
&lt;p&gt;CPAN Testers collates results of tests for every module across a broad
set of platforms and perl versions.  Here are two examples for
DBD::Pg:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="http://www.cpantesters.org/distro/D/DBD-Pg.html#DBD-Pg-2.19.2"&gt;Report list&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://matrix.cpantesters.org/?dist=DBD-Pg+2.19.2"&gt;Perl/Platform matrix&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;As a user, I can quickly find out whether a module is likely to work
on my system.  As a module author, I get rapid feedback when I screw
something up for a user on a platform I don't test on myself.&lt;/p&gt;
&lt;p&gt;We have little hope of promoting widespread use of shared cookbooks
until we can show that the work we share functions correctly across
the set of platforms we intend to support - and continues to do so as
both platforms and cookbooks evolve.&lt;/p&gt;</content><category term="Blog"/><category term="chef"/></entry><entry><title>IPsec/L2TP VPN server with Ubuntu 12.04</title><link href="https://www.cryptocracy.com/blog/2012/05/13/ipsec-slash-l2tp-vpn-server-with-ubuntu-precise/" rel="alternate"/><published>2012-05-13T17:30:00+01:00</published><updated>2012-05-13T17:30:00+01:00</updated><author><name>Zachary Stevens</name></author><id>tag:www.cryptocracy.com,2012-05-13:/blog/2012/05/13/ipsec-slash-l2tp-vpn-server-with-ubuntu-precise/</id><summary type="html">&lt;p&gt;Configuring an IPsec/L2TP VPN server on Ubuntu 12.04 using openswan and xl2tpd, with OS X client considerations for split DNS.&lt;/p&gt;</summary><content type="html">&lt;p&gt;In an earlier post describing my
&lt;a href="http://www.cryptocracy.com/blog/2012/05/07/setting-up-a-pptp-vpn/"&gt;PPTP VPN configuration&lt;/a&gt;,
one reason I gave for my use of the (relatively) insecure protocol was
that the IPsec alternative appeared to require building updated
versions of the software.  I'm delighted to report that that's no
longer the case.&lt;/p&gt;
&lt;p&gt;The versions of openswan and xl2tpd shipping with Ubuntu 12.04
(precise) are more recent than those mentioned in the elderly
walkthroughs I'd found, and have worked for the OS X clients I'm
using.&lt;/p&gt;
&lt;h2&gt;Simple Configuration&lt;/h2&gt;
&lt;p&gt;If you need instructions for creating a VPN using pre-shared
keys,
&lt;a href="http://blog.riobard.com/2010/04/30/l2tp-over-ipsec-ubuntu"&gt;this post by Riobard Zhan&lt;/a&gt;
is good despite overlooking the required firewall configuration.&lt;/p&gt;
&lt;p&gt;IPsec traffic can be permitted using the ufw tool:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;$&lt;span class="w"&gt; &lt;/span&gt;sudo&lt;span class="w"&gt; &lt;/span&gt;ufw&lt;span class="w"&gt; &lt;/span&gt;allow&lt;span class="w"&gt; &lt;/span&gt;proto&lt;span class="w"&gt; &lt;/span&gt;udp&lt;span class="w"&gt; &lt;/span&gt;from&lt;span class="w"&gt; &lt;/span&gt;any&lt;span class="w"&gt; &lt;/span&gt;to&lt;span class="w"&gt; &lt;/span&gt;any&lt;span class="w"&gt; &lt;/span&gt;port&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;500&lt;/span&gt;
Rule&lt;span class="w"&gt; &lt;/span&gt;added
$&lt;span class="w"&gt; &lt;/span&gt;sudo&lt;span class="w"&gt; &lt;/span&gt;ufw&lt;span class="w"&gt; &lt;/span&gt;allow&lt;span class="w"&gt; &lt;/span&gt;proto&lt;span class="w"&gt; &lt;/span&gt;udp&lt;span class="w"&gt; &lt;/span&gt;from&lt;span class="w"&gt; &lt;/span&gt;any&lt;span class="w"&gt; &lt;/span&gt;to&lt;span class="w"&gt; &lt;/span&gt;any&lt;span class="w"&gt; &lt;/span&gt;port&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;4500&lt;/span&gt;
Rule&lt;span class="w"&gt; &lt;/span&gt;added
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;L2TP is a little more tricky.  We only want to allow L2TP traffic that
has been secured by IPsec, which isn't a scenario that ufw(1)
supports.  The solution is to add a rule to the &lt;code&gt;ufw-before-input&lt;/code&gt; chain
by adding the following lines to /etc/ufw/before.rules.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="c1"&gt;# Allow L2TP only over IPSEC&lt;/span&gt;
-A&lt;span class="w"&gt; &lt;/span&gt;ufw-before-input&lt;span class="w"&gt; &lt;/span&gt;-m&lt;span class="w"&gt; &lt;/span&gt;policy&lt;span class="w"&gt; &lt;/span&gt;--dir&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;in&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;--pol&lt;span class="w"&gt; &lt;/span&gt;ipsec&lt;span class="w"&gt; &lt;/span&gt;-p&lt;span class="w"&gt; &lt;/span&gt;udp&lt;span class="w"&gt; &lt;/span&gt;--dport&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;1701&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;-j&lt;span class="w"&gt; &lt;/span&gt;ACCEPT
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Riobard's instructions disable ICMP redirects through the proc
filesystem, and do this on boot from rc.local.  I chose to use
sysctl instead:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;$&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;net.ipv4.conf.all.accept_redirects = 0&amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;sudo&lt;span class="w"&gt; &lt;/span&gt;tee&lt;span class="w"&gt; &lt;/span&gt;-a&lt;span class="w"&gt; &lt;/span&gt;/etc/sysctl.conf
$&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;net.ipv4.conf.all.send_redirects = 0&amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;sudo&lt;span class="w"&gt; &lt;/span&gt;tee&lt;span class="w"&gt; &lt;/span&gt;-a&lt;span class="w"&gt; &lt;/span&gt;/etc/sysctl.conf
$&lt;span class="w"&gt; &lt;/span&gt;sudo&lt;span class="w"&gt; &lt;/span&gt;sysctl&lt;span class="w"&gt; &lt;/span&gt;-p
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h2&gt;Advanced Configuration&lt;/h2&gt;
&lt;p&gt;&lt;a href="http://rootmanager.com/ubuntu-ipsec-l2tp-windows-domain-auth/setting-up-openswan-xl2tpd-with-native-windows-clients-lucid.html"&gt;Setting Up an IPsec L2TP VPN Server on Ubuntu&lt;/a&gt;
gives a very thorough walkthrough for those looking to support Windows
clients with certificates for IPsec and user authentication against
Active Directory.  Each facet of the configuration is discussed
separately, so it's useful even if (like me) you aren't looking to use
AD.&lt;/p&gt;
&lt;h2&gt;OS X and Split DNS&lt;/h2&gt;
&lt;p&gt;It turns out that OS X configures routing for IPsec/L2TP VPNs in the
same way as PPTP, so I'm still unable to change my DNS resolver
configuration - but not my default route - when the VPN connection is
established.  I've done a little more investigation, but it looks as
though this "split DNS" configuration is only available for
Cisco-flavoured IPsec VPNs.&lt;/p&gt;
&lt;p&gt;Fortunately, the OS X resolver can be configured on a per-domain
basis.  A near-enough solution changes my domain so that the VPN's
nameserver is tried initially, before falling back to my local
resolver after a shortened request timeout.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;options&lt;span class="w"&gt; &lt;/span&gt;timeout:1
nameserver&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;192&lt;/span&gt;.168.42.1
nameserver&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;192&lt;/span&gt;.168.1.1
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;When the VPN is disconnected, this configuration occasionally delays
lookups for records in my public-facing zone.  I could live with the
inconvenience, but it's an "infrastructure smell" that I'd rather not
have.&lt;/p&gt;
&lt;p&gt;A better solution is to use a different domain for the hosts that
will only be accessible when I'm on the VPN.&lt;/p&gt;</content><category term="Blog"/><category term="sysadmin"/></entry><entry><title>Bootstrapping Chef with ubuntu-vm-builder</title><link href="https://www.cryptocracy.com/blog/2012/05/12/bootstrapping-chef/" rel="alternate"/><published>2012-05-12T20:00:00+01:00</published><updated>2012-05-12T20:00:00+01:00</updated><author><name>Zachary Stevens</name></author><id>tag:www.cryptocracy.com,2012-05-12:/blog/2012/05/12/bootstrapping-chef/</id><summary type="html">&lt;p&gt;Using ubuntu-vm-builder to create KVM guests with Chef pre-installed, going from zero to a fully registered Chef client in under 2 minutes.&lt;/p&gt;</summary><content type="html">&lt;p&gt;It's very easy to configure a machine as a KVM host these days.
Modern releases of Ubuntu and Centos both offer simple installation
methods that provide a useful system with minimal configuration.&lt;/p&gt;
&lt;p&gt;Creating guests is a different story.  A number of good tools are
available, supporting a huge variety of installation scenarios.  While
it's reassuring to know you won't be limited by your tools, it can be
a frustrating experience when you're just getting started.&lt;/p&gt;
&lt;p&gt;This post shows how &lt;code&gt;ubuntu-vm-builder&lt;/code&gt; can be used to go from zero to
fully-installed Chef client in under 2 minutes.&lt;/p&gt;
&lt;h1&gt;Installing KVM&lt;/h1&gt;
&lt;p&gt;Configuring the server as a KVM host is pretty straightforward.
Ubuntu's
&lt;a href="https://help.ubuntu.com/community/KVM/Installation"&gt;KVM documentation&lt;/a&gt;
is well-written, and a good place to start.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;$&lt;span class="w"&gt; &lt;/span&gt;sudo&lt;span class="w"&gt; &lt;/span&gt;apt-get&lt;span class="w"&gt; &lt;/span&gt;install&lt;span class="w"&gt; &lt;/span&gt;qemu-kvm&lt;span class="w"&gt; &lt;/span&gt;libvirt-bin&lt;span class="w"&gt; &lt;/span&gt;ubuntu-vm-builder
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;By default, libvirt will create a host-only NAT network, with DHCP
service, for guests to use.  All my guests will be using a network
I've created manually, so I've removed the default one.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;$&lt;span class="w"&gt; &lt;/span&gt;virsh&lt;span class="w"&gt; &lt;/span&gt;net-destroy&lt;span class="w"&gt; &lt;/span&gt;default
Network&lt;span class="w"&gt; &lt;/span&gt;default&lt;span class="w"&gt; &lt;/span&gt;destroyed

$&lt;span class="w"&gt; &lt;/span&gt;virsh&lt;span class="w"&gt; &lt;/span&gt;net-undefine&lt;span class="w"&gt; &lt;/span&gt;default
Network&lt;span class="w"&gt; &lt;/span&gt;default&lt;span class="w"&gt; &lt;/span&gt;has&lt;span class="w"&gt; &lt;/span&gt;been&lt;span class="w"&gt; &lt;/span&gt;undefined
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h2&gt;(Optional) Install apt-cacher-ng&lt;/h2&gt;
&lt;p&gt;Using apt-cacher-ng can speed up guest VM creation by keeping required
packages on the host.
&lt;a href="http://ubuntuforums.org/showthread.php?t=564301"&gt;This forum post&lt;/a&gt;
provides a good walkthrough.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;$&lt;span class="w"&gt; &lt;/span&gt;sudo&lt;span class="w"&gt; &lt;/span&gt;apt-get&lt;span class="w"&gt; &lt;/span&gt;install&lt;span class="w"&gt; &lt;/span&gt;apt-cacher-ng
$&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;Acquire::http::Proxy &amp;quot;http://localhost:3142&amp;quot;;&amp;#39;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;sudo&lt;span class="w"&gt; &lt;/span&gt;tee&lt;span class="w"&gt; &lt;/span&gt;/etc/apt/apt.conf.d/01proxy
$&lt;span class="w"&gt; &lt;/span&gt;sudo&lt;span class="w"&gt; &lt;/span&gt;ufw&lt;span class="w"&gt; &lt;/span&gt;allow&lt;span class="w"&gt; &lt;/span&gt;proto&lt;span class="w"&gt; &lt;/span&gt;tcp&lt;span class="w"&gt; &lt;/span&gt;from&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;192&lt;/span&gt;.168.42.0/24&lt;span class="w"&gt; &lt;/span&gt;to&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;192&lt;/span&gt;.168.42.1&lt;span class="w"&gt; &lt;/span&gt;port&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;3142&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h1&gt;Configuring ubuntu-vm-builder&lt;/h1&gt;
&lt;p&gt;The easiest way of creating Ubuntu guests appears to be the
&lt;code&gt;ubuntu-vm-builder&lt;/code&gt; tool.  The
&lt;a href="https://help.ubuntu.com/community/JeOSVMBuilder"&gt;wiki documentation&lt;/a&gt;
is decent, and the command-line help is comprehensive - see
&lt;code&gt;ubuntu-vm-builder kvm --help&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;My &lt;code&gt;~/.vmbuilder.cfg&lt;/code&gt; sets the options that will be used for most (or
all) of my Ubuntu guests.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="k"&gt;[DEFAULT]&lt;/span&gt;
&lt;span class="na"&gt;domain&lt;/span&gt;&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;cryptocracy.com&lt;/span&gt;
&lt;span class="na"&gt;gw&lt;/span&gt;&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;192.168.42.1&lt;/span&gt;
&lt;span class="na"&gt;dns&lt;/span&gt;&lt;span class="w"&gt;       &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;192.168.42.1&lt;/span&gt;
&lt;span class="na"&gt;firstboot&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;/home/zts/.vmbuilder/first-boot.sh&lt;/span&gt;
&lt;span class="na"&gt;copy&lt;/span&gt;&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;/home/zts/.vmbuilder/copy-files&lt;/span&gt;

&lt;span class="k"&gt;[ubuntu]&lt;/span&gt;
&lt;span class="na"&gt;proxy&lt;/span&gt;&lt;span class="w"&gt;           &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;http://gateway.cryptocracy.com:3142&lt;/span&gt;
&lt;span class="na"&gt;mirror&lt;/span&gt;&lt;span class="w"&gt;          &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;http://mirror.hetzner.de/ubuntu/packages&lt;/span&gt;
&lt;span class="na"&gt;security-mirror&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;http://mirror.hetzner.de/ubuntu/security&lt;/span&gt;
&lt;span class="na"&gt;suite&lt;/span&gt;&lt;span class="w"&gt;           &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;precise&lt;/span&gt;
&lt;span class="na"&gt;components&lt;/span&gt;&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;main, universe&lt;/span&gt;
&lt;span class="na"&gt;addpkg&lt;/span&gt;&lt;span class="w"&gt;          &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;openssh-server, acpid, chef&lt;/span&gt;

&lt;span class="k"&gt;[kvm]&lt;/span&gt;
&lt;span class="na"&gt;libvirt&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;qemu:///system&lt;/span&gt;
&lt;span class="na"&gt;bridge&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;nat0&lt;/span&gt;
&lt;span class="na"&gt;mem&lt;/span&gt;&lt;span class="w"&gt;     &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;1024&lt;/span&gt;
&lt;span class="na"&gt;cpus&lt;/span&gt;&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;2&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The initial build process happens in a RAM disk, which means that
package installation is much faster than inside the guest.&lt;/p&gt;
&lt;p&gt;As my guests will all be running Chef, I want to install the required
packages during the initial build.  This requires enabling an
additional package repository, which can be achieved by customising
the APT sources template used by vmbuilder.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="x"&gt;deb &lt;/span&gt;&lt;span class="cp"&gt;$&lt;/span&gt;&lt;span class="n"&gt;mirror&lt;/span&gt;&lt;span class="x"&gt; &lt;/span&gt;&lt;span class="cp"&gt;$&lt;/span&gt;&lt;span class="n"&gt;suite&lt;/span&gt;&lt;span class="x"&gt; &lt;/span&gt;&lt;span class="cp"&gt;#slurp&lt;/span&gt;
&lt;span class="cp"&gt;#echo&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39; &amp;#39;&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="cp"&gt;$&lt;/span&gt;&lt;span class="n"&gt;components&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="x"&gt;deb &lt;/span&gt;&lt;span class="cp"&gt;$&lt;/span&gt;&lt;span class="n"&gt;updates_mirror&lt;/span&gt;&lt;span class="x"&gt; &lt;/span&gt;&lt;span class="cp"&gt;$&lt;/span&gt;&lt;span class="n"&gt;suite&lt;/span&gt;&lt;span class="x"&gt;-updates &lt;/span&gt;&lt;span class="cp"&gt;#slurp&lt;/span&gt;
&lt;span class="cp"&gt;#echo&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39; &amp;#39;&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="cp"&gt;$&lt;/span&gt;&lt;span class="n"&gt;components&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="x"&gt;deb &lt;/span&gt;&lt;span class="cp"&gt;$&lt;/span&gt;&lt;span class="n"&gt;security_mirror&lt;/span&gt;&lt;span class="x"&gt; &lt;/span&gt;&lt;span class="cp"&gt;$&lt;/span&gt;&lt;span class="n"&gt;suite&lt;/span&gt;&lt;span class="x"&gt;-security &lt;/span&gt;&lt;span class="cp"&gt;#slurp&lt;/span&gt;
&lt;span class="cp"&gt;#echo&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39; &amp;#39;&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="cp"&gt;$&lt;/span&gt;&lt;span class="n"&gt;components&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="cp"&gt;#if&lt;/span&gt; &lt;span class="cp"&gt;$&lt;/span&gt;&lt;span class="n"&gt;ppa&lt;/span&gt;
&lt;span class="cp"&gt;#for&lt;/span&gt; &lt;span class="cp"&gt;$&lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="cp"&gt;$&lt;/span&gt;&lt;span class="n"&gt;ppa&lt;/span&gt;
&lt;span class="x"&gt;deb http://ppa.launchpad.net/$p/ubuntu &lt;/span&gt;&lt;span class="cp"&gt;$&lt;/span&gt;&lt;span class="n"&gt;suite&lt;/span&gt;&lt;span class="x"&gt; main&lt;/span&gt;

&lt;span class="cp"&gt;#end for&lt;/span&gt;
&lt;span class="cp"&gt;#end if&lt;/span&gt;

&lt;span class="x"&gt;# The Opscode repository, for Chef&lt;/span&gt;
&lt;span class="x"&gt;deb http://apt.opscode.com/ precise-0.10 main&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;For the new VM to register as a Chef client, it needs my validation
key.  The &lt;code&gt;copy&lt;/code&gt; option in .vmbuilder.cfg lists files on the host to
install in the guest.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;/home/zts/.chef/validation.pem /etc/chef/validation.pem
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Finally, we need a script to run when the guest first boots.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="err"&gt;#&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;Fix&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;locale&lt;/span&gt;
&lt;span class="nt"&gt;echo&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;LANGUAGE=&amp;quot;en_US.UTF-8&amp;quot;&amp;#39;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nt"&gt;etc&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nt"&gt;default&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nt"&gt;locale&lt;/span&gt;
&lt;span class="nt"&gt;echo&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;LC_ALL=&amp;quot;en_US.UTF-8&amp;quot;&amp;#39;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nt"&gt;etc&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nt"&gt;default&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nt"&gt;locale&lt;/span&gt;

&lt;span class="err"&gt;#&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;Configure&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;guest&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;to&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;use&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;the&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;host&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;s apt-cacher-ng&lt;/span&gt;
&lt;span class="s1"&gt;echo &amp;#39;&lt;/span&gt;&lt;span class="nt"&gt;Acquire&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nd"&gt;http&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nd"&gt;Proxy&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;http://gateway.cryptocracy.com:3142&amp;quot;&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;&lt;span class="err"&gt;&amp;#39;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nt"&gt;etc&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nt"&gt;apt&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nt"&gt;apt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;conf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;d&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nt"&gt;01proxy&lt;/span&gt;

&lt;span class="err"&gt;#&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;Configure&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;and&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;start&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;chef-client&lt;/span&gt;
&lt;span class="nt"&gt;echo&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;chef chef/chef_server_url string http://chef.cryptocracy.com:4000&amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;debconf-set-selections&lt;/span&gt;
&lt;span class="nt"&gt;dpkg-reconfigure&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-u&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;chef&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h1&gt;Creating a Guest&lt;/h1&gt;
&lt;p&gt;At this point, we're ready to create guests.  The required steps are:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Create a volume for the guest's disk.&lt;/li&gt;
&lt;li&gt;Run ubuntu-vm-builder, passing a hostname and IP address along with
the path to the volume.&lt;/li&gt;
&lt;li&gt;Start the guest.&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;$&lt;span class="w"&gt; &lt;/span&gt;sudo&lt;span class="w"&gt; &lt;/span&gt;lvcreate&lt;span class="w"&gt; &lt;/span&gt;-L&lt;span class="w"&gt; &lt;/span&gt;5G&lt;span class="w"&gt; &lt;/span&gt;-n&lt;span class="w"&gt; &lt;/span&gt;guest0&lt;span class="w"&gt; &lt;/span&gt;vg0
&lt;span class="w"&gt;  &lt;/span&gt;Logical&lt;span class="w"&gt; &lt;/span&gt;volume&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;guest0&amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;created
$&lt;span class="w"&gt; &lt;/span&gt;sudo&lt;span class="w"&gt; &lt;/span&gt;ubuntu-vm-builder&lt;span class="w"&gt; &lt;/span&gt;kvm&lt;span class="w"&gt; &lt;/span&gt;-o&lt;span class="w"&gt; &lt;/span&gt;--tmpfs&lt;span class="w"&gt; &lt;/span&gt;-&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="w"&gt;         &lt;/span&gt;--raw&lt;span class="w"&gt; &lt;/span&gt;/dev/mapper/vg0-guest0&lt;span class="w"&gt;     &lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="w"&gt;         &lt;/span&gt;--hostname&lt;span class="w"&gt; &lt;/span&gt;guest0&lt;span class="w"&gt;                &lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="w"&gt;         &lt;/span&gt;--ip&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;192&lt;/span&gt;.168.42.3
&lt;span class="m"&gt;2012&lt;/span&gt;-05-12&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;18&lt;/span&gt;:08:33,777&lt;span class="w"&gt; &lt;/span&gt;INFO&lt;span class="w"&gt;    &lt;/span&gt;:&lt;span class="w"&gt; &lt;/span&gt;Mounting&lt;span class="w"&gt; &lt;/span&gt;tmpfs&lt;span class="w"&gt; &lt;/span&gt;under&lt;span class="w"&gt; &lt;/span&gt;/tmp/tmpLRgUKMtmpfs
&lt;span class="m"&gt;2012&lt;/span&gt;-05-12&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;18&lt;/span&gt;:08:33,810&lt;span class="w"&gt; &lt;/span&gt;INFO&lt;span class="w"&gt;    &lt;/span&gt;:&lt;span class="w"&gt; &lt;/span&gt;Calling&lt;span class="w"&gt; &lt;/span&gt;hook:&lt;span class="w"&gt; &lt;/span&gt;preflight_check
&lt;span class="m"&gt;2012&lt;/span&gt;-05-12&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;18&lt;/span&gt;:08:33,814&lt;span class="w"&gt; &lt;/span&gt;INFO&lt;span class="w"&gt;    &lt;/span&gt;:&lt;span class="w"&gt; &lt;/span&gt;Calling&lt;span class="w"&gt; &lt;/span&gt;hook:&lt;span class="w"&gt; &lt;/span&gt;set_defaults
&lt;span class="m"&gt;2012&lt;/span&gt;-05-12&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;18&lt;/span&gt;:08:33,814&lt;span class="w"&gt; &lt;/span&gt;INFO&lt;span class="w"&gt;    &lt;/span&gt;:&lt;span class="w"&gt; &lt;/span&gt;Calling&lt;span class="w"&gt; &lt;/span&gt;hook:&lt;span class="w"&gt; &lt;/span&gt;bootstrap
&lt;span class="m"&gt;2012&lt;/span&gt;-05-12&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;18&lt;/span&gt;:08:55,343&lt;span class="w"&gt; &lt;/span&gt;INFO&lt;span class="w"&gt;    &lt;/span&gt;:&lt;span class="w"&gt; &lt;/span&gt;Calling&lt;span class="w"&gt; &lt;/span&gt;hook:&lt;span class="w"&gt; &lt;/span&gt;configure_os
&lt;span class="m"&gt;2012&lt;/span&gt;-05-12&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;18&lt;/span&gt;:09:00,374&lt;span class="w"&gt; &lt;/span&gt;INFO&lt;span class="w"&gt;    &lt;/span&gt;:&lt;span class="w"&gt; &lt;/span&gt;W:&lt;span class="w"&gt; &lt;/span&gt;GPG&lt;span class="w"&gt; &lt;/span&gt;error:&lt;span class="w"&gt; &lt;/span&gt;http://apt.opscode.com&lt;span class="w"&gt; &lt;/span&gt;precise-0.10&lt;span class="w"&gt; &lt;/span&gt;Release:&lt;span class="w"&gt; &lt;/span&gt;The&lt;span class="w"&gt; &lt;/span&gt;following&lt;span class="w"&gt; &lt;/span&gt;signatures&lt;span class="w"&gt; &lt;/span&gt;couldn&lt;span class="err"&gt;&amp;#39;&lt;/span&gt;t&lt;span class="w"&gt; &lt;/span&gt;be&lt;span class="w"&gt; &lt;/span&gt;verified&lt;span class="w"&gt; &lt;/span&gt;because&lt;span class="w"&gt; &lt;/span&gt;the&lt;span class="w"&gt; &lt;/span&gt;p
ublic&lt;span class="w"&gt; &lt;/span&gt;key&lt;span class="w"&gt; &lt;/span&gt;is&lt;span class="w"&gt; &lt;/span&gt;not&lt;span class="w"&gt; &lt;/span&gt;available:&lt;span class="w"&gt; &lt;/span&gt;NO_PUBKEY&lt;span class="w"&gt; &lt;/span&gt;2940ABA983EF826A
Extracting&lt;span class="w"&gt; &lt;/span&gt;templates&lt;span class="w"&gt; &lt;/span&gt;from&lt;span class="w"&gt; &lt;/span&gt;packages:&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;100&lt;/span&gt;%
.
.&lt;span class="w"&gt; &lt;/span&gt;output&lt;span class="w"&gt; &lt;/span&gt;elided
.
&lt;span class="m"&gt;2012&lt;/span&gt;-05-12&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;18&lt;/span&gt;:09:59,940&lt;span class="w"&gt; &lt;/span&gt;INFO&lt;span class="w"&gt;    &lt;/span&gt;:&lt;span class="w"&gt; &lt;/span&gt;Calling&lt;span class="w"&gt; &lt;/span&gt;hook:&lt;span class="w"&gt; &lt;/span&gt;post_install
&lt;span class="m"&gt;2012&lt;/span&gt;-05-12&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;18&lt;/span&gt;:09:59,941&lt;span class="w"&gt; &lt;/span&gt;INFO&lt;span class="w"&gt;    &lt;/span&gt;:&lt;span class="w"&gt; &lt;/span&gt;Copying&lt;span class="w"&gt; &lt;/span&gt;files&lt;span class="w"&gt; &lt;/span&gt;specified&lt;span class="w"&gt; &lt;/span&gt;by&lt;span class="w"&gt; &lt;/span&gt;copy&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;in&lt;/span&gt;:&lt;span class="w"&gt; &lt;/span&gt;/home/zts/.vmbuilder/copy-files
&lt;span class="m"&gt;2012&lt;/span&gt;-05-12&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;18&lt;/span&gt;:09:59,948&lt;span class="w"&gt; &lt;/span&gt;INFO&lt;span class="w"&gt;    &lt;/span&gt;:&lt;span class="w"&gt; &lt;/span&gt;Calling&lt;span class="w"&gt; &lt;/span&gt;hook:&lt;span class="w"&gt; &lt;/span&gt;unmount_partitions
&lt;span class="m"&gt;2012&lt;/span&gt;-05-12&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;18&lt;/span&gt;:09:59,948&lt;span class="w"&gt; &lt;/span&gt;INFO&lt;span class="w"&gt;    &lt;/span&gt;:&lt;span class="w"&gt; &lt;/span&gt;Unmounting&lt;span class="w"&gt; &lt;/span&gt;target&lt;span class="w"&gt; &lt;/span&gt;filesystem
&lt;span class="m"&gt;2012&lt;/span&gt;-05-12&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;18&lt;/span&gt;:10:03,713&lt;span class="w"&gt; &lt;/span&gt;INFO&lt;span class="w"&gt;    &lt;/span&gt;:&lt;span class="w"&gt; &lt;/span&gt;Calling&lt;span class="w"&gt; &lt;/span&gt;hook:&lt;span class="w"&gt; &lt;/span&gt;convert
&lt;span class="m"&gt;2012&lt;/span&gt;-05-12&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;18&lt;/span&gt;:10:03,714&lt;span class="w"&gt; &lt;/span&gt;INFO&lt;span class="w"&gt;    &lt;/span&gt;:&lt;span class="w"&gt; &lt;/span&gt;Calling&lt;span class="w"&gt; &lt;/span&gt;hook:&lt;span class="w"&gt; &lt;/span&gt;fix_ownership
&lt;span class="m"&gt;2012&lt;/span&gt;-05-12&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;18&lt;/span&gt;:10:03,715&lt;span class="w"&gt; &lt;/span&gt;INFO&lt;span class="w"&gt;    &lt;/span&gt;:&lt;span class="w"&gt; &lt;/span&gt;Calling&lt;span class="w"&gt; &lt;/span&gt;hook:&lt;span class="w"&gt; &lt;/span&gt;deploy
&lt;span class="m"&gt;2012&lt;/span&gt;-05-12&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;18&lt;/span&gt;:10:04,140&lt;span class="w"&gt; &lt;/span&gt;INFO&lt;span class="w"&gt;    &lt;/span&gt;:&lt;span class="w"&gt; &lt;/span&gt;Unmounting&lt;span class="w"&gt; &lt;/span&gt;tmpfs&lt;span class="w"&gt; &lt;/span&gt;from&lt;span class="w"&gt; &lt;/span&gt;/tmp/tmpLRgUKMtmpfs
$&lt;span class="w"&gt; &lt;/span&gt;virsh&lt;span class="w"&gt; &lt;/span&gt;start&lt;span class="w"&gt; &lt;/span&gt;guest0
Domain&lt;span class="w"&gt; &lt;/span&gt;guest0&lt;span class="w"&gt; &lt;/span&gt;started
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;After waiting a moment for the guest to boot, we can check that it has
registered itself with the Chef server:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;$&lt;span class="w"&gt; &lt;/span&gt;knife&lt;span class="w"&gt; &lt;/span&gt;node&lt;span class="w"&gt; &lt;/span&gt;show&lt;span class="w"&gt; &lt;/span&gt;guest0.cryptocracy.com
Node&lt;span class="w"&gt; &lt;/span&gt;Name:&lt;span class="w"&gt;   &lt;/span&gt;guest0.cryptocracy.com
Environment:&lt;span class="w"&gt; &lt;/span&gt;_default
FQDN:&lt;span class="w"&gt;        &lt;/span&gt;guest0.cryptocracy.com
IP:&lt;span class="w"&gt;          &lt;/span&gt;&lt;span class="m"&gt;192&lt;/span&gt;.168.42.3
Run&lt;span class="w"&gt; &lt;/span&gt;List:
Roles:
Recipes:
Platform:&lt;span class="w"&gt;    &lt;/span&gt;ubuntu&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;12&lt;/span&gt;.04
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Voila!&lt;/p&gt;</content><category term="Blog"/><category term="chef"/></entry><entry><title>Setting up a PPTP VPN</title><link href="https://www.cryptocracy.com/blog/2012/05/07/setting-up-a-pptp-vpn/" rel="alternate"/><published>2012-05-07T23:30:00+01:00</published><updated>2012-05-07T23:30:00+01:00</updated><author><name>Zachary Stevens</name></author><id>tag:www.cryptocracy.com,2012-05-07:/blog/2012/05/07/setting-up-a-pptp-vpn/</id><summary type="html">&lt;p&gt;Configuring a PPTP VPN on Ubuntu with dnsmasq and pptpd, including workarounds for OS X routing and DNS issues.&lt;/p&gt;</summary><content type="html">&lt;p&gt;First things first: PPTP, as a protocol, has a number of serious
security issues.  As a general rule, don't use it.  I'm aware of the
risks, and am accepting them for this implementation.&lt;/p&gt;
&lt;p&gt;PPTP's main advantage is that it's very easy to configure.  I briefly
investigated the state of IPsec/L2TP, and found a lot of advice to
build things from source because the distro packaged versions are too
old.  That's fine advice, but I wanted to get something started
quickly.  Once I've built a build box, I'll be revisiting this decision.&lt;/p&gt;
&lt;h2&gt;dnsmasq&lt;/h2&gt;
&lt;p&gt;Dnsmasq is a forwarding resolver that also answers queries based on
the contents of &lt;code&gt;/etc/hosts&lt;/code&gt;.  This is a simple way of providing
resolvable names for VM guests, and it seemed appropriate to use it
for the VPN.&lt;/p&gt;
&lt;p&gt;The default configuration is a good starting point.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;# apt-get install dnsmasq
# ufw allow from 192.168.42.0/24 to 192.168.42.1 port 53
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h2&gt;pptpd&lt;/h2&gt;
&lt;p&gt;The default configuration installed by &lt;code&gt;pptpd&lt;/code&gt; only needs a couple of
customisations, and the creation of a password file.&lt;/p&gt;
&lt;p&gt;Install the package:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;apt-get install pptpd
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Update &lt;code&gt;/etc/pptpd.conf&lt;/code&gt; to specify local and remote addresses.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;localip 192.168.42.2
remoteip 192.168.42.250
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The &lt;code&gt;localip&lt;/code&gt; will be assigned to the &lt;code&gt;ppp0&lt;/code&gt; interface created by
pptpd.  The &lt;code&gt;remoteip&lt;/code&gt; value can specify a range of addresses; as I'm
only supporting a single client, I've only listed one.&lt;/p&gt;
&lt;p&gt;(Optionally) update &lt;code&gt;/etc/ppp/pptpd-options&lt;/code&gt; to return the address where dnsmasq is listening.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;ms-dns 192.168.42.1
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Use a long, random string for the password.  Specifying the IP address
is optional - an asterisk would have the same effect here.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="err"&gt;#&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;Secrets&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;authentication&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;using&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;CHAP&lt;/span&gt;
&lt;span class="err"&gt;#&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;client&lt;/span&gt;&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nx"&gt;server&lt;/span&gt;&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nx"&gt;secret&lt;/span&gt;&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="nx"&gt;IP&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;addresses&lt;/span&gt;
&lt;span class="nx"&gt;username&lt;/span&gt;&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nx"&gt;pptpd&lt;/span&gt;&lt;span class="w"&gt;     &lt;/span&gt;&lt;span class="nx"&gt;password&lt;/span&gt;&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="m m-Double"&gt;192.168.42.250&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Open the firewall and start the service:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;ufw allow 1723
service pptpd start
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;I read several HOWTO's when setting this up, but none was quite what I
needed.  I imagine that others will have the same problem with this
one, so I'll recommend
&lt;a href="http://manpages.ubuntu.com/manpages/precise/man5/pptpd.conf.5.html"&gt;the pptpd manpage&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;OS X VPN client&lt;/h2&gt;
&lt;p&gt;At that point, everything was ready to connect the client.  Not
coincidentally, that's also the point where frustrations emerged.&lt;/p&gt;
&lt;p&gt;The basic OS X configuration is simple - add a new VPN connection in
Network Preferences, enter address and authentication details, and hit
Connect.  I did that, the connection came up, and I was able to ping
other hosts on the NAT network (192.168.42.0/24).&lt;/p&gt;
&lt;p&gt;However, the resolver configuration hadn't been updated with the
nameserver specified by PPP.  It appears that this is governed by the
order of the connections in Network Preferences - the resolvers
specified by the first active connection will be used.&lt;/p&gt;
&lt;p&gt;After re-ordering the connections to place the VPN first, my client
started resolving via the dnsmasq server.  This was good.&lt;/p&gt;
&lt;p&gt;Unfortunately, it now also changed my default route to point over the VPN.
This was less good.&lt;/p&gt;
&lt;p&gt;Beyond the fact that it wasn't necessary (and slowed down my web
browsing), hitting Google via the VPN gave me the Russian language
page.&lt;/p&gt;
&lt;p&gt;The Advanced settings for the VPN connection have a checkbox, "Send
all traffic over VPN connection".  It turns out that OS X will create
a default route to the connection whether or not this is set - it
merely increases the routes priority.  ie, if the VPN is first in the
list of connections, it is already at the highest priority and the
checkbox has no practical effect.&lt;/p&gt;
&lt;h2&gt;The Current, Grudging Solution&lt;/h2&gt;
&lt;p&gt;A
&lt;a href="http://superuser.com/questions/4904/how-to-selectively-route-network-traffic-through-vpn-on-mac-os-x-leopard"&gt;post on SuperUser&lt;/a&gt;
offered an AppleScript to connect a VPN, then adjust routing.  My
slightly tweaked version looks like this:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="k"&gt;tell&lt;/span&gt; &lt;span class="nb"&gt;application&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;System Events&amp;quot;&lt;/span&gt;
    &lt;span class="k"&gt;tell&lt;/span&gt; &lt;span class="nv"&gt;network&lt;/span&gt; &lt;span class="nv"&gt;preferences&lt;/span&gt;
        &lt;span class="k"&gt;tell&lt;/span&gt; &lt;span class="nv"&gt;current&lt;/span&gt; &lt;span class="na"&gt;location&lt;/span&gt;
            &lt;span class="k"&gt;tell&lt;/span&gt; &lt;span class="nv"&gt;service&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;My VPN&amp;quot;&lt;/span&gt;
                &lt;span class="nv"&gt;connect&lt;/span&gt;
                &lt;span class="k"&gt;tell&lt;/span&gt; &lt;span class="nv"&gt;current&lt;/span&gt; &lt;span class="na"&gt;configuration&lt;/span&gt;
                    &lt;span class="k"&gt;repeat&lt;/span&gt; &lt;span class="k"&gt;until&lt;/span&gt; &lt;span class="k"&gt;get&lt;/span&gt; &lt;span class="nv"&gt;connected&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;true&lt;/span&gt;
                        &lt;span class="nb"&gt;delay&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
                    &lt;span class="k"&gt;end&lt;/span&gt; &lt;span class="k"&gt;repeat&lt;/span&gt;
                &lt;span class="k"&gt;end&lt;/span&gt; &lt;span class="k"&gt;tell&lt;/span&gt;
            &lt;span class="k"&gt;end&lt;/span&gt; &lt;span class="k"&gt;tell&lt;/span&gt;
        &lt;span class="k"&gt;end&lt;/span&gt; &lt;span class="k"&gt;tell&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt; &lt;span class="k"&gt;tell&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt; &lt;span class="k"&gt;tell&lt;/span&gt;

&lt;span class="nb"&gt;do shell script&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;route change default 192.168.1.1&amp;quot;&lt;/span&gt; &lt;span class="nv"&gt;with&lt;/span&gt; &lt;span class="nv"&gt;administrator&lt;/span&gt; &lt;span class="nv"&gt;privileges&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Using this to bring up the connection, I end up with a resolver
pointing to dnsmasq, and a default route via my home router.&lt;/p&gt;
&lt;p&gt;It's not ideal.  If I forget to use the script and instead connect the
"normal" way, my routing is broken.  If I do use the script, I'm
confronted with a dialog box requesting an an administrator password.&lt;/p&gt;
&lt;p&gt;Adding insult to injury, the dialog box doesn't have focus when
displayed.&lt;/p&gt;
&lt;h2&gt;Next Steps&lt;/h2&gt;
&lt;p&gt;Giving up the use of dnsmasq for the VPN connection would neatly
sidestep the issues above, and I'm tempted to do just that.  Manually
managing &lt;code&gt;/etc/hosts&lt;/code&gt; wouldn't be too onerous in this case.&lt;/p&gt;
&lt;p&gt;As noted above, I'm planning to implement IPsec/L2TP before long, and
I'm holding out hope that OS X will deal with default routes
differently for those connections.  Not a lot of hope, but it's there.&lt;/p&gt;</content><category term="Blog"/><category term="sysadmin"/></entry><entry><title>A Dedicated Server</title><link href="https://www.cryptocracy.com/blog/2012/05/06/a-dedicated-server/" rel="alternate"/><published>2012-05-06T22:30:00+01:00</published><updated>2012-05-06T22:30:00+01:00</updated><author><name>Zachary Stevens</name></author><id>tag:www.cryptocracy.com,2012-05-06:/blog/2012/05/06/a-dedicated-server/</id><summary type="html">&lt;p&gt;Setting up a Hetzner dedicated server with KVM, LVM partitioning, and a NAT network for virtual machines and VPN.&lt;/p&gt;</summary><content type="html">&lt;p&gt;We've been building out a new development environment at work -
virtualised using KVM, and managed with Chef and MCollective.  It has
made it so easy to try out new things that I found myself wishing I
had the same facilities for my own projects.&lt;/p&gt;
&lt;p&gt;An article on Hacker News had me taking another look at Hetzner, which
was followed a few days later by an order for a dedicated server with
a quad-core i7, 32GB memory, and a pair of 3TB SATA disks.  Hetzner
gets mixed reviews, but the negatives weren't enough to put me off -
the prices are good, and I'm not planning to host any critical
services.  I'll try not to complain when I get what I pay for.&lt;/p&gt;
&lt;p&gt;The rest of this post describes the initial configuration of the
server for use as a KVM host.&lt;/p&gt;
&lt;h2&gt;Initial (Re)Installation&lt;/h2&gt;
&lt;p&gt;Hetzner's default partitioning is a little questionable - with
mirrored 3TB disks, I was given a system with a 1TB root and 1.7TB
/home.  Fortunately, this is easy to customise using &lt;code&gt;installimage&lt;/code&gt;
after booting into the Hetzner rescue image.&lt;/p&gt;
&lt;p&gt;The following installimage configuration allocates most of the space to LVM,
and creates a 10GB volume for the root filesystem.  Ubuntu 11.10 is
the most recent version currently supported by Hetzner.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;DRIVE1 /dev/sda
DRIVE2 /dev/sdb
SWRAID 1
SWRAIDLEVEL 1
BOOTLOADER grub
HOSTNAME illuminati.cryptocracy.com
PART /boot ext3 512M
PART lvm vg0 all
LV vg0   root   /        ext4         10G
LV vg0   swap   swap     swap          4G
IMAGE /root/.oldroot/nfs/install/../images/Ubuntu-1110-oneiric-64-minimal.tar.gz
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Upon booting into the newly provisioned machine, I found that the
firewall wasn't enabled.  That is easily fixed:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;# ufw allow ssh
# ufw enable
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;I then used &lt;code&gt;do-release-upgrade&lt;/code&gt; to bring the system up to 12.04.&lt;/p&gt;
&lt;h2&gt;Creating a NAT network&lt;/h2&gt;
&lt;p&gt;Although libvirt can be used to manage a NAT network for guests (and
does this out of the box), its simplicity comes at a cost.  I want to
create a VPN that gives my workstation an address on the same network
as the guests, and that requires custom iptables rules.  I couldn't
figure out a clean way of doing this with libvirt managing the
interface, so I set it up manually instead.&lt;/p&gt;
&lt;p&gt;Define a detached bridge by appending to /etc/network/interfaces:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="err"&gt;#&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;detached&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;bridge&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;VMs&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;and&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;VPN&lt;/span&gt;
&lt;span class="kt"&gt;auto&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;nat0&lt;/span&gt;
&lt;span class="nx"&gt;iface&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;nat0&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;inet&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;static&lt;/span&gt;
&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;address&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m m-Double"&gt;192.168.42.1&lt;/span&gt;
&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;netmask&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m m-Double"&gt;255.255.255.0&lt;/span&gt;
&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;pre&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;up&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;brctl&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;addbr&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;nat0&lt;/span&gt;
&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;post&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;down&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;brctl&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;delbr&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;nat0&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Install brctl, and bring it up.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;#&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;apt&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nv"&gt;get&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;install&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;bridge&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nv"&gt;utils&lt;/span&gt;
#&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;ifup&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;nat0&lt;/span&gt;
#&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;brctl&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;show&lt;/span&gt;
&lt;span class="nv"&gt;bridge&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;name&lt;/span&gt;&lt;span class="w"&gt;   &lt;/span&gt;&lt;span class="nv"&gt;bridge&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;id&lt;/span&gt;&lt;span class="w"&gt;           &lt;/span&gt;&lt;span class="nv"&gt;STP&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;enabled&lt;/span&gt;&lt;span class="w"&gt;       &lt;/span&gt;&lt;span class="nv"&gt;interfaces&lt;/span&gt;
&lt;span class="nv"&gt;nat0&lt;/span&gt;&lt;span class="w"&gt;          &lt;/span&gt;&lt;span class="mi"&gt;8000&lt;/span&gt;.&lt;span class="nv"&gt;fe5400f3c41d&lt;/span&gt;&lt;span class="w"&gt;   &lt;/span&gt;&lt;span class="nv"&gt;no&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h2&gt;Enabling IP masquerading (NAT)&lt;/h2&gt;
&lt;p&gt;To complete the setup of our new network, we need enable IP forwarding
and configure the firewall.  I followed the instructions in the
&lt;a href="https://help.ubuntu.com/12.04/serverguide/firewall.html#ip-masquerading"&gt;Ubuntu firewall documentation&lt;/a&gt;
and they worked as written.&lt;/p&gt;
&lt;h2&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;At this point, we have Ubuntu 12.04 installed under LVM, with a
manually created network ready for use by our VMs and VPN.  In the
next post, we'll configure a VPN and confirm that the &lt;code&gt;nat0&lt;/code&gt; network
works as intended.&lt;/p&gt;</content><category term="Blog"/><category term="sysadmin"/></entry><entry><title>Chef LWRP - managed_directory</title><link href="https://www.cryptocracy.com/blog/2012/04/07/chef-lwrp-managed-directory/" rel="alternate"/><published>2012-04-07T22:37:00+01:00</published><updated>2012-04-07T22:37:00+01:00</updated><author><name>Zachary Stevens</name></author><id>tag:www.cryptocracy.com,2012-04-07:/blog/2012/04/07/chef-lwrp-managed-directory/</id><summary type="html">&lt;p&gt;The managed_directory LWRP inspects the Chef resource collection to identify managed files in a directory, then removes any unmanaged files it finds there.&lt;/p&gt;</summary><content type="html">&lt;p&gt;A common configuration management pattern is to generate snippets of
configuration into a ".d" directory, which are subsequently compiled
into a complete configuration - either by a script, or through support
from the application itself.&lt;/p&gt;
&lt;p&gt;This pattern works well when you're maintaining a set of snippets, or
adding to it, but removing snippets from the set can present a
challenge.  If you need to specifically remove a snippet from a node,
you can always use the File resource with &lt;code&gt;action :delete&lt;/code&gt; to do so.
But what do you do if you don't know which snippets need to be removed?&lt;/p&gt;
&lt;p&gt;The &lt;code&gt;managed_directory&lt;/code&gt; LWRP
&lt;a href="https://github.com/zts/chef-cookbook-managed_directory"&gt;(Github Repo)&lt;/a&gt;
inspects the node's resource collection to identify the Chef-managed
files in a given directory.  It then compares this to the list of
files actually present in the directory and removes the difference.&lt;/p&gt;
&lt;p&gt;Walking the resource collection is pretty easy, although I had trouble
finding examples when I sat down to try it.  Hence this simple one:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;managed_files&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;run_context&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;resource_collection&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;all_resources&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;map&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;start_with?&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;new_resource&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;/&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;compact&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;(Follow the "full source" link to see it in context.)&lt;/p&gt;
&lt;p&gt;I haven't uploaded this cookbook to the community site yet, as the
&lt;a href="https://github.com/zts/chef-cookbook-managed_directory/blob/master/README.md"&gt;list of assumptions and caveats&lt;/a&gt;
is almost as long as this post.  If there's sufficient interest, I'll
fix a few of those and put it up.&lt;/p&gt;
&lt;p&gt;Suggestions and pull requests are welcome.&lt;/p&gt;</content><category term="Blog"/><category term="chef"/></entry><entry><title>Starting over with Emacs</title><link href="https://www.cryptocracy.com/blog/2012/04/04/starting-over-with-emacs/" rel="alternate"/><published>2012-04-04T12:13:00+01:00</published><updated>2012-04-04T12:13:00+01:00</updated><author><name>Zachary Stevens</name></author><id>tag:www.cryptocracy.com,2012-04-04:/blog/2012/04/04/starting-over-with-emacs/</id><summary type="html">&lt;p&gt;After two years using the Emacs Starter Kit without really understanding it, I rebuilt my Emacs configuration from scratch to gain a deeper understanding of the editor.&lt;/p&gt;</summary><content type="html">&lt;h2&gt;Starting&lt;/h2&gt;
&lt;p&gt;I switched to Emacs sometime in 2009.  At the time, I was using
TextMate most of the time (though diving frequently into vi, as
befitting my background as a system administrator).  There wasn't any
singular event that drove me to try out Emacs, but I do remember being
frustrated by TextMate's performance with a particularly large project
at work.  I'd noticed Emacs-using colleagues having a much better time
of things, and some stories about Emacs on Hacker News had piqued my
interest.&lt;/p&gt;
&lt;p&gt;The learning curve was initially quite steep, which presented
something of a challenge - I needed to use the tool to get work done,
and couldn't afford to significantly slow myself down for an unknown
period.  I bought PeepCode's
&lt;a href="https://peepcode.com/products/meet-emacs"&gt;"Meet Emacs"&lt;/a&gt; screencast
to see a quick introduction to the essential features, and get a
handle on my ignorance.  It's important to know what you don't know,
and the screencast helped me reach
&lt;a href="http://en.wikipedia.org/wiki/Four_stages_of_competence"&gt;"conscious competence"&lt;/a&gt;
quickly enough to stick with it.&lt;/p&gt;
&lt;p&gt;Following the advice in "Meet Emacs", I used the
&lt;a href="https://github.com/technomancy/emacs-starter-kit"&gt;Emacs Starter Kit&lt;/a&gt;
for my initial configuration.  It was &lt;em&gt;awesome&lt;/em&gt;.  More awesome than I
could comprehend; despite spending time poking around the contents of
my new &lt;code&gt;~/.emacs.d&lt;/code&gt;, only the most superficial aspects of the
configuration made much sense.  I had an editor that was powerful and
feature-rich, but the much-vaunted malleability of the Emacs environment
lay beyond my grasp.&lt;/p&gt;
&lt;p&gt;Fortunately, my earlier switch to OS X had brought with it a certain
serenity in the face of technology.  If an opinionated application (or
OS) does what you want, most of the time, it's worth going along with
it in the places you disagree.  That this is largely antithetical to
the Emacs view of the world is not lost on me.&lt;/p&gt;
&lt;p&gt;So, I spent my first couple of years with Emacs using a
barely-customised ESK configuration, and I was pretty happy with it.
While missing some of vi's functionality, I choose not to install any
vi-compatibility features.  The lynch-pin of my commitment turned out to be
&lt;a href="http://philjackson.github.com/magit/"&gt;magit&lt;/a&gt;, the excellent git mode
for Emacs.  Having become accustomed to such seamless interaction with
my VCS, I can no longer imagine working without it.&lt;/p&gt;
&lt;h2&gt;Restarting&lt;/h2&gt;
&lt;p&gt;Though I was largely happy with the end result, the amount of magic
(or sufficiently advanced technology) bothered me.  Nor was this
entirely academic - I had been putting up with a bunch of quirks I was
sure could be fixed, if only I knew how.  Last week, I came across the
article that helped me start down that road.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://stevendanna.github.com/blog/2011/11/26/emacs-configuration-rewrite/"&gt;"Emacs Configuration Rewrite"&lt;/a&gt;
documents Steven Danna's experience rebuilding his Emacs configuration
from scratch.  The result is positively minimalist alongside ESK, and
lacks many features and customisations the latter delivers "out of the
box".  I decided that probably didn't matter to me - after all, if I
missed something enough to add it back in, that would simply drive me
to learn how to do that.  Above all else, Steven's configuration
showed me that I could start out with something I could comprehend
completely, and expand from there.  So that's what I did.&lt;/p&gt;
&lt;p&gt;The
&lt;a href="https://github.com/zts/emacs.d/commit/a722d44cf3ae4eee825d89da67d809d7e259c8fe"&gt;initial commit&lt;/a&gt;
to my emacs configuration repo doesn't tweak anything - it simply
introduces the skeleton that everything else hangs off.  I've added
one thing at a time as I've needed it, and understood it.  That's not
to say it's entirely (or even mostly) original work - I've picked
things up from various places, but they only go into my config when I
understand what they do.  No blind copy-and-paste, no cargo cults.&lt;/p&gt;
&lt;p&gt;Emacs makes this exercise pretty easy.  The built-in help can give you
the value and meaning of any variable (&lt;code&gt;C-h v&lt;/code&gt;), and the documentation
for any function (&lt;code&gt;C-h f&lt;/code&gt;).  For anything implemented in elisp (and
that's nearly everything), you can even jump straight to the source.
This was way too much to deal with when I first started using Emacs,
but I regret leaving it so long to come back to it.&lt;/p&gt;
&lt;h2&gt;The Future&lt;/h2&gt;
&lt;p&gt;I don't like unnecessary wheel reinvention.  My goal is to understand
how things fit together, that I might change them according to my
needs - I don't feel that meeting that goal demands personally entering every single sexp
into my Emacs configuration.&lt;/p&gt;
&lt;p&gt;The Emacs Starter Kit has evolved considerably since I made a personal
fork in 2009, and I made
no attempt to evolve my forked configuration with it.  It contains
lots of good stuff, and I've started to look more closely at exactly
how it's put together.  As my understanding grows, I expect to be able
to reuse larger pieces of elisp (from ESK and elsewhere) without
feeling that my configuration is outgrowing my competence.&lt;/p&gt;
&lt;p&gt;I may move to an ESK-based configuration again in the future, and I'm
glad I used one in the past.  In the present, I'm appreciating a
greater understanding of a smaller set of features.&lt;/p&gt;</content><category term="Blog"/><category term="misc"/></entry><entry><title>Migrating to Octopress</title><link href="https://www.cryptocracy.com/blog/2012/03/20/migrating-to-octopress/" rel="alternate"/><published>2012-03-20T08:16:00+00:00</published><updated>2012-03-20T08:16:00+00:00</updated><author><name>Zachary Stevens</name></author><id>tag:www.cryptocracy.com,2012-03-20:/blog/2012/03/20/migrating-to-octopress/</id><summary type="html">&lt;p&gt;A brief account of migrating this site from Posterous to Octopress, including importing content and switching to GitHub Pages hosting.&lt;/p&gt;</summary><content type="html">&lt;p&gt;As may be obvious from the new look, this site is now running on
Octopress.  Migrating from Posterous wasn't especially traumatic, but
the paucity of content helped in that regard.&lt;/p&gt;
&lt;h2&gt;Importing from Posterous&lt;/h2&gt;
&lt;p&gt;Jekyll ships with an importer for pulling content out of Posterous,
but it no longer works after the latter changed their API.  There's
&lt;a href="https://github.com/mojombo/jekyll/pull/477"&gt;a fix&lt;/a&gt;, but wasn't in a
released version when I needed it.&lt;/p&gt;
&lt;p&gt;With the update, the importer appeared to do a reasonable job of
importing my posts (although it failed to set &lt;code&gt;published: false&lt;/code&gt; on my
drafts).  One caveat: the date used is the creation date, not the
publish date, of the source posts.&lt;/p&gt;
&lt;p&gt;The importer didn't grab any of the "pages" on my Posterous site, but
I chose to recreate the "About Me" page in markdown rather than
determine whether this was intended behaviour.&lt;/p&gt;
&lt;p&gt;I manually converted my posts and drafts into markdown, so let me know
if you notice any errors.&lt;/p&gt;
&lt;h2&gt;Publishing&lt;/h2&gt;
&lt;p&gt;The site is now hosted on GitHub pages, backed by a private
repository.  This works well enough, although it doesn't appear to
be possible to assign two custom hostnames for the same site.  I'd
like to migrate from "www.cryptocracy.com" to "cryptocracy.com", so
a further hosting change is on the cards.&lt;/p&gt;</content><category term="Blog"/><category term="misc"/></entry><entry><title>Chef MCollective cookbook, v0.9.0</title><link href="https://www.cryptocracy.com/blog/2011/09/25/chef-mcollective-cookbook-v-0-9-0/" rel="alternate"/><published>2011-09-25T23:29:00+01:00</published><updated>2011-09-25T23:29:00+01:00</updated><author><name>Zachary Stevens</name></author><id>tag:www.cryptocracy.com,2011-09-25:/blog/2011/09/25/chef-mcollective-cookbook-v-0-9-0/</id><summary type="html">&lt;p&gt;Version 0.9.0 of the MCollective Chef cookbook addresses the three issues from the original announcement: Ohai fact speed, fact list size, and default recipe name normalisation.&lt;/p&gt;</summary><content type="html">&lt;p&gt;After far too long, I've released
&lt;a href="http://community.opscode.com/cookbooks/mcollective"&gt;an updated cookbook for installing MCollective&lt;/a&gt;
which addresses the three issues called out in &lt;a href="http://www.cryptocracy.com/using-mcollective-with-chef"&gt;the original announcement&lt;/a&gt;:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Directly invoking Ohai as a fact source is pretty slow.&lt;/li&gt;
&lt;li&gt;The full set of Ohai facts can be pretty large.&lt;/li&gt;
&lt;li&gt;Chef doesn't normalise 'default' recipe names in the expanded run list.&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;Ohai facts via YAML&lt;/h2&gt;
&lt;p&gt;Prior to this release, this cookbook configured MCollective to use the
&lt;code&gt;opscodeohai_facts&lt;/code&gt; plugin from the
&lt;a href="https://github.com/puppetlabs/mcollective-plugins/tree/master/facts/ohai/"&gt;mcollective-plugins repository&lt;/a&gt;.
While this continues to be supported, the default configuration now has MCollective loading facts from a YAML file written by a Chef report handler.&lt;/p&gt;
&lt;p&gt;A new attribute has been added to control this - set
&lt;code&gt;node.mcollective.factsource&lt;/code&gt; to &lt;code&gt;ohai&lt;/code&gt; to restore the old behaviour.&lt;/p&gt;
&lt;h2&gt;Configurable fact list&lt;/h2&gt;
&lt;p&gt;Out of the box, Ohai produces a lot of facts &amp;ndash; not all of which are especially useful as MCollective Facts.  The report handler responsible for building the YAML fact file looks at an attribute (&lt;code&gt;node.mcollective.fact_whitelist&lt;/code&gt;) to filter the full list of facts available to Chef.&lt;/p&gt;
&lt;h2&gt;Default recipe name&lt;/h2&gt;
&lt;p&gt;The original responsibility of the report handler was to produce a list of "classes", the roles and recipes Chef used on this node.  Unfortunately, Chef offers two ways of referring to a cookbook's default recipe - either with an explicit recipe name, &lt;code&gt;recipe[cookbook::default]&lt;/code&gt;, or without, &lt;code&gt;recipe[cookbook]&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;This isn't spectacularly helpful, as the result is the same no matter which name was used.  With this release, default recipes in the classlist always use their full name.&lt;/p&gt;
&lt;h2&gt;Other Changes&lt;/h2&gt;
&lt;h3&gt;Site Plugins&lt;/h3&gt;
&lt;p&gt;A separate directory is now created to hold third-party plugins.  Its path is stored as an attribute, &lt;code&gt;node.mcollective.site_plugins&lt;/code&gt;.&lt;/p&gt;
&lt;h3&gt;Recipe for Puppetlabs repo installation&lt;/h3&gt;
&lt;p&gt;The cookbook previously assumed that the user would want to install the MCollective packages from the Puppetlabs apt/yum repository.  While this simplifies installation for internet-connected machines, it's not the best approach for larger sites.  If the nodes you're configuring don't have access to the internet, it obviously won't work at all.&lt;/p&gt;
&lt;p&gt;This version introduces &lt;code&gt;recipe[mcollective::puppetlabs-repo]&lt;/code&gt;, which
is included by &lt;code&gt;mcollective::default&lt;/code&gt;.  If you wish to use a local
package mirror for installation, make sure it has been installed
before using &lt;code&gt;mcollective::server&lt;/code&gt; and &lt;code&gt;mcollective::client&lt;/code&gt;.&lt;/p&gt;
&lt;h3&gt;Futures&lt;/h3&gt;
&lt;p&gt;What's left before a 1.0 release?&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Paths to the generated facts/classes files should be controlled by a node attribute.&lt;/li&gt;
&lt;li&gt;Optionally include non-automatic attributes in the fact file.&lt;/li&gt;
&lt;li&gt;Support for using security plugins other than the default 'PSK'.&lt;/li&gt;
&lt;li&gt;Tests (&lt;a href="http://www.cucumber-chef.org"&gt;cucumber-chef&lt;/a&gt;, I'm looking at you).&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Where can I get it?&lt;/h2&gt;
&lt;p&gt;You can find &lt;a href="http://community.opscode.com/cookbooks/mcollective"&gt;the MCollective Cookbook&lt;/a&gt; on the
Opscode Community site, install it using Knife (&lt;code&gt;knife cookbook site install mcollective&lt;/code&gt;), or check out &lt;a href="https://github.com/zts/cookbook-mcollective"&gt;the source on github&lt;/a&gt;.&lt;/p&gt;</content><category term="Blog"/><category term="chef"/><category term="mcollective"/></entry><entry><title>Using MCollective with Chef</title><link href="https://www.cryptocracy.com/blog/2011/08/21/using-mcollective-with-chef/" rel="alternate"/><published>2011-08-21T13:27:00+01:00</published><updated>2011-08-21T13:27:00+01:00</updated><author><name>Zachary Stevens</name></author><id>tag:www.cryptocracy.com,2011-08-21:/blog/2011/08/21/using-mcollective-with-chef/</id><summary type="html">&lt;p&gt;MCollective is a Ruby framework for building server orchestration or parallel job execution systems. Although it often seems to go hand-in-hand with Puppet, it can readily be used with Chef. Here's how.&lt;/p&gt;</summary><content type="html">&lt;p&gt;&lt;a href="http://www.puppetlabs.com/mcollective/introduction/" title="MCollective Introduction"&gt;MCollective&lt;/a&gt; is a Ruby framework "to build server
orchestration or parallel job execution systems".  Using messaging
middleware (currently STOMP) for communication, a server running on
each node can announce its existence, receive requests, and respond
with structured data.  Writing clients and agents is a straightforward
exercise - while you'll need to know enough Ruby to implement your
desired functionality, the framework itself adds little complexity.  A
number of non-core plugins are available
&lt;a href="https://github.com/puppetlabs/mcollective-plugins/" title="MCollective Plugins on Github"&gt;on github&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Although it often seems that MCollective goes hand-in-hand with
Puppet, there's no technical limitation behind this.  It can quite
readily be used with any other configuration management tool, or none
at all.  The plugins supporting integration with Puppet may be a
little more mature today, but users of Chef won't be missing out on
anything.&lt;/p&gt;
&lt;h2&gt;Installation&lt;/h2&gt;
&lt;p&gt;To satisfy MCollective's requirement for a STOMP server, it's
easiest to use ActiveMQ.  For Ubuntu users, this can be easily
installed using a cookbook from the Opscode site.  After installation,
we need to configure the service for use by MCollective - for
simplicity, we'll use the sample configuration from
the
&lt;a href="http://docs.puppetlabs.com/mcollective/reference/basic/gettingstarted.html#configuring-stomp"&gt;Getting Started&lt;/a&gt; documentation.&lt;/p&gt;
&lt;p&gt;See &lt;a href="https://gist.github.com/1130790"&gt;this gist&lt;/a&gt; for the
necessary changes to the ActiveMQ cookbook.&lt;/p&gt;
&lt;p&gt;The community site didn't have a cookbook to install MCollective, so
I've been working on one to fill the gap.  I've released it on
&lt;a href="http://community.opscode.com/cookbooks/mcollective"&gt;the community site&lt;/a&gt;,
but be warned - this is my first attempt at writing a public cookbook,
and your mileage may vary.  You can find the source repository
&lt;a href="https://github.com/zts/cookbook-mcollective" title="cookbook-mcollective repository"&gt;on github&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;Demonstration&lt;/h2&gt;
&lt;p&gt;We can use Vagrant to make a simple demonstration using a single
node.  In practice, there's not much point to running MCollective on
just a single node - fortunately, using these cookbooks on a group of
nodes (with Chef Server) is similarly straightforward.  The repository
for this demonstration is
&lt;a href="http://github.com/zts/vagrant-mcollective-chef-ubuntu"&gt;on github&lt;/a&gt;
 - the Vagrantfile specifies a "natty64" base box, but
anything from "lucid" onwards should work.&lt;/p&gt;
&lt;script src="https://gist.github.com/1159727.js?file=Spinning%20up%20the%20box"&gt;&lt;/script&gt;

&lt;p&gt;Our first test that everything has worked is to use "mco ping".
This is an MCollective client command which broadcasts an echo
request, and presents the replies from any mcollective servers which
happen to be listening.  As we're running on a single node, we expect
a single response:&lt;/p&gt;
&lt;script src="https://gist.github.com/1159727.js?file=Testing%20the%20box."&gt;&lt;/script&gt;

&lt;h2&gt;Chef Integration&lt;/h2&gt;
&lt;p&gt;The cookbook incorporates the Chef integration code found in the
MCollective documentation
(&lt;a href="http://docs.puppetlabs.com/mcollective/reference/integration/chef.html&amp;quot;"&gt;link&lt;/a&gt;),
with one small improvement - the code in the "Class filters" section
has been implemented as a Chef handler, to avoid needing to pin a
recipe at the end of the run list.
The resulting inventory output looks something like this:&lt;/p&gt;
&lt;script src="https://gist.github.com/1159727.js?file=Inventory"&gt;&lt;/script&gt;

&lt;h2&gt;Issues&lt;/h2&gt;
&lt;p&gt;While relatively minor, there are several issues with the
integration that I'm planning to work on.
First, Ohai is a not especially fast.  Although MCollective will
cache its output, this means that requests might occasionally take
several seconds to return (vs the typical tens-of-milliseconds
latency).  This is merely an annoyance during interactive use, but I
expect it to be a problem for more sophisticated applications.  An
alternative approach used in the Puppet integration is to dump the
facts into a YAML file, which MCollective then loads.
Second, out of the box, Ohai appears to expose considerably more
facts than Facter.  I'm not convinced this is especially useful to
MCollective, and I'm considering ways to filter the list down to facts
I want to select or efficiently report on.  Returning the data from
only a specified list of Ohai plugins is my short-term plan.  That
said, I may yet change my mind about it being a problem - undesirably
verbose "mco inventory" output is my only real complaint.
Third, the list of Chef recipes reported to MCollective needs to be
normalised.  Depending upon how they made it into the expanded run
list, a default recipe may be reported as either "recipe.cookbook" or
"recipe.cookbook::default".  I'm not sure whether Chef should be
taking care of this, or whether I should just fix it in the report
handler.&lt;/p&gt;
&lt;h2&gt;Further Reading&lt;/h2&gt;
&lt;p&gt;Nicolas Szalay's blog has
&lt;a href="http://www.rottenbytes.info/tag/mcollective/" title="Nicolas Szalay's blog"&gt;some must-read entries&lt;/a&gt;
demonstrating how to trigger Chef runs using
MCollective, and how to create and use Chef resources from within
MCollective agents.  The &lt;a href="http://docs.puppetlabs.com/mcollective/reference/"&gt;MCollective Reference Guide&lt;/a&gt;
on the Puppet Labs site is comprehensive and
well-written.  It's worth spending some time browsing it to get a feel
for what's possible.  In the next post, we'll take a step back from
MCollective and take a closer look at the cookbook itself.&lt;/p&gt;</content><category term="Blog"/><category term="chef"/><category term="mcollective"/></entry></feed>