<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:blogger='http://schemas.google.com/blogger/2008' xmlns:georss='http://www.georss.org/georss' xmlns:gd="http://schemas.google.com/g/2005" xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-1083699665345453745</id><updated>2026-11-04T13:46:13.385-08:00</updated><category term="chef"/><category term="devops"/><title type='text'>devopsanywhere</title><subtitle type='html'>It&#39;s cloudy all over</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://devopsanywhere.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1083699665345453745/posts/default?redirect=false'/><link rel='alternate' type='text/html' href='http://devopsanywhere.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Anonymous</name><uri>http://www.blogger.com/profile/10631977500882582704</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>24</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-1083699665345453745.post-420964150623249027</id><published>2016-08-01T07:55:00.001-07:00</published><updated>2016-08-03T09:17:21.920-07:00</updated><title type='text'>Let&#39;s make CLI Tools less Shitty</title><content type='html'>&lt;div dir=&quot;ltr&quot; style=&quot;text-align: left;&quot; trbidi=&quot;on&quot;&gt;
Alternate Title:&amp;nbsp; Bash Programmers Shall Inherit the Earth&lt;br /&gt;
&lt;br /&gt;
I have recently come to the conclusion that the future of configuration management is not Ruby, Python, or a putrified YAML DSL but it is Bash and PowerShell. My thinking largely stems from the recent release of &lt;a href=&quot;https://www.habitat.sh/&quot;&gt;Habitat&lt;/a&gt; from Chef Inc. and several years of experience writing automation tools for Sysadmins with varying levels of sophistication. I have written tons of Chef cookbooks, Puppet manifests, and Ansible Playbooks over the last 7 years. My greatest frustration with all of these tools has been that it is very difficult for users not already immersed in those tools to reuse and modify their respective cookbook/manifest/playbook. I have written previously about how it might work if we &lt;a href=&quot;http://devopsanywhere.blogspot.com/2016/04/what-if-cli-tools-had-restful-apis.html&quot;&gt;gave CLI tools Restful APIs&lt;/a&gt; and this post builds on some of those ideas.&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: &amp;quot;arial&amp;quot; , &amp;quot;helvetica&amp;quot; , sans-serif;&quot;&gt;&lt;span style=&quot;background-color: white; color: #333333; display: inline; float: none; font-size: 14px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: 21px; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px;&quot;&gt;My friend Milos Gajdos asked if this proposal supports the spawning of long-lived processes that can be interacted with asynchronously like Restful services. That is an idea I proposed In my earlier post. I am no longer sure how that would best work so it is not part of this proposal.&lt;/span&gt;&lt;/span&gt; &lt;br /&gt;
&lt;br /&gt;
Bash is the lowest common denominator for automation scripting. Habitat puts enough structure around Bash that it *might* be able to replace Chef entirely for automation tasks. Note that while Bash is a very primitive environment, Powershell is not. Powershell is a very sophisticated tool but Bash sets the minimum capabilities that we have to expect.&lt;br /&gt;
&lt;br /&gt;
As noted earlier, I have spent a lot of time writing code for Chef, Puppet, and Ansible. I want to move away from writing sophisticated tooling inside these frameworks to writing more flexible command-line tools that work well with Bash, Powershell, and higher-level frameworks.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
What I have in mind is a standard for CLI tools that I call &lt;u&gt;CREST or Command REST&lt;/u&gt;. The similarity to ReST is intentional as it takes some inspiration from &lt;a href=&quot;https://en.wikipedia.org/wiki/Representational_state_transfer&quot;&gt;Representational State Transfer&lt;/a&gt;&lt;br /&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
Before we get into what CREST might look like, let&#39;s start with a meaningful example command line invocation and show how it might take advantage of crest. At
 acme Corp our users need a cli tool to create amazon ec2 instances and 
returns a list of instance ids for the newly created instances. For the sake of this argument, please ignore that there are many tools and libraries that already handle this. This 
command should have the option to be idempotent. Sysadmin Bob in 
Connecticut wants to use the command in their bespoke&amp;nbsp; bash scripting 
config mgt system. The devoops team in San Jose will use the tool within
 their existing chef cookbooks. There is even a team of Windows devs in Utah that want to invoke our new tool from their Windows-based CI server that is just a pile of Powershell. The developers in a new acquisition use 
Ansible. Acme corp users will use this tool on Windows, OS X, and Linux machines.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
Let&#39;s call or new command hamilton after &lt;a href=&quot;http://perspectives.mvdirona.com/&quot;&gt;James Hamilton&lt;/a&gt;, a distinguished engineer at Amazon who gives great presentations. For the common case, hamilton does not need any arguments. It creates a single EC2 instance using a bunch of built in defaults.&lt;br /&gt;
&lt;br /&gt;
$ hamilton&lt;br /&gt;
&lt;br /&gt;
stdout:&lt;br /&gt;
&lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;instance_id: i-2345345&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;public_ip: 1.1.1.1&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;region: us-east1 &lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;Name: acme-rand12345 &lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;machine_type: t2.small&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
stderr:&amp;nbsp; [empty]&lt;br /&gt;
&lt;br /&gt;
$ echo $? &lt;br /&gt;
0 &lt;br /&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
That was easy! However, if you have ever worked with EC2 instances you know that the API supports many, many different parameters. Let&#39;s create 3 ec2 instances with the following properties&lt;/div&gt;
&lt;div&gt;
&lt;ul style=&quot;text-align: left;&quot;&gt;
&lt;li&gt;region: southeast-ap1&lt;/li&gt;
&lt;li&gt;image_id ami-123456,&lt;/li&gt;
&lt;li&gt;instance_type: c2.xlarge&lt;/li&gt;
&lt;li&gt;termination_protection: on&lt;/li&gt;
&lt;li&gt;ephemeral volumes: 1 50GB&lt;/li&gt;
&lt;li&gt;enhanced IOPS&lt;/li&gt;
&lt;li&gt;tags: [&quot;Name: foo_instance#{count}&quot;, &quot;environment: testing&quot;]&lt;/li&gt;
&lt;li&gt;and even more . . .&amp;nbsp; &lt;/li&gt;
&lt;/ul&gt;
Wow! That&#39;s a lot of options. So many that they are infeasible to supply on the command-line.&amp;nbsp; We could allow 100+ command-line options. That would make our Bash users happy but frustrate our Chef and Ansible users to no end. This is especially true when you consider what a pain it is to generate command-line invocations for Powershell. Putting together long sets of strings for Powershell is a bloody fucking nightmare. At this point many people would write a Python (or Ruby) library that can be manipulated to create ec2 instances with the correct options. Congratulations! You have just required everyone on your distributed team to learn Python! This is not entirely true as some of your users will never learn Python but simply ask you to create scripts for them that they can call from Bash/Powershell/Ansible.&lt;br /&gt;
&lt;br /&gt;
Instead of writing a Python library or creating a CLI w/ a bazillion options. I would give hamilton the most common options on the CLI and allow it to ingest a big ball of JSON for the more complex cases. Our Bash users can grudgingly write JSON documents and our Ansible and Chef users will happily generate them from dictionaries.&lt;br /&gt;
&lt;br /&gt;
$ hamilton input.json&lt;br /&gt;
&lt;br /&gt;
contents of input.json&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;{ &quot;region&quot;: &quot;southeast-ap1&quot;,&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;&amp;nbsp; &quot;image_id&quot;: &quot;ami-123456&quot;,&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;&amp;nbsp; &quot;instance_type&quot;: &quot;c2.xlarge&quot;,&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;&amp;nbsp; &quot;termination_protection&quot;: &quot;on&quot;,&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;&amp;nbsp; &quot;ephemeral_volumes&quot;: { [ &quot;size&quot;: &quot;50GB&quot; ] },&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;&amp;nbsp; &quot;enhanced_iops&quot;: true,&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;&amp;nbsp; &quot;tags&quot;: [&quot;Name: foo_instance#{count}&quot;, &quot;environment: testing&quot;]&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;}&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
Here is the first part of CREST. The Request, should support a JSON input for easier automation.&lt;/div&gt;
&lt;div&gt;
Now let&#39;s look at the Response we want to get back.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
stdout:&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;instance_id: i-2345345&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;public_ip: 1.1.1.1&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;region: us-east1 &lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;Name: acme-rand12345 &lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;machine_type: t2.small&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
stderr: empty&lt;br /&gt;
&lt;br /&gt;
Alright this looks fine. We got back the details we needed and we can go about our work. That said, what should hamilton return if there are no c2.xlarge instances available? What if the EC2 API calls failed and returned a long error message? How would we expose that to the user?&lt;br /&gt;
&lt;br /&gt;
I believe that we should separate the &quot;data&quot; of the response from the metadata about it. The UNIX standard does have mechanisms to do this but it is not consistently implemented or even clear how to do it. The convention of using an &lt;a href=&quot;https://en.wikipedia.org/wiki/Exit_status&quot;&gt;exit status&lt;/a&gt; to report command failure to report command status is too coarse in my opinion. I am a big fan of the &lt;a href=&quot;http://redsymbol.net/articles/unofficial-bash-strict-mode/&quot;&gt;Unofficial Bash Strict Mode&lt;/a&gt;. However, one unpleasant side effect of using strict mode is that it leads you to ignore exit codes in your scripting or to turn strict mode on and off in error-prone ways.&lt;br /&gt;
&lt;br /&gt;
I propose that the Response should support outputting on stderr a message in either of two formats, newline-delimited or JSON. &lt;/div&gt;
&lt;br /&gt;
stderr: &lt;br /&gt;
exit_status: 403&amp;nbsp;&amp;nbsp; # A descriptive status about the API that matches a common convention, just like HTTP&lt;br /&gt;
error_message: A human-readable error message&lt;br /&gt;
verbose: stack trace, log messages, anything else to print to user&lt;br /&gt;
&lt;br /&gt;
Why put the exit status in stderr? Use of the `set -e` option in Bash will cause our script to exit as soon as a non-zero exit status is generated. However, we may not want to exit the script in all error cases. To get around this, many scripters write lines like this `cat some_file | grep &quot;some_string&quot; || true`. In this case, a non-zero exit status is ignored so our script dpesn&#39;t exit prematurely but we have also lost some information.&lt;br /&gt;
&lt;br /&gt;
To summarize here is what I have in mind for CREST. I would love your input!&lt;br /&gt;
&lt;br /&gt;
CREST - Command REST&lt;br /&gt;
&lt;br /&gt;
A CRESTful tool:&lt;br /&gt;
&lt;ul style=&quot;text-align: left;&quot;&gt;
&lt;li&gt;is available as a standalone binary&lt;/li&gt;
&lt;li&gt;accepts arguments as command-line args or a JSON document, similar to an HTTP Request&lt;/li&gt;
&lt;li&gt;The &quot;data&quot; output by the tool goes to stdout and can be in any format. This maps to the data part of an HTTP response&lt;/li&gt;
&lt;li&gt;The metadata for the result of the command is output to stderr and must support both newline-delimited and JSON output formats. This maps to Response Headers in HTTP.&lt;/li&gt;
&lt;li&gt;&amp;nbsp;The exit code should only be 0 to indicate success and 1 to indicate failure&lt;/li&gt;
&lt;li&gt;If the invocation succeeds, an exit_status of 2xx is returned&lt;/li&gt;
&lt;li&gt;If invocation fails, an exit status other than 2xx is returned&amp;nbsp;&lt;/li&gt;
&lt;/ul&gt;
The standalone binary is critical as a CRESTful tool and its dependencies must avoid making assumptions whenever possible about what common libraries might be installed. Note that this can be hard to avoid entirely, see GLIBC for example.&lt;br /&gt;
&lt;ul style=&quot;text-align: left;&quot;&gt;
&lt;/ul&gt;
Notes: It is critical that metadata can be output in either newline-delimited or JSON formats. We cannot assume that our users have a JSON parser like jq at their disposal. &lt;br /&gt;
&lt;br /&gt;
Here is a possible format for Standard Error Output. Note that only exit_status is required.&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;exit_status: a commonly understood status code like HTTP uses [required]&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;error_message: human-readable error message [optional]&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;verbose:&amp;nbsp; stack trace, log messages, anything else we wish to print to user in case of failure [optional]&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;arbitrary additional headers . . .&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
I prefer http status codes over C exit statuses as there is no standard meaning to C exit statuses while HTTP has relatively well understood codes that even I can grok without searching for a man page that might not exist.&lt;br /&gt;
&lt;br /&gt;
There is a giant hole in this specification. I have not specified how a CRESTful tool manages internal state transitions and reflects that status to users. This is a hard but important problem. It will take some trial and error to suss this out. Thanks to Adam Jacob for highlighting the importance of this.&lt;br /&gt;
&lt;br /&gt;
I would love your thoughts and input on this!&lt;br /&gt;
&lt;br /&gt;
Update August 1, 2016: Thanks to Milos Gajdos for his input. &lt;br /&gt;
&lt;br /&gt;
Update August 2, 2016: Thanks to Adam Jacob for his input.&amp;nbsp; My vision of CREST is less ambitious than the issues and use cases that he brought up. Adam thinks it is critical that CRESTful tools support idempotency. Doing that, however, requires each CRESTful tool manage state transitions. There is a lot &quot;devil&quot; in those details. He also pointed out that the example tool I use in this post, &quot;hamilton,&quot; is perhaps the poorest demonstration of the utility of CREST. Better examples are user management, sysctl, and firewall rules.&lt;br /&gt;
&lt;br /&gt;&lt;/div&gt;
</content><link rel='replies' type='application/atom+xml' href='http://devopsanywhere.blogspot.com/feeds/420964150623249027/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://devopsanywhere.blogspot.com/2016/08/lets-make-cli-tools-less-shitty.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1083699665345453745/posts/default/420964150623249027'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1083699665345453745/posts/default/420964150623249027'/><link rel='alternate' type='text/html' href='http://devopsanywhere.blogspot.com/2016/08/lets-make-cli-tools-less-shitty.html' title='Let&#39;s make CLI Tools less Shitty'/><author><name>Anonymous</name><uri>http://www.blogger.com/profile/10631977500882582704</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1083699665345453745.post-5066741643006666322</id><published>2016-06-19T20:02:00.001-07:00</published><updated>2016-06-19T23:16:49.207-07:00</updated><title type='text'>Why I am excited about Habitat</title><content type='html'>&lt;div dir=&quot;ltr&quot; style=&quot;text-align: left;&quot; trbidi=&quot;on&quot;&gt;
Last week, Chef Inc. announced &lt;a href=&quot;https://www.habitat.sh/&quot;&gt;Habitat&lt;/a&gt;
 a new tool for packaging and deploying applications. It is hard for me 
to overstate how excited I am about this new project. Let&#39;s start w/ a 
little backstory. I have been involved with the Chef community since ~ 
2010 but not actively involved over the last couple years. The primary 
reason for this was that the Chef tooling was less and less a good fit 
for my daily work.&lt;br /&gt;
&lt;br /&gt;
My primary client over the last 
couple years needed a highly reliable, deterministic system where the 
provenance of all code deployed to production had to be verified and 
tracked. Let&#39;s call this Project X to protect the innocent. That is, we 
had to know where all the code came from and prove that it had not been 
tampered with. This meant that pulling gems off of rubygems.org or pypi 
was a non-starter. Even pulling these resources from private mirrors was
 problematic as it we still had to put in place a mechanism that 
documented the hashes of all rubygems, pip packages, jars, tarballs 
anything else to be used prior to actually deploying anything. We needed
 a deployable, accountable unit of software. &quot;Docker!&quot; you say. &quot;Nay!&quot; I
 reply. Docker is a great tool but it only provides a storage unit. It 
has no mechanisms for code provenance or authentication. A Docker image 
gives you is an opaque blob opaque blog of bits without any information 
about where they came from.&lt;br /&gt;
&lt;br /&gt;
Needless to say, Chef 
was a poor fit for Project X. Chef leaves all configuration up to the 
very last moment possible, the time of deployment. This gives you a lot 
of flexibility that should not be taken for granted. Combine this with 
the infinite flexibility of Ruby and you have a wonderful tool for 
gluing together systems. This flexibility comes at a cost however, it 
makes the system overall fairly non-deterministic and a really bad fit 
for clients that require code provenance and tracking. Back on Project 
X, I spent some time researching the &lt;a href=&quot;https://nixos.org/nix/&quot;&gt;Nix Package Manager&lt;/a&gt;.
 If you are not familiar with the Nix package manager, it has a number 
of neat properties that address Project X&#39;s requirements and more. The 
tooling around Nix, however, left a lot to be desired as did concerns 
about long-term adoption of Nix. Sadly, I cannot remember the specific 
concerns the team had about Nix tooling. &lt;br /&gt;
&lt;br /&gt;
Rewind to
 last week&#39;s announcement of Habitat. Habitat takes a lot of inspiration
 from Nix as far as I can tell, and from Consul as well. There are a few
 nix features missing from Habitat. The big one is that Nix packages use
 cryptographic hashes to verify the current package and all of it 
dependencies. This gives you a nice way to track not only the current 
package but everything it depends on. As far as I can tell, Habitat does
 not give you a way to say &quot;I want core/glibc/2.22/RELEASE/CHECKSUM&quot;. 
You can only specify &quot;core/glibc/2.22/RELEASE&quot;. Further, you can use the
 use the cryptographic hash of a deployed package to determine all of 
its exact dependencies.&lt;br /&gt;
&lt;br /&gt;
One thing I really like about 
Habitat is that it provides many of the advantages of containers w/out 
forcing you to use them. You can get many of the touted advantages of 
containers minus the complexity with a simple Linux chroot. A Habitat 
package, once installed, is essentially a chrooted application. Docker 
et al make most sense to me when you are working on top of a system like
 Kubernetes or Mesos. W/out that tooling in place, you can be in for a 
lot of pain and needless complexity. However, if you are on the Docker 
train Habitat supports exporting packages to Docker and the ACI format.&lt;br /&gt;
&lt;br /&gt;
I still have a lot of open questions. &lt;br /&gt;
&lt;ul style=&quot;text-align: left;&quot;&gt;
&lt;li&gt;How will Habitat work on Windows? Will it be possible to isolate packages w/out the chroot facilities that Linux has? &lt;/li&gt;
&lt;li&gt;Does Habitat obsolete Chef or should they be used in concert? I suspect the former.&lt;/li&gt;
&lt;li&gt;How does one set global settings like firewall rules and sysctls?&amp;nbsp;&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
On this last point, Adam Jacob told me that global settings might best be handled by a separate Habitat service.&lt;br /&gt;
&lt;br /&gt;
In conclusion, I am very excited about Habitat and I think it is worth your time to take a look.&lt;br /&gt;
&lt;br /&gt;
P.S.
 I am very happy to see Habitat is written in Rust. Having spent part of
 the last year learning Go, it is very exciting to read source code that
 has &lt;b&gt;dangerous&lt;/b&gt; features like pattern matching, generics, and monads.&lt;br /&gt;
&lt;br /&gt;
P.P.S.
 After some time away from the Chef community, it is great to see many 
of my old friends in the Habitat Slack channel. Ohai! &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;&lt;/div&gt;
</content><link rel='replies' type='application/atom+xml' href='http://devopsanywhere.blogspot.com/feeds/5066741643006666322/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://devopsanywhere.blogspot.com/2016/06/why-i-am-excited-about-habitat.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1083699665345453745/posts/default/5066741643006666322'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1083699665345453745/posts/default/5066741643006666322'/><link rel='alternate' type='text/html' href='http://devopsanywhere.blogspot.com/2016/06/why-i-am-excited-about-habitat.html' title='Why I am excited about Habitat'/><author><name>Anonymous</name><uri>http://www.blogger.com/profile/10631977500882582704</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1083699665345453745.post-8559354551291401243</id><published>2016-04-16T08:45:00.001-07:00</published><updated>2016-04-17T20:05:19.222-07:00</updated><title type='text'>Give your CLI Tool a ReSTful API</title><content type='html'>&lt;div dir=&quot;ltr&quot; style=&quot;text-align: left;&quot; trbidi=&quot;on&quot;&gt;
I have some rough ideas about how to use some of the concepts of &lt;a href=&quot;https://en.wikipedia.org/wiki/Representational_state_transfer&quot;&gt;ReSTful APIs&lt;/a&gt; to improve command-line tools. I do not have a lot of expertise in building ReSTful APIs.&amp;nbsp; I would love your feedback!&lt;br /&gt;
&lt;br /&gt;
Lately I have been working with Azure&#39;s new Resource Management (ARM) API and been quite impressed by its behavior. Mind you, many other ReSTful APIs may behave similarly but Azure&#39;s is the first I have had similar experience with. A neat aspect of Azure&#39;s ARM API is that it is mostly asynchronous and how it lets you monitor the status of a long-running operation.&lt;br /&gt;
Let&#39;s say I want to create or update a VirtualMachine (azure parlance for an EC2 instance). I would take the following steps:&lt;br /&gt;
&lt;br /&gt;
&lt;ol style=&quot;text-align: left;&quot;&gt;
&lt;li&gt;Build up an object describing the virtual machine to be created&lt;/li&gt;
&lt;li&gt;Submit HTTP PUT request, with the serialized virtual machine object in the body of the request&lt;/li&gt;
&lt;li&gt;Receive back a response w/ a status code and json document representing the virtual machine if the initial request was successful.&lt;/li&gt;
&lt;/ol&gt;
&lt;br /&gt;
This response comes back more or less asynchronously. Azure sends back a 204 response if the request was accepted, i.e. passed validation and can be fulfilled.&amp;nbsp; The only blocking part here is the validation of supplied parameters. The returned json document contains a property &#39;status&#39; that indicates the provisioning status of the new virtual machine. This status will initially be &quot;InProgress&quot; and will eventually become &quot;Succeeded&quot; once the virtual machine has started. I can send Azure GET requests for the VM to check for the &quot;Succeeded&quot; status. &lt;a href=&quot;https://twitter.com/milosgajdos&quot;&gt;HTTP&#39;s PUT&lt;/a&gt; method is particularly interesting because it is an idempotent operation.&lt;br /&gt;
&lt;br /&gt;
Now let&#39;s look at deleting a VM.&lt;br /&gt;
&lt;ol style=&quot;text-align: left;&quot;&gt;
&lt;li&gt;Submit a DELETE request for a given VM&lt;/li&gt;
&lt;li&gt;Receive a response that indicates whether the request was accepted and a URL to query for the status of the operation&lt;/li&gt;
&lt;li&gt;Query the status url and receive a json document that indicates the status of the delete operation. The status will be &quot;Succeeded&quot; once the deletion completes.&lt;/li&gt;
&lt;/ol&gt;
&lt;br /&gt;
The status URL is only valid for a limited period of time after which GET operations will return a 400.&lt;br /&gt;
&lt;br /&gt;
What I really like about this ReST API is that I can execute fairly complex operations that complete (mostly) asynchronously. Could we create CLI tools that operated in a similar fashion?&lt;br /&gt;
&lt;br /&gt;
A common task that I automate for cloud instances is the formatting and mounting mounting of ephemeral and longer-lived nfs volumes. This task can be fairly complex as it can involve LVM volumes, software RAID (mdadm), and possibly an encrypted filesystem. This operation task can also take some time to complete depending on the sizes of disks involved and the filesystem used. For example, it is not uncommon for this task to take several minutes when using ext4. I currently use a fairly complex Chef recipe to handle this task. It would be very interesting if we could use an external cli tool to handle this operation for us. Let&#39;s call this imaginary tool &quot;cvol&quot; for cloud volume. There are a lot of knobs and switches when it comes to managing filesystems so it is nigh impossible that I would be able to write all the possible options nor want compose a shell command that uses them. Rather, let&#39;s just pass cvol a json document describing the operation and including all the relevant parameters.&lt;br /&gt;
&lt;br /&gt;
This document describes a volume mounted at /mnt/data that uses all ephemeral volumes in a RAID 0 configuration. Additionally, the volume is encrypted and formatted w/ xfs.&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;{ &quot;mountpoint&quot;: &quot;/mnt/data&quot;,&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;&amp;nbsp;&amp;nbsp; &quot;use_all_ephemeral&quot;: true,&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;&amp;nbsp;&amp;nbsp; &quot;raid&quot;: 0,&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;&amp;nbsp;&amp;nbsp; &quot;encrypted&quot;: true,&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;&amp;nbsp;&amp;nbsp; &quot;encryption&quot;: {&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &quot;password&quot;: &quot;123456789&quot;,&lt;/span&gt;&lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp; &quot;format&quot;: &quot;luks&quot;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;&amp;nbsp;&amp;nbsp; },&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;&amp;nbsp;&amp;nbsp; &quot;format&quot;: &quot;xfs&quot; &lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;}&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;&lt;br /&gt;&lt;/span&gt;
&lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;$ cvol create-or-update -i format_my_disks.json&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
cvol would respond immediately w/ a json document. That doesn&#39;t mean that cvol is finished. It would have to fork itself and detach from the session to actually do the work.&lt;br /&gt;
&lt;br /&gt;
{ &quot;status&quot;: 204,&lt;br /&gt;
&amp;nbsp;&amp;nbsp; &quot;operationId&quot;: &quot;123456&quot;,&lt;br /&gt;
&amp;nbsp;&amp;nbsp; &quot;port&quot;: 9999 &lt;br /&gt;
&amp;nbsp;&amp;nbsp; &quot;state&quot;: &quot;started&quot;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
To check the status of the operation&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;$ cvol get --id 123456 --port 9999&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;&lt;br /&gt;&lt;/span&gt;
&lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;&lt;br /&gt;&lt;/span&gt;
&lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;{ &quot;status&quot;: 200,&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;&amp;nbsp;&amp;nbsp; &quot;operationId&quot;: &quot;123456&quot;,&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;&amp;nbsp;&amp;nbsp; &quot;state&quot;: &quot;succeeded&quot;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;}&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
`cvol get` would tell us the status of the operation. For this to actually work, our first invocation of cvol would have to be still running in the background with and embedded http server for some finite period after the operation has completed. cvol would not run indefinitely in the background as that would be a crazy waste of resources. Let&#39;s say it stays in memory for 3 minutes after the operation has completed. What gets tricky is if the cli tool dies mid-operation. How would we know? I don&#39;t have a good solution for this.&lt;br /&gt;
&lt;br /&gt;
Let&#39;s look at cvol&#39;s &lt;a href=&quot;https://www.gnu.org/software/coreutils/manual/html_node/shred-invocation.html&quot;&gt;shred&lt;/a&gt; operation. This operation not only unmounts a volume but also securely&lt;br /&gt;
deletes all files stored there. Shredding a volume can take quite while.&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;$ cvol shred /mnt/data --iterations=10&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
returns&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;{&quot;status&quot;: 204,&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;&amp;nbsp; &quot;operationId&quot;: &quot;0913256&quot;,&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;&amp;nbsp; &quot;port&quot;: 8777,&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;&amp;nbsp; &quot;state&quot;: &quot;started&quot;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;}&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
To check the current status:&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;$ cvol get --id 0913256 --port 8777&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
After the shred operation completes, `cvol get --id 0913256` returns a response with the property&lt;br /&gt;
&quot;succeeded&quot;.&lt;br /&gt;
&lt;br /&gt;
Making our cli tool ReSTful adds a significant amount of overhead. It requires embedding an http server into the tool and forcing the cli to use at least two threads; one thread to answer requests about the status of an operation and another to do the actual work. Why go to all this trouble? The primary reason is that it might make it easier to create higher-level building blocks for managing systems.&lt;br /&gt;
&lt;br /&gt;
&lt;h3 style=&quot;text-align: left;&quot;&gt;
Chef is Awesome but Dependencies Suck&lt;/h3&gt;
&lt;br /&gt;
I have been a happy Chef user for over six years and I still think it is the best configuration management tool out there. I do not, however, think it is the one true configuration management system for all time, forever. There were many before it and there will be many after it. Further, ruby dependencies drive me nuts (as do Python and Node.js dependencies). Having to pull dependencies down from Ruby gems (or a mirror) and the compiler toolchain in place to build them is a continual headache. Having a terrible deployment story is somewhat endemic to dynamic languages. This is frustrating because my configuration management tool should be easier to deploy than my application code.&lt;br /&gt;
&lt;br /&gt;
&lt;i&gt;&quot;But, c&#39;mon just use Ansible&lt;/i&gt;,&quot; you say. &quot;&lt;i&gt;No server-side deps!&lt;/i&gt;&quot; Ansible definitely is an easy tool to get started with but I would never, ever provision 1,000 EC2 instances with it for reasons of performance. I have done that with Chef and it has worked flawlessly. Further, you hit some pretty hard limits on code reuse early on. Writing the equivalent of cvol in Ansible would be many times longer and bug-prone. And again, that code would live and die w/ Ansible.&lt;br /&gt;
&lt;br /&gt;
With some discipline, you can write a Chef LWRP to the handle complex tasks like the kind cvol would w/out using requiring gems external to Chef. My concern here is that this Ruby code will live and die with Chef. We won&#39;t reuse it when the new CTO decides to dump Chef for a hot new configuration management tool written in Haskell. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
ReSTful cli tools would be easy to integrate with Chef, Ansible, and whatever other CM tool comes down the pike. &lt;br /&gt;
&lt;br /&gt;
&lt;h3 style=&quot;text-align: left;&quot;&gt;
Implementation Ideas:&lt;/h3&gt;
&lt;br /&gt;
A ReSTful CLI tool would ideally be a single static binary. Obviously, Go would be a good choice for this but Python tools compiled w/ &lt;a href=&quot;https://pex.readthedocs.org/en/stable/&quot;&gt;PEX&lt;/a&gt; or PyInstaller would also be viable options. The CLI tool would require an embedded HTTP/RPC server to respond to GET requests. The tool would also require multiple threads in order to both respond to status requests and get actual work done.&amp;nbsp; Supporting TLS would be a big mistake as it would add a lot of overhead. Instead, a ReSTful CLI application should only listen on 127.0.0.1. &lt;br /&gt;
&lt;br /&gt;
Note that HTTP isn&#39;t essential here. We could easily use another RPC protocol. The important parts that I want to adopt are:&lt;br /&gt;
&lt;ol style=&quot;text-align: left;&quot;&gt;
&lt;li&gt;ability to describe an arbitrarily complex operation using a document rather than cobbling together an endless chain of command-line arguments and flags&lt;/li&gt;
&lt;li&gt;Ability to execute idempotent operations with a cli like the &lt;a href=&quot;https://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html#sec9.6&quot;&gt;HTTP PUT &lt;/a&gt;operation &lt;/li&gt;
&lt;li&gt;Option to execute an operation synchronously or asynchronously&lt;/li&gt;
&lt;/ol&gt;
I have to admit that #3 could be pretty challenging. We could get a lot of value out of just #1 and #2.&lt;br /&gt;
&lt;br /&gt;
&lt;h3 style=&quot;text-align: left;&quot;&gt;
Closing Thoughts&lt;/h3&gt;
&lt;br /&gt;
These are some very, very rough ideas and I would love your feedback on them. &lt;br /&gt;
&lt;br /&gt;
Thanks to &lt;a href=&quot;https://twitter.com/milosgajdos&quot;&gt;Milos Gajdos&lt;/a&gt; for reviewing a draft of this. &lt;br /&gt;
&lt;h3&gt;
Notes:&lt;/h3&gt;
For the Docker heads out there who believe we will all have immutable servers. Our application instances may be immutable however we will always have to configure the cloud instances or bare metal that host those docker images. That problem will not go away.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;&lt;/div&gt;
</content><link rel='replies' type='application/atom+xml' href='http://devopsanywhere.blogspot.com/feeds/8559354551291401243/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://devopsanywhere.blogspot.com/2016/04/what-if-cli-tools-had-restful-apis.html#comment-form' title='14 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1083699665345453745/posts/default/8559354551291401243'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1083699665345453745/posts/default/8559354551291401243'/><link rel='alternate' type='text/html' href='http://devopsanywhere.blogspot.com/2016/04/what-if-cli-tools-had-restful-apis.html' title='Give your CLI Tool a ReSTful API'/><author><name>Anonymous</name><uri>http://www.blogger.com/profile/10631977500882582704</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>14</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1083699665345453745.post-7274671090797516681</id><published>2015-03-01T11:49:00.001-08:00</published><updated>2015-03-09T09:02:42.757-07:00</updated><title type='text'>Scala meet DevOps, DevOps meet Scala</title><content type='html'>&lt;div dir=&quot;ltr&quot; style=&quot;text-align: left;&quot; trbidi=&quot;on&quot;&gt;
&lt;h2 style=&quot;text-align: center;&quot;&gt;
&lt;span style=&quot;font-weight: normal;&quot;&gt;
&amp;nbsp;Alternate Title: Scala Shines Where Go Stumbles &lt;/span&gt;&lt;/h2&gt;
It&#39;s embarrassing that I haven&#39;t blogged in over 2 years. Let&#39;s hope I can change. In the &lt;a href=&quot;http://devopsanywhere.blogspot.it/2013/11/why-im-learning-java.html&quot;&gt;last time we spoke&lt;/a&gt;, I had begun learning Java. Things haven&#39;t gone exactly as planned. I got diverted from that plan and spent quite a bit of time becoming reacquainted with Python and JavaScript. In the last four months however I have spent a lot of time on the JVM, just not with Java. In my $DAYJOB, I have had the opportunity to learn scala. While the learning curve was more than a little steep, I am really enjoying working in it and I think it is a perfect fit for many of the problems we in devops-land work on.&lt;br /&gt;
&lt;h3 style=&quot;text-align: left;&quot;&gt;
Scala the Language&lt;/h3&gt;
Getting started with a Scala was a little rough. First off, I found the official &lt;a href=&quot;http://scala-lang.org/documentation/&quot;&gt;scala documentation dense and bewildering&lt;/a&gt;. It is nothing near as straightforward as the Python documentation nor the &lt;a href=&quot;http://docs.oracle.com/javase/tutorial/java/nutsandbolts/index.html&quot;&gt;official Java tutorials&lt;/a&gt; from Oracle. It reminds me more than a little bit of the Ruby documentation landscape. However, most Ruby newbs starts with the wonderful &lt;a href=&quot;http://ruby-doc.com/docs/ProgrammingRuby/&quot;&gt;PickAxe book&lt;/a&gt;, freely available online. There is a wonderful counterpart to the PickAxe in &lt;a href=&quot;http://www.horstmann.com/scala/index.html&quot;&gt;Scala for the impatient.&lt;/a&gt; I have really, really enjoyed this book. Sadly, only the first 100 pages are available for free. The remaining 300 pages are well worth $30.00. Scala for the Impatient does have one ginormous fault, it doesn&#39;t cover &lt;a href=&quot;http://akka.io/&quot;&gt;akka&lt;/a&gt;! We&#39;ll see why akka is important later. I found a nice, concise intro to Akka and Futures in the &lt;a href=&quot;http://shop.oreilly.com/product/0636920026914.do&quot;&gt;Scala Cookbook from O&#39;Reilly&lt;/a&gt;. It kind of sucks that you need to spend ~$60 for a decent introduction to the language. &lt;br /&gt;
&lt;br /&gt;
While the documentation story isn&#39;t great, I was very happy to find that the Scala community embraces the REPL. When I code Ruby and Python, I rely heavily on Pry and IPython to explore APIs and libraries. Often as not, I use boto from IPython to interact with AWS rather than using the AWS console. I have learned HTTP and ReST basics using Faraday and Requests. Unlike Java or golang (&lt;i&gt;last I checked&lt;/i&gt;), Scala works really well with the REPL in large part because everything is an expression, i.e. every line returns a value. Further, scala&#39;s build tool sbt has a wonderful command &lt;span style=&quot;font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;&quot;&gt;`sbt console`&lt;/span&gt; that starts a repl with all your dependencies available, including your own code. It works the same as running `bundle exec pry` or `bundle exec irb`&lt;br /&gt;
&lt;br /&gt;
One of the complaints I had heard about scala is that the type system is very complex and hard to use. I haven&#39;t found that to be the case. In fact I have found the type system to be quite helpful in diagnosing problems and as a baseline form of documentation. That said I am still learning how to use the type system. I still haven&#39;t figured out what contravariants, existential types, structured types are. I do find Generics immensely useful as an end user. I love that I can use map, filter, fold, sum, etc. on virtually any type. To my knowledge this is not possible in Golang, and this saddens me.&lt;br /&gt;
&lt;br /&gt;
Dear Gophers, is it true that to map over an collection of ints I need MapInt, for doubles MapDouble, for bytes, MapBytes, and so on? Please let me know if I am mistaken.&lt;br /&gt;
&lt;br /&gt;
Here is a Python script that I frequently invoke in Python&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;&quot;&gt;conn = boto.connect_ec2()&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;&quot;&gt;reservations = conn.get_all_instances(instance_ids=instances) # instances in cmd line arg&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;&quot;&gt;for res in reservations:&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; for instance in res.instances:&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; print(&quot;Terminating instance %s&quot; % instance.id)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; try:&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; instance.terminate()&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; except EC2ResponseError as e:&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; print(&quot;Termination of instance %s encountered error&amp;nbsp; &lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; EC2ResponseError with &quot;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &quot;message %s&quot; % (instance.id, e.message))&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;&quot;&gt;&lt;br /&gt;&lt;/span&gt;
I assume the golang equivalent would look similar except that you would have to manually check for `nils`.&lt;br /&gt;
&lt;br /&gt;
Here is how I would write the same in scala.&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;&quot;&gt;Ec2.instances(instancesIds).foreach { i =&amp;gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;&quot;&gt;&amp;nbsp; &amp;nbsp; try&amp;nbsp; {&amp;nbsp;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; EC2.terminate(i)&amp;nbsp;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; } catch { e: EC2ResponseError =&amp;gt; s&quot;killing instance _ failed&quot;}&lt;/span&gt;&lt;br /&gt;
&amp;nbsp;}&lt;br /&gt;
&amp;nbsp; &lt;br /&gt;
Buyer-beware, I haven&#39;t tested out this code yet. For any Scalaists, that may be reading, is there a scala-environment/tool that I could use for writing scripts like this?&lt;br /&gt;
&lt;br /&gt;
I like type-checking. Sure, a good test suite will keep you safe as long you run it each time before you make your commit. That said, you know how many times I have visited a file after running the tests and accidentally injected an errant &#39;w&#39;, &#39;s&#39;, or &lt;tab&gt; before committing? Far more times than I care to admit. Sure these things are caught in CI but I don&#39;t want to wait that long.&lt;/tab&gt;&lt;br /&gt;
&lt;br /&gt;
While I may like static typing, I LOVE regular expressions and internal DSLs.&lt;br /&gt;
&lt;br /&gt;
I recently discovered that pattern matching and regular expressions are a match made in Heaven. check this out. &lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;&quot;&gt;val pattern = &quot;([0-9]+) ([a-z]+)&quot;.r&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;&quot;&gt;val pattern(num, item) = &quot;99 bottles&quot;&amp;nbsp;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;&quot;&gt;# result &amp;nbsp;&amp;nbsp; num: String = 99
item: String = bottles&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
Fanboyism aside, what I do find challenging about the scala language is the sheer amount of goddamn syntax. There is just so much language to learn, so many features to grok. Like Ruby and the lisps, successful scala teams need to limit the scope of how much of scala they use to keep their projects from becoming unknowable messes. For example, in the Ruby world there are a lot of conventions on when and how to use monkey patches. &lt;br /&gt;
&lt;br /&gt;
Sadly, Emacs support for Scala didn&#39;t work out of the box for me. There is the popular Ensime mode but I couldn&#39;t get it working in 4 hours. I hope to revisit it at a later time. I have been using the community edition of Intellij and it has worked better than I care to admit. You probably can code scala w/ bare Emacs or vim but it doesn&#39;t compare to my workflow w/ ELPy or the wealth of ruby modes.&lt;br /&gt;
&lt;br /&gt;
&lt;h3&gt;
The Community&lt;/h3&gt;
&lt;br /&gt;
My experiences with the community so far have been quite positive. I have gotten a lot of assistance from the fine people on the #scala IRC channel, particularly lmm, Tpolecat, kueller, and others. It not as warm and as fuzzy as the Ruby community, but well few communities are.&lt;br /&gt;
&lt;h3&gt;
Where Scala fits in to DevOps?&lt;/h3&gt;
Increasingly in DevOps-land, I find myself writing operations-related webservices and command-line utilities. I have been writing Chef cookbooks for quite some time now and too often I find myself adding log rotation via logrotate, exernal monitoring via collectd, metrics gathering via statsd, etc. One day I came upon the wonderful &lt;a href=&quot;http://dropwizard.io/&quot;&gt;DropWizard&lt;/a&gt; framework which incorporated healthchecks, metrics publishing, powerful logging features into the application itself. When you think about, it really makes sense for the application to report its own health, gather its own metrics, rather than external applications trying to reach into its guts to figure out if its screwed up. Now that I am writing my own webservicces, I&#39;ll be damned if some poor sap has to pry it apart to see if it&#39;s working properly.&lt;br /&gt;
&lt;br /&gt;
To put it succinctly, scala is awesome for building operations-friendly services. You absolutely can write great services in Dropwizard with Java, but with a heck of a lot more boilerplate.&lt;br /&gt;
&lt;br /&gt;
On a recent weekend I created an Akka Actor that periodically wakes up, invokes a long running task. If it wakes up and the task is still running, the task is not invoked again. What I love about this this actor is that it responds to healthchecks! The magic here is that since the long operation runs in a Future, it doesn&#39;t block the actor from responding to health checks. I can deploy this app with just the JVM. To do the same with Python would require Celery&amp;nbsp;+ Redis or RabbitMQ. Also I don&#39;t know if there is a way for Celery workers to respond to healthchecks. If there is, let me know! I doubt it&#39;s possible because of uhh, you know, the &lt;a href=&quot;https://wiki.python.org/moin/GlobalInterpreterLock&quot;&gt;GIL&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;pre style=&quot;-webkit-text-stroke-width: 0px; color: black; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: pre-wrap; widows: auto; word-spacing: 0px; word-wrap: break-word;&quot;&gt;class BryansActor extends Actor with RegisteredHealthCheckActor {

  import context.dispatcher
  val id = number
  val period = 4000
  val tick = context.system.scheduler.schedule(400 millis, period millis, self, &quot;tick&quot;)
  case class LongOperationResult(result: Double)
  var longOperationRunning = false

  override def postStop() = tick.cancel()

  def receive = {
    case &quot;tick&quot; =&amp;gt;
      if (longOperationRunning == false) {
        println(&quot;start long operation&quot;)
        Future[LongOperationResult] {
          val start = System.currentTimeMillis()
          Thread.sleep(10000)
          new longResult(System.currentTimeMillis() - start)
        } pipeTo self
        longOperationRunning = true
      } else {
        println(&quot;future still running, nothing to do&quot;)
      }

    case longOperationResult(runtime) =&amp;gt;
      longOperationRunning = false
      println(s&quot;Runtime was $runtime&quot;)
        // Determine our health
    case GetHealth =&amp;gt; sender ! HealthInfo(&quot;bryans-actor&quot;, HealthState.OK, &quot;doing great!&quot;)
  }


}&lt;/pre&gt;
&lt;pre style=&quot;-webkit-text-stroke-width: 0px; color: black; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: pre-wrap; widows: auto; word-spacing: 0px; word-wrap: break-word;&quot;&gt;&amp;nbsp;&lt;/pre&gt;
&lt;pre style=&quot;-webkit-text-stroke-width: 0px; color: black; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: pre-wrap; widows: auto; word-spacing: 0px; word-wrap: break-word;&quot;&gt;&lt;/pre&gt;
There is actually a lot more to a great service, things like backpressure and circuit breakers but that&#39;s a whole other blog post. Dear Gophers, is there a golang library that supports actors? The closest I found in my brief research was go-kite.&lt;br /&gt;
&lt;br /&gt;
Friends of mine know that I have long been an admirer of Erlang and more specifically the OTP framework.&amp;nbsp; As far as I can tell, Akka has done a decent job stealing many of the great ideas from Erlang so that JVM schmucks like me can take advantage of them. Actors really fit how my brain works. I have written a fair amount of asynchronous code in javascript, w/ and w/out Promises and I never found them as easy to work with as actors.&lt;br /&gt;
&lt;br /&gt;
In addition to the Akka DSL, I quite like the &lt;a href=&quot;http://spray.io/&quot;&gt;Spray DSL&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;pre style=&quot;-webkit-text-stroke-width: 0px; background-color: whitesmoke; border-radius: 4px; border: 1px solid rgba(0, 0, 0, 0.14902); color: #333333; display: block; font-family: Menlo, Monaco, &#39;Courier New&#39;, monospace; font-size: 12.025px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: 18px; margin: 0px 0px 1em; orphans: auto; overflow: auto; padding: 8.5px; text-align: start; text-indent: 0px; text-transform: none; white-space: pre; widows: auto; word-break: break-all; word-spacing: 0px; word-wrap: normal;&quot;&gt;&lt;span class=&quot;k&quot; style=&quot;font-weight: bold;&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot; style=&quot;color: #555555;&quot;&gt;spray.routing.SimpleRoutingApp&lt;/span&gt;

&lt;span class=&quot;k&quot; style=&quot;font-weight: bold;&quot;&gt;object&lt;/span&gt; &lt;span class=&quot;nc&quot; style=&quot;color: #445588; font-weight: bold;&quot;&gt;Main&lt;/span&gt; &lt;span class=&quot;k&quot; style=&quot;font-weight: bold;&quot;&gt;extends&lt;/span&gt; &lt;span class=&quot;nc&quot; style=&quot;color: #445588; font-weight: bold;&quot;&gt;App&lt;/span&gt; &lt;span class=&quot;k&quot; style=&quot;font-weight: bold;&quot;&gt;with&lt;/span&gt; &lt;span class=&quot;nc&quot; style=&quot;color: #445588; font-weight: bold;&quot;&gt;SimpleRoutingApp&lt;/span&gt; &lt;span class=&quot;o&quot; style=&quot;font-weight: bold;&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;k&quot; style=&quot;font-weight: bold;&quot;&gt;implicit&lt;/span&gt; &lt;span class=&quot;k&quot; style=&quot;font-weight: bold;&quot;&gt;val&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;system&lt;/span&gt; &lt;span class=&quot;k&quot; style=&quot;font-weight: bold;&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nc&quot; style=&quot;color: #445588; font-weight: bold;&quot;&gt;ActorSystem&lt;/span&gt;&lt;span class=&quot;o&quot; style=&quot;font-weight: bold;&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot; style=&quot;color: #bb8844;&quot;&gt;&quot;my-system&quot;&lt;/span&gt;&lt;span class=&quot;o&quot; style=&quot;font-weight: bold;&quot;&gt;)&lt;/span&gt;

  &lt;span class=&quot;n&quot;&gt;startServer&lt;/span&gt;&lt;span class=&quot;o&quot; style=&quot;font-weight: bold;&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;interface&lt;/span&gt; &lt;span class=&quot;k&quot; style=&quot;font-weight: bold;&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot; style=&quot;color: #bb8844;&quot;&gt;&quot;localhost&quot;&lt;/span&gt;&lt;span class=&quot;o&quot; style=&quot;font-weight: bold;&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;port&lt;/span&gt; &lt;span class=&quot;k&quot; style=&quot;font-weight: bold;&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot; style=&quot;color: #009999;&quot;&gt;8080&lt;/span&gt;&lt;span class=&quot;o&quot; style=&quot;font-weight: bold;&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot; style=&quot;font-weight: bold;&quot;&gt;{&lt;/span&gt;
    &lt;a href=&quot;http://spray.io/documentation/1.1-SNAPSHOT/spray-routing/path-directives/path/&quot; style=&quot;-webkit-transition: opacity 0.2s linear; color: #0088cc; text-decoration: none; transition: opacity 0.2s linear;&quot;&gt;&lt;span class=&quot;n&quot;&gt;path&lt;/span&gt;&lt;/a&gt;&lt;span class=&quot;o&quot; style=&quot;font-weight: bold;&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot; style=&quot;color: #bb8844;&quot;&gt;&quot;hello&quot;&lt;/span&gt;&lt;span class=&quot;o&quot; style=&quot;font-weight: bold;&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot; style=&quot;font-weight: bold;&quot;&gt;{&lt;/span&gt;
      &lt;a href=&quot;http://spray.io/documentation/1.1-SNAPSHOT/spray-routing/method-directives/get/&quot; style=&quot;-webkit-transition: opacity 0.2s linear; color: #0088cc; text-decoration: none; transition: opacity 0.2s linear;&quot;&gt;&lt;span class=&quot;n&quot;&gt;get&lt;/span&gt;&lt;/a&gt; &lt;span class=&quot;o&quot; style=&quot;font-weight: bold;&quot;&gt;{&lt;/span&gt;
        &lt;a href=&quot;http://spray.io/documentation/1.1-SNAPSHOT/spray-routing/route-directives/complete/&quot; style=&quot;-webkit-transition: opacity 0.2s linear; color: #0088cc; text-decoration: none; transition: opacity 0.2s linear;&quot;&gt;&lt;span class=&quot;n&quot;&gt;complete&lt;/span&gt;&lt;/a&gt; &lt;span class=&quot;o&quot; style=&quot;font-weight: bold;&quot;&gt;{&lt;/span&gt;
          &lt;span class=&quot;o&quot; style=&quot;font-weight: bold;&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;h1&lt;/span&gt;&lt;span class=&quot;o&quot; style=&quot;font-weight: bold;&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;nc&quot; style=&quot;color: #445588; font-weight: bold;&quot;&gt;Say&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;hello&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;to&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;spray&lt;/span&gt;&lt;span class=&quot;o&quot; style=&quot;font-weight: bold;&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;h1&lt;/span&gt;&lt;span class=&quot;o&quot; style=&quot;font-weight: bold;&quot;&gt;&amp;gt;&lt;/span&gt;
        &lt;span class=&quot;o&quot; style=&quot;font-weight: bold;&quot;&gt;}&lt;/span&gt;
      &lt;span class=&quot;o&quot; style=&quot;font-weight: bold;&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;o&quot; style=&quot;font-weight: bold;&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;o&quot; style=&quot;font-weight: bold;&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;o&quot; style=&quot;font-weight: bold;&quot;&gt;}&lt;/span&gt;&lt;/pre&gt;
I am also itching to try out the Slick DSL which looks a little bit like the JOOQ library in Java.&lt;br /&gt;
&lt;br /&gt;
Remember that how I said I love DSLs? I should have said that &lt;a href=&quot;http://martinfowler.com/bliki/DomainSpecificLanguage.html&quot;&gt;I love internal DSLs&lt;/a&gt;. I spend 90% of my day working in DSLs, some of which I&#39;ll decline to name. I love Chef for its &lt;i&gt;internal DSL&lt;/i&gt; that gives me the full power of Ruby. I&#39;ll decline to name some other tools which I use that have external DSLs in YAML, JSON, or XML. I find these tools exceptionally easy to get started with but inevitably I find them very unexpressive and constraining. Often as not, I end up writing plugins in python/ruby/powershell for tasks as simple as list comprehensions.&lt;br /&gt;
&lt;br /&gt;
So what sucks about Scala for devops? As an aside, at FOSDEM 2012 I asked a group of Rubyists why Ruby what 5 different popular testing libraries. Gareth Rushgrove answered &quot;Because in Ruby there are 5 different libraries for everything!&quot; So far this also rings true in scala-land. There are 5-6 different popular libraries working with JSON, for instance. Sadly, I have yet to find a single sane one for working with YAML after wasting a morning trying to get SnakeYAML to do what I want. Dear reader, if you can point me to easy path for working with YAML and Scala, I would much appreciate it.&lt;br /&gt;
&lt;h3 style=&quot;text-align: left;&quot;&gt;
Conclusion &lt;/h3&gt;
On the whole, scala is &lt;i&gt;hard&lt;/i&gt;er but &lt;i&gt;simpler&lt;/i&gt;. Rich Hickey of Clojure fame gave a great presentation entitled &lt;a href=&quot;http://www.infoq.com/presentations/Simple-Made-Easy&quot;&gt;&quot;Simple made Easy.&quot;&lt;/a&gt; The gist is that what&#39;s easy right now is just what&#39;s most familiar to you. Simpler and more maintainable solutions may take more initial investment. That mess of for loops may be easy to write, but it&#39;s more complex and thus &lt;i&gt;expensive&lt;/i&gt; to maintain over time.&lt;br /&gt;
&lt;br /&gt;
I feel that too many people bypass Scala and languages like it because they perceive them as too hard. I call this &lt;b&gt;The Tyranny of 15 minutes&lt;/b&gt;. Too often in Software-land, people focus on technologies that they can get comfortable with in the course of their lunch hour. This pisses me off. It&#39;s one thing if you love Golang because it fits your problem space and your head but another if you chose it for your next project because you got through the &lt;a href=&quot;http://shop.oreilly.com/product/0636920026914.do&quot;&gt;Tour of Go&lt;/a&gt; in an afternoon. We&#39;re engineers folks, &quot;it&#39;s too hard&quot; is not a valid excuse. You&#39;ll be maintaining that code - or someone else will - 100x longer than it took for you to learn the language.&lt;br /&gt;
&lt;br /&gt;
I have no idea how scala will fare in the programming language popularity wars. My crystal ball is very cloudy. I do think it is worth your time to learn. I hope to spend a lot more time with Scala over the next few months. I&#39;ll let you know how it goes.&lt;br /&gt;
&lt;br /&gt;
P.S. This post may sound a little harsh on Golang. I believe that Go is a very productive and powerful tool. The virtues of Golang are also tradeoffs. I just hope people are of aware of them. Also, I am not an expert on Golang, so please correct any incorrect statements that I may have made!&lt;br /&gt;
&lt;br /&gt;
P.S.S. I didn&#39;t mention Clojure once in this post and that&#39;s because I have yet to spend any time with it. If you have code examples for similar problems, I would love to see them.&lt;/div&gt;
</content><link rel='replies' type='application/atom+xml' href='http://devopsanywhere.blogspot.com/feeds/7274671090797516681/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://devopsanywhere.blogspot.com/2015/03/scala-meet-devops-devops-meet-scala.html#comment-form' title='32 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1083699665345453745/posts/default/7274671090797516681'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1083699665345453745/posts/default/7274671090797516681'/><link rel='alternate' type='text/html' href='http://devopsanywhere.blogspot.com/2015/03/scala-meet-devops-devops-meet-scala.html' title='Scala meet DevOps, DevOps meet Scala'/><author><name>Anonymous</name><uri>http://www.blogger.com/profile/10631977500882582704</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>32</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1083699665345453745.post-3559572768396595254</id><published>2014-01-10T14:48:00.001-08:00</published><updated>2014-01-13T08:55:39.480-08:00</updated><title type='text'>You Should Start a Technical Podcast</title><content type='html'>&lt;div dir=&quot;ltr&quot; style=&quot;text-align: left;&quot; trbidi=&quot;on&quot;&gt;
In summer of 2010, my wife and I moved from a Kathmandu, Nepal, where I had worked for a &lt;a href=&quot;http://www.olenepal.org/&quot;&gt;kickass technology startup&lt;/a&gt; to Rome, Italy, a city with practically no technology scene at all. We had moved for the sake of my wife&#39;s career with the United Nations. Prior to the move, I had worked in a variety of IT positions but once in Rome I found a job as Linux system administrator. While I was lucky to find to a job relevant to my career I felt very isolated. I stared listening to the amazing &lt;a href=&quot;http://www.devopscafe.org/&quot;&gt;DevOps Cafe&lt;/a&gt; podcast, and my sense of isolation only got worse. In a quiet, cry for help, I started my own podcast &lt;a href=&quot;http://foodfightshow.org/&quot;&gt;FoodFightShow&lt;/a&gt;, focused on Devops, linux, and general software geekery.&lt;br /&gt;
&lt;br /&gt;
That cry for help was heard! FoodFightShow now has over 100 episodes and over 125,000 downloads. I have to credit my cohost,&lt;a href=&quot;http://nathenharvey.com/&quot;&gt; Nathen Harvey&lt;/a&gt;, for a large part of the show&#39;s, success. I like to think that FoodFightShow has benefited my professional community of linux system administrators but I &lt;b&gt;know&lt;/b&gt; that it has benefited me. The show has really expanded my professional network and given me an amazing peer group.&amp;nbsp; Too often people discount the importance of a peer group, but I think it is very helpful for maintaining one&#39;s motivation and focus. Additionally, for whatever reason, I have found that a number of people accord my opinions with greater weight simply because I cohost a podcast. One of my show&#39;s sponsored paid for me to attend a conference in San Francisco where I met my current, super awesome&amp;nbsp;&lt;a href=&quot;http://cyclecomputing.com/&quot;&gt;employer&lt;/a&gt;. Most important of all, I have learned a lot by doing the show and really, really enjoyed it. I think that &lt;b&gt;you&lt;/b&gt; (yes you!)&lt;b&gt; &lt;/b&gt;should start a technical podcast of your own, be it about IOS development, FPGA design, robotics, or advanced HVAC.&lt;br /&gt;
&lt;br /&gt;
There is a deep dark secret that all podcast hosts share. Hosting a podcast is the best way to get the smartest people in your industry to answer your questions for 40-60 minutes. Good luck getting them to do that at a conference, in a mailing list, or on IRC.&lt;br /&gt;
&lt;h3 style=&quot;text-align: left;&quot;&gt;
Podcasts are Super Fun&lt;/h3&gt;
I love podcasts. I think they are a ridiculously easy way for people to connect in a personal way through a conversation or monologue, and share that discussion with a larger group of people. If you work at top-flight technology company, you are lucky enough to engage in these times a day. However, we don&#39;t all live in Silicon Valley nor work for Google or Netflix. Podcasts provide a more intimate conversation than you can get on IRC. In case, you do work at Google or Facebook, podcasts provide a great way to hear from people who work in your profession but are not in your immediate zone of corporate influence.&lt;br /&gt;
&lt;h3 style=&quot;text-align: left;&quot;&gt;
It&#39;s Easy&lt;/h3&gt;
Back in the dark ages of 2010, it was pain in the ass to produce a podcast. One had to connect an audio editor to Skype, tweak it just right, and reshare that audio. Today, we have &lt;a href=&quot;http://www.google.com/+/learnmore/hangouts/onair.html&quot;&gt;Hangouts on Air&lt;/a&gt;, which make it ridiculously easy to record a multi-person podcast and even engage a live audience. If you are too lazy to synthesize the audio portion into an MP3 files, the youtube video stream can suffice.&lt;br /&gt;
&lt;h3 style=&quot;text-align: left;&quot;&gt;
How to Do It&lt;/h3&gt;
&lt;br /&gt;
Let&#39;s assume that I have convinced you to start your new podcast on Windows Kernel Development, school psychology, or .. whatever! I have got some highly-subjective tips for you. Your Mileage May Vary.&lt;br /&gt;
&lt;br /&gt;
&lt;ul style=&quot;text-align: left;&quot;&gt;
&lt;li&gt;Publish early and often&lt;/li&gt;
&lt;li&gt;Content is King&lt;/li&gt;
&lt;li&gt;Pick a format and stick to it &lt;/li&gt;
&lt;li&gt;Use Audacity &lt;/li&gt;
&lt;li&gt;Hire an editor&lt;/li&gt;
&lt;li&gt;Recording happens when you and the guest show up&lt;/li&gt;
&lt;li&gt;Reach beyond the &quot;usual suspects&quot; &lt;/li&gt;
&lt;li&gt;Avoid &quot;Inside baseball&quot;&lt;/li&gt;
&lt;li&gt;Keep it family-friendly&lt;/li&gt;
&lt;li&gt;Don&#39;t talk trash about groups within your professional community&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;
The hardest part of doing a podcast is to keep it going. Most 
podcasts don&#39;t make it past a few episodes. Don&#39;t put a lot of time upfront into 
developing into learning Audacity and developing an awesome logo and 
theme song. Focus on the recording episodes and iteratively improving 
the audio quality as you go along. The audio-quality of the first 10 
FoodFight episodes was absolutely, or &quot;unlistenable&quot; as &lt;a href=&quot;https://twitter.com/gregkare&quot;&gt;Greg Karekinian&lt;/a&gt; told me. We have steadily improved over time. I think it&#39;s absolutely fine to compromise on audio quality. &lt;b&gt;Publish early and often&lt;/b&gt;, make it a habit.&lt;br /&gt;
&lt;br /&gt;
While the audio-quality of our show hasn&#39;t always been greatest, I 
have always paid a lot attention to the technical content of our show. 
From the very beginning I drafted &lt;a href=&quot;https://github.com/foodfight/showz/tree/master/scripts&quot;&gt;fairly detailed script&lt;/a&gt;
 for each episode to ensure we didn&#39;t descend into random banter. I 
never started a show without a pretty good idea what I wanted to cover. 
As &lt;a href=&quot;http://www.johnmwillis.com/&quot;&gt;John Willis&lt;/a&gt; of DevOps Cafe 
told me, &quot;&lt;b&gt;Content is King&lt;/b&gt;.&quot; Nerds won&#39;t care if you stutter or aren&#39;t 
ridiculously eloquent. They will lose interest if you only talk about 
last night NFLBAMLB game or about your children. They will lose interest if 
the show if you don&#39;t consistently talk about the opportunities and challenges in your technical domain.&lt;br /&gt;
&lt;br /&gt;
&lt;a href=&quot;https://twitter.com/damonedwards&quot;&gt;Damon Edwards&lt;/a&gt; of DevOps Cafe recommends that you pick a format for your show and stick to it. I strongly second this. Damon elaborates&lt;br /&gt;
&lt;blockquote class=&quot;tr_bq&quot;&gt;
Decide upfront (or as early as possible) on a format and stick to it. 
Short discussion segments? Quick hit news recap? News discussion? Short 
form interview? Long form interview? Tip of the day/week? Technical 
Q&amp;amp;A? Whatever it is, decide now on work to that. It will drive 
everything from content decisions to editing (if at all). If you want a 
new format, make a new show. &lt;/blockquote&gt;
I recommend you use &lt;a href=&quot;http://audacity.sourceforge.net/&quot;&gt;Audacity&lt;/a&gt; to edit your episode, not GarageBand. Garageband ate my recordings multiple time and wasted my time in a multitude of other ways. Audacity may have a bit more of a learning curve but it is reliable.&lt;br /&gt;
&lt;br /&gt;
In order to better focus on your technical domain, I recommend you &lt;b&gt;pay someone else to edit your shows&lt;/b&gt;. Editing audio tracks is not much fun and distraction from recording or planning another awesome episode. I highly recommend &lt;a href=&quot;http://www.rubyrep.com/&quot;&gt;TheRubyRep&lt;/a&gt; who does great work for a very reasonable price. &lt;br /&gt;
&lt;br /&gt;
Scheduling a podcast that involves multiple people can be challenging, particularly if you have a panel of guests, as the FoodFightShow does. We use &lt;a href=&quot;http://doodle.com/&quot;&gt;doodle.com&lt;/a&gt; to plan our shows but the prevailing rule is that the show happens whenever the organizing host and primary guest can make it. You can easily chew up a lot of in scheduling coordination that would be better spent actually recording a podcast. &lt;br /&gt;
&lt;br /&gt;
In any professional community, there are a number of who present themselves very well and appear frequently in a number of community forums. I call these people &quot;&lt;b&gt;the usual suspects.&lt;/b&gt;&quot; I strongly encourage you to recruit anyone who you think has a lot to say, regardless of how much experience they have speaking publicly. I had to twist the arm of &lt;a href=&quot;https://twitter.com/miah_&quot;&gt;Miah Johnson&lt;/a&gt; to appear on our show. She had little prior experience speaking publicly and didn&#39;t feel very comfortable doing it. But she did have a wealth of experience to share. After her first appearance on the show, one listener wrote in &quot;Thanks for having Miah on the show, she is the kind of engineer I aspire to be.&quot;&lt;br /&gt;
&lt;br /&gt;
Another thing I like to avoid is what is referred to as &quot;&lt;b&gt;Inside baseball&lt;/b&gt;&quot;.&amp;nbsp; While it&#39;s great to discuss the minutiae of your profession it&#39;s not so exciting to discuss the minutiae of the more well-know people and their personalities or activities. It is very easy for a panel-oriented podcast&amp;nbsp; degenerate into a group of friends talking about their friends. While this can be fun if you happen to be a member of that small group of friends, it&#39;s not every interesting otherwise.&lt;br /&gt;
&lt;br /&gt;
Another thing to avoid is cursing, sexist language, or discussion of politics. In any given technical profession, the common thing that binds together your listeners together is their shared professional interest. I know that our podcast has listeners of all religious faiths, political stripes, and genders.&lt;br /&gt;
&lt;br /&gt;
On the off-chance that there happen to already be a significant number of podcasts in your professional area, I still recommend you start a podcast. In my own area, there are 6-7 great podcasts yet there is still so much that doesn&#39;t get discussed. Just as importantly, you have opinions and the Internet needs to hear them!&lt;br /&gt;
&lt;br /&gt;
I have left out a crucial piece of information. How much time do I spend on my bi-monthly podcast? Roughly 5 hours per month. That&#39;s a small investment when you think about it. That&#39;s all for now. Happy Podcasting!&lt;/div&gt;
&lt;/div&gt;
</content><link rel='replies' type='application/atom+xml' href='http://devopsanywhere.blogspot.com/feeds/3559572768396595254/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://devopsanywhere.blogspot.com/2014/01/you-should-start-technical-podcast.html#comment-form' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1083699665345453745/posts/default/3559572768396595254'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1083699665345453745/posts/default/3559572768396595254'/><link rel='alternate' type='text/html' href='http://devopsanywhere.blogspot.com/2014/01/you-should-start-technical-podcast.html' title='You Should Start a Technical Podcast'/><author><name>Anonymous</name><uri>http://www.blogger.com/profile/10631977500882582704</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1083699665345453745.post-7709808878450917389</id><published>2013-11-17T13:51:00.002-08:00</published><updated>2013-11-19T00:42:15.539-08:00</updated><title type='text'>Why I&#39;m Learning Java</title><content type='html'>&lt;div dir=&quot;ltr&quot; style=&quot;text-align: left;&quot; trbidi=&quot;on&quot;&gt;
I spend most of my days writing either Python or Ruby. I enjoy programming in these languages but am painfully aware of their faults. The single process concurrency limitation in both sucks ass. I love that Python is straightforward and predictable but have to admit that I prefer Ruby because I can always bend Ruby to my needs while I sometimes have to change my thinking to fit Python. There are several things about both Ruby and Python that annoy me and make them a poor fit for some of the problems I deal with. Problem #1 is that I need serious concurrency. Python&#39;s multiprocessing module doesn&#39;t cut it. Problem #2 is that neither is a great fit for writing small predictably performing daemons, though Python is a little better at this task. Problem #3 is that I am sick of spelling errors causing my code to fail. I need static typing or &lt;b&gt;something&lt;/b&gt;&amp;nbsp;to reduce the need to run my code just to know if it is syntactically correct.&lt;br /&gt;
&lt;br /&gt;
It is high time for me to expand my skills and learn a new programming language, a process which I don&#39;t take lightly. It may take only a few hours to learn the basic syntax of a new language but in my experience it can take quite a while to comfortably program idiomatically in a new language. &amp;nbsp;Adapting one&#39;s development environment to a new language, learning the standard library, becoming familiar with certain popular libraries, etc. can take a good chunk of time. I believe it took me a year from starting with Ruby to actually programming idiomatically in it.&lt;br /&gt;
&lt;br /&gt;
So how would one select which language to learn? For me the most important factors are, in order of importance:&lt;br /&gt;
&lt;ol style=&quot;text-align: left;&quot;&gt;
&lt;li&gt;Which am i most likely to use at my day job?&lt;/li&gt;
&lt;li&gt;Which is well-suited to kinds of problems I am interested in and work on professionally?&lt;/li&gt;
&lt;li&gt;Which language are many of the open-source projects I work with regularly written in?&lt;/li&gt;
&lt;li&gt;Which language is key to the open-source projects that I want to work with but currently don&#39;t?&lt;/li&gt;
&lt;li&gt;Which language is a joy to work in?&lt;/li&gt;
&lt;/ol&gt;
Based on these factors, I have decided to learn Java. Wait, &lt;b&gt;WAT&lt;/b&gt;? If I had written this post a few years ago, this list would have been inverted. If I were to pick a programming language solely on point #5, here is the list I would come up with, listed in order of interest.&lt;br /&gt;
&lt;br /&gt;
&lt;ol style=&quot;text-align: left;&quot;&gt;
&lt;li&gt;elixir&lt;/li&gt;
&lt;li&gt;erlang&lt;/li&gt;
&lt;li&gt;Go Language&lt;/li&gt;
&lt;li&gt;Scala&lt;/li&gt;
&lt;li&gt;Clojure&lt;/li&gt;
&lt;/ol&gt;
&lt;br /&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;
Notice that Java does not appear on that list. However, the language that I am currently learning is Java and not the cooler, sexier languages in that list. Elixir is freaking awesome because it promises much of the developer happiness that I get from developing Ruby but with all the power of the Erlang VM and OTP library. Erlang is brilliant for a number of reasons, including the aforementioned OTP. I love Golang for developing small services and command-line utilities though it doesn&#39;t offer the me the flexibility and freedom that elixir or Ruby do. Finally, Scala and Clojure are both ridiculously interesting with their functional approaches.&lt;/div&gt;
&lt;br /&gt;
Now back to the present day. In his great post&amp;nbsp;&lt;a href=&quot;http://cuddletech.com/blog/?p=817&quot;&gt;Why Sysadmins Can&#39;t Code&lt;/a&gt;, Ben Rockwood advises that one of the best ways to learn a programming language is to attack a problem that you personally have. Since I have a very demanding 4 month old baby and a pretty darn intense day job, there is preciously little time for hobby programming in my life. I barely even have time for my podcast&amp;nbsp;&lt;a href=&quot;http://foodfightshow.org/&quot;&gt;FoodFightShow&lt;/a&gt;. &amp;nbsp;We don&#39;t use Erlang, elixir, Golang, etc. in my dayjob nor is there any immediate plan to. On a daily basis I do wrangle with java-based tools such as Cassandra, Tomcat, ZooKeeper,&amp;nbsp;ElasticSearch, and a few others. Per Ben&#39;s advice, the problems I personally have and can actually allocate time to on a consistent basis are related to my day job, which primarily revolves around java-related tools.&lt;br /&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
I had fought learning Java for a long-time because it is ugly, verbose, and the Emacs support has historically been pretty lousy. Did I mention that I hate Eclipse? That XML-based DSLs suck ass?Lack of closures and mixins? However, these aren&#39;t good enough reasons not to learn Java. Luckily, Java 8 finally includes closures with Project Lambda and mixins with extension methods.&lt;br /&gt;
&lt;br /&gt;
While there are a number ops-related applications written in Java, Golang is coming on strong. Derek Collison, one of the key developers of CloudFoundry, &lt;a href=&quot;https://twitter.com/derekcollison/status/245522124666716160&quot;&gt;famously tweeted&lt;/a&gt;&amp;nbsp;&quot;Golang will become the dominant language in Iaas, Paas, and orchestration in 24 months.&quot;&amp;nbsp;He wrote that roughly 14 months ago and arguably Golang has made impressive progress toward that goal in the meantime. So why not learn Golang hoping that day job eventually sees the light? I feel that despite all the golang excitement, the Java behemoth has incredible momentum. Projects such as the &lt;a href=&quot;http://ampcamp.berkeley.edu/wp-content/uploads/2013/02/Berkeley-Data-Analytics-Stack-BDAS-Overview-Ion-Stoica-Strata-2013.pdf&quot;&gt;Berkeley analytics stack&lt;/a&gt;, Hadoop, and Cassandra keep innovating at a breakneck pace. Companies such as Twitter, Netflix, LinkedIn and others keep kicking out awesome tools, all based on the JVM. &amp;nbsp;Further, a new language like Golang is most likely to be first applied to the areas where it is best-suited. We don&#39;t really know how well golang will serve the needs of application servers, large dataprocessing apps, and other niches. It could serve those use cases incredibly well . . . or not. We&#39;ll have to see.&lt;br /&gt;
&lt;h3 style=&quot;text-align: left;&quot;&gt;
NetflixOSS - The Quiet Tide of JavaOps&lt;/h3&gt;
While HackerNews keeps talking up the virtues of Golang (which are many), Netflix has done an incredible job of releasing kickass operational tools that mostly happen to be JVM-specific. We did an awesome &lt;a href=&quot;http://foodfightshow.org/2013/05/netflix-oss.html&quot;&gt;Foodfightshow episode&lt;/a&gt; with Adrian Cockcroft and Jeremy Edberg. The venerable ShipShow also did a &lt;a href=&quot;http://theshipshow.com/2013/10/because-you-watched-devops-you-might-enjoy-netflix/&quot;&gt;great episode&lt;/a&gt; with Netflix that you should listen to. The NetflixOSS stack deftly integrates metrics, monitoring, backpressure, and dynamic configuration in a way that makes the resulting applications very easy to support. Their libraries reuse common Java tooling such as JMX, tomcat, slf4j, and others rather than reinventing everything from scratch. JMX, slf4j probably couldn&#39;t work on a run-time like Ruby MRI or Python&#39;s CPython as they require robust threading support that doesn&#39;t block the main thread of execution.&lt;br /&gt;
&lt;br /&gt;
You could possibly implement the kind of monitoring, dynamic configuration, and other properties that NetflixOSS runtime utilizes in Golang, however you probably would have to implement these features from scratch in Golang while they are stable and production-ready in java. Go users, please let me know if I am mistaken.&lt;br /&gt;
&lt;h3 style=&quot;text-align: left;&quot;&gt;
&lt;b&gt;The Runtime&#39;s the Thing&lt;/b&gt;&lt;/h3&gt;
What really makes java truly compelling is the Java Virtual Machine. There are many elements to a language runtime but the one&#39;s I deal with on a daily basis are the thread scheduler and garbage collection algorithms. Effectively managing parallelism in a programming language requires a sophisticated scheduler inside the language itself. Such a scheduler must be able to efficiently allocate threads while maximizing CPU-level cache efficiency. That&#39;s a tall order especially across ARM, x86_64, and NUMA architectures. A dumb scheduler will simply place your threads on whatever CPU is available, regardless of where that thread was last running and irrespective of NUMA requirements. This &#39;cache thrashing&#39; can actually make multithreaded programs run slower on multicore machines than on single core ones. You could just run tons of node.js daemons and push this problem down to the operating system. This does work to some extent, however you have a ton of extra overhead switching process-level contexts. And don&#39;t get me started on what a nightmare it would be to share some minimal state between 1000s of node.js daemons. While you may not need to share state between stateless webapps, one does need to do that if you are coding up a new database or complex batch process.&lt;br /&gt;
&lt;br /&gt;
The programming language scheduler needs to make a number of optimizations to accommodate different cpu architectures. Developing such a scheduler is probably a very expensive and time-consuming process. I guess conservatively that such a scheduler requires at least several million dollars worth of software engineering to develop. Even if Ruby and Python removed their global interpreter locks tomorrow (which would break most C extensions), I doubt any company will step up and invest the money needed for a proper thread scheduler in those languages.&lt;br /&gt;
&lt;br /&gt;
So this leaves us with the few programming languages for which corporations are willing to sponsor the continued development of the language runtime. To the best of my knowledge that leaves us with Java, Erlang, maybe Haskell, and the languages that can run on top of those runtimes.&lt;br /&gt;
&lt;br /&gt;
Another important aspect of a language runtime is the garbage collection algorithms that it supports. I find it ridiculous that it&#39;s already 2013 and there isn&#39;t an open-source pauseless garbage collection algorithm for OpenJDK yet though it is heartening that &lt;a href=&quot;http://rkennke.wordpress.com/2013/06/10/shenandoah-a-pauseless-gc-for-openjdk/&quot;&gt;RedHat is working on one&lt;/a&gt;. It really sucks having to limit your Java heap to 8 GB on a 64 GB box. Projects like HBase and Cassandra get around this by using off-heap caches, but it adds no small amount of complexity and significant runtime overhead. &lt;a href=&quot;http://www.youtube.com/watch?v=ysf1RekaZoI&quot;&gt;This presentation&lt;/a&gt; from Neil Ferguson gives a great overview of how many Java projects maximize RAM usage. I am extremely curious if there is work on a pauseless GC implementation for Golang. Go users, please chime in!&lt;br /&gt;
&lt;h3 style=&quot;text-align: left;&quot;&gt;
&lt;b&gt;Applications and Libraries Trump Language Features&lt;/b&gt;&lt;/h3&gt;
Java doesn&#39;t have &lt;a href=&quot;http://en.wikipedia.org/wiki/Pattern_matching&quot;&gt;pattern matching&lt;/a&gt; like scala, elixir, or erlang. If you are unfamiliar with pattern matching, you should become so as it is fucking awesome. Nor does Java have hygienic macros like Clojure or Elixir. However it is the source language for ZooKeeper, Metrics, and Cassandra, all applications which I really, really enjoy working with.&lt;br /&gt;
&lt;h3 style=&quot;text-align: left;&quot;&gt;
&lt;b&gt;Next Steps&lt;/b&gt;&lt;/h3&gt;
I am slowly working through Cay Horstmann&#39;s &lt;a href=&quot;http://www.horstmann.com/corejava.html&quot;&gt;Core Java series&lt;/a&gt;. I have set up my Eclipse environment and customized it with the excellent &lt;a href=&quot;https://marketplace.eclipse.org/content/emacs&quot;&gt;Emacs+ plugin&lt;/a&gt; that makes it bearable. I intend to first become comfortable with Eclipse as it is the most popular one in my office so I have plenty of people to ask questions of. Longer term I would really like to use something like &lt;a href=&quot;http://blog.senny.ch/blog/2012/10/13/emacs-and-java-journey-of-a-hard-friendship/&quot;&gt;eclim with emacs&lt;/a&gt;. Eventually, I hope that my java knowledge could be a useful springboard to learning some actually &lt;b&gt;fun&lt;/b&gt; languages such as Clojure and Scala.&lt;br /&gt;
&lt;br /&gt;
Summing up, I am learning Java because I have the opportunity to learn it on my day job during a period in my life where I have minimal free time AND because it is the source language for some really compelling open-source projects that I would like to contribute to. In a perfect world we would all be hacking on Elixir or Haskell but alas, the stars are not currently so aligned.&lt;br /&gt;
&lt;br /&gt;
Please don&#39;t read this blog post as my statement on which programming language is *best*. That is a meaningless measure. Obviously the &lt;b&gt;coolest&lt;/b&gt; programming language on the planet is Elixir but the best programming language for Bryan Willson Berry, originally of Whittier, CA (the nicest part of East Los Angeles), to learn at this moment in time is Java.&lt;/div&gt;
</content><link rel='replies' type='application/atom+xml' href='http://devopsanywhere.blogspot.com/feeds/7709808878450917389/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://devopsanywhere.blogspot.com/2013/11/why-im-learning-java.html#comment-form' title='6 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1083699665345453745/posts/default/7709808878450917389'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1083699665345453745/posts/default/7709808878450917389'/><link rel='alternate' type='text/html' href='http://devopsanywhere.blogspot.com/2013/11/why-im-learning-java.html' title='Why I&#39;m Learning Java'/><author><name>Anonymous</name><uri>http://www.blogger.com/profile/10631977500882582704</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>6</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1083699665345453745.post-6709913488007216571</id><published>2013-02-10T22:39:00.001-08:00</published><updated>2013-02-10T22:40:03.648-08:00</updated><title type='text'>SysAdmin Productivity and Chef</title><content type='html'>&lt;div dir=&quot;ltr&quot; style=&quot;text-align: left;&quot; trbidi=&quot;on&quot;&gt;
Inspired by Nathen Harvey&#39;s &lt;a href=&quot;https://speakerdeck.com/nathenharvey/learning-to-automate&quot;&gt;&quot;Learning to Automate&quot;&lt;/a&gt; presentation, I came up with this graph of system administrator productivity. Enjoy&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh0fZ_buuT3dtl5_5vxfGtSSdVryFOn_b8_CTGuenaKarllQG2VdfIQIXki8OIuncillO4MrobxWogJuQY9Xl2aLVYYA-KAi21v0nWBQY2iEIJDlLA10ktdQKeYf69urD-4nTfEJ6DN0RS4/s1600/sysadmin_productivity.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;588&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh0fZ_buuT3dtl5_5vxfGtSSdVryFOn_b8_CTGuenaKarllQG2VdfIQIXki8OIuncillO4MrobxWogJuQY9Xl2aLVYYA-KAi21v0nWBQY2iEIJDlLA10ktdQKeYf69urD-4nTfEJ6DN0RS4/s640/sysadmin_productivity.png&quot; width=&quot;640&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;&lt;/div&gt;
</content><link rel='replies' type='application/atom+xml' href='http://devopsanywhere.blogspot.com/feeds/6709913488007216571/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://devopsanywhere.blogspot.com/2013/02/sysadmin-productivity-and-chef.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1083699665345453745/posts/default/6709913488007216571'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1083699665345453745/posts/default/6709913488007216571'/><link rel='alternate' type='text/html' href='http://devopsanywhere.blogspot.com/2013/02/sysadmin-productivity-and-chef.html' title='SysAdmin Productivity and Chef'/><author><name>Anonymous</name><uri>http://www.blogger.com/profile/10631977500882582704</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh0fZ_buuT3dtl5_5vxfGtSSdVryFOn_b8_CTGuenaKarllQG2VdfIQIXki8OIuncillO4MrobxWogJuQY9Xl2aLVYYA-KAi21v0nWBQY2iEIJDlLA10ktdQKeYf69urD-4nTfEJ6DN0RS4/s72-c/sysadmin_productivity.png" height="72" width="72"/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1083699665345453745.post-2987920115480194189</id><published>2012-11-10T11:53:00.002-08:00</published><updated>2012-11-12T08:15:03.117-08:00</updated><title type='text'>How to Write Reusable Chef Cookbooks, Gangnam Style</title><content type='html'>&lt;div dir=&quot;ltr&quot; style=&quot;text-align: left;&quot; trbidi=&quot;on&quot;&gt;
I am at pains lately to explain to others how I think Chef cookbooks should be developed. There are only a few good blog posts on the subject, most notably Peter Donald&#39;s blog posts &quot;&lt;a href=&quot;http://realityforge.org/code/2012/05/12/evolving-towards-cookbook-reusability-in-chef.html&quot;&gt;Evolving Towards Cookbook Reusability&lt;/a&gt;&quot; &amp;nbsp; and &lt;a href=&quot;http://realityforge.org/code/2012/11/12/reusable-cookbooks-revisited.html&quot;&gt;Reusable Cookbooks Revisited&lt;/a&gt; and Jamie Winsor&#39;s &quot;&lt;a href=&quot;http://vialstudios.com/guide-authoring-cookbooks.html&quot;&gt;Authoring a Chef Cookbook as a Developer&lt;/a&gt;.&quot; These articles have influenced me significantly, as well Jamie Winsor&#39;s &lt;a href=&quot;http://foodfightshow.org/2012/08/jamie-winsor-and-michael-ivey-skool-us-on-berkshelf.html&quot;&gt;appearance on the FoodFightShow podcast&lt;/a&gt;.&amp;nbsp;Both Jamie and Peter urge toward creating generic, attribute-driven cookbook wrapped with a policy-driven cookbook. That&#39;s a complex topic that we will come back to later. Jamie recommends something similar with his distinction between &quot;library&quot; and &quot;application&quot; cookbooks. Jamie has also convinced me that Chef&#39;s Roles are to be avoided. Some people alternately call this pattern &quot;library + application&quot; or &quot;generic + wrapper.&quot; For lack of a better name, I call this way of cooking infrastructure &lt;i&gt;&lt;b&gt;Gangnam Style&lt;/b&gt;&lt;/i&gt;.&lt;br /&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
If you look closely at this image, you can see that Korean rapper PSY is subtly sending us a message about Chef cookbook development.&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgwyiIT7a1uXvQAKl0syl_6pk8fTjbKUeEL-0VIXMUmttp6HhuD4HDFV-uze6TJjRuqd3LDWuPxrw8nDt_nouyacrpYVpLkQUJZrytoBUCMBaA1WJoh0rDJz4d-XtmlFD8g8iyYNN53NYrh/s1600/psy_hands.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;305&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgwyiIT7a1uXvQAKl0syl_6pk8fTjbKUeEL-0VIXMUmttp6HhuD4HDFV-uze6TJjRuqd3LDWuPxrw8nDt_nouyacrpYVpLkQUJZrytoBUCMBaA1WJoh0rDJz4d-XtmlFD8g8iyYNN53NYrh/s400/psy_hands.png&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;br /&gt;
Why are roles bad? Why do you need to write two cookbooks rather than one? Well, this all boils down to cookbook development workflow. I start by developing locally on my workstation using Vagrant, &lt;a href=&quot;http://berkshelf.com/&quot;&gt;Berkshelf&lt;/a&gt;, and Chef Solo. I find using Chef Solo with a local Vagrant VM much faster than working with a Chef Server. This has the added benefit that you will be able to share your library cookbooks with people outside of your immediate organization. This can help a lot when you look to the community for help fixing a thorny issue. Now you can use roles with Chef Solo, but in my opinion, it is a very bad idea. You will have two copies of a given role, one copy in a given cookbook and the main copy in your chef-repo code repository. Syncing the two will introduce errors and complexity unnecessarily. Roles are also a big fat global variable across your entire infrastructure. You can&#39;t version them. You can&#39;t roll out a new role incrementally. Changing a role instantly affects every node that uses it regardless of its environment.&lt;br /&gt;
&lt;br /&gt;
It is critical to use a &lt;i&gt;transient&lt;/i&gt; virtual machine for cookbook development. You can&#39;t really be sure that your cookbook works properly until your delete your virtual machine then reprovision it from scratch.&lt;br /&gt;
&lt;br /&gt;
For the purpose of this article, let&#39;s say I am working on a PostgreSQL cookbook for Acme Corporation. I will fork the default PostgreSQL cookbook from Opscode and only make changes to that cookbook that I will be able to push upstream later. I will put all Acme-specific values and configuration into the acme-postgresql cookbook. In the past, I would have put the Acme-specific values into a role and then done my best not to tweak the PostgreSQL cookbook in any way that infected it with Acme-specific values that couldn&#39;t or shouldn&#39;t be upstreamed. Inevitably, Acme-specific logic and data would make its way into the library cookbook and the changes would never be upstreamed.&lt;br /&gt;
&lt;br /&gt;
The Acme-PostgreSQL cookbook wraps the generic PostgreSQL cookbook with `include_recipe` and then overriding certain attributes and &quot;editing&quot; a few resources with chef-rewind (formerly named chef-edit). For instance, I may need to change the permissions of the main PostgreSQL configuration file because ACME&#39;s DBA team has a written policy that specifies the exact mode for that file. We can argue about whether or not the file mode is worth changing but that won&#39;t change the fact that ACME&#39;s DBA team is paying me an hourly rate on a short-term contract. If I don&#39;t fulfill their requirements to the letter, I won&#39;t get paid :). Next, I have to disable the PostgreSQL service because it is actually managed by Pacemaker.&lt;br /&gt;
&lt;br /&gt;
Once I have most of the cookbook&#39;s elements in place, I begin testing it on my own laptop using Vagrant. Once I am happy with the state of the cookbook, I will deploy it to a server in the QA or Test environment. I am very strict about which cookbook versions are allowed by my environments. In case these two cookbooks are already in use, I make sure that I have incremented the cookbook versions in metadata.rb so they will not be loaded into a production environment accidentally. In the past, I would have to change a role used by both Production and QA servers. This was bad, very bad. Using a wrapper cookbook I can avoid this possibility entirely while keeping all of the benefits of a role.&lt;br /&gt;
&lt;br /&gt;
Once I have deployed to a QA server, I monitor it for anything unexpected. In the case of my haproxy servers, I actually have written a set of integration tests using &lt;a href=&quot;http://rspec.info/&quot;&gt;Rspec&lt;/a&gt;. If everything goes OK after a couple days, I will go increment the version of the wrapper cookbook allowed on the production environment to that of the new version and run chef-client on the target production servers.&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjRrVRxyQHxUKfvyaL4i0kl_SyHY_T83VMBfrDjcGh7jV7EOj52Y3CtrkJq6PEx6xfRDF3DNocJXWcqJixwcCLKlFx7FeMOysf0zo7Nwp5Yfh8P1pALgszC17xGxxAL3R8i_oLAxGjQDneA/s1600/cookbook_life_cycle.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjRrVRxyQHxUKfvyaL4i0kl_SyHY_T83VMBfrDjcGh7jV7EOj52Y3CtrkJq6PEx6xfRDF3DNocJXWcqJixwcCLKlFx7FeMOysf0zo7Nwp5Yfh8P1pALgszC17xGxxAL3R8i_oLAxGjQDneA/s1600/cookbook_life_cycle.png&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
Now what if we had chosen to use roles? Well then the deployment to QA would have been a Hell of a lot more nerve-wracking. Unfortunately, I have made the error in the past of adding an error to a base role. Luckily I caught it before it affected more than a couple servers.&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhaA88VsV3J1WvoARMvhaFjgJOyww1SAaiOiqGo7fCCp3ej18BM8RHHrw7GnLvh8-j9a866lPD8xKK7zkylBvzQ5MUbcxw9tN3P-L8d8w-orGWfj9mYFdHbSi4PPvsWpy4q2K_WCiYatvxa/s1600/cookbook_life_cycle_w_roles.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhaA88VsV3J1WvoARMvhaFjgJOyww1SAaiOiqGo7fCCp3ej18BM8RHHrw7GnLvh8-j9a866lPD8xKK7zkylBvzQ5MUbcxw9tN3P-L8d8w-orGWfj9mYFdHbSi4PPvsWpy4q2K_WCiYatvxa/s1600/cookbook_life_cycle_w_roles.png&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
So far I have explained how I distinguish between Library and Application Cookbooks but here is a table that I think will help you visualize those distinctions.&lt;br /&gt;
&lt;br /&gt;
&lt;table align=&quot;center&quot; cellpadding=&quot;0&quot; cellspacing=&quot;0&quot; class=&quot;tr-caption-container&quot; style=&quot;margin-left: auto; margin-right: auto; text-align: center;&quot;&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td style=&quot;text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhX0QpEAlGWDc5P9aFI6iTMc8ibAKHK4PSDgGFlrHhVQ01UBN7B5gjtAp3xircD7GROmmCA3Rg9XSSOssdVyCEWVDvgHmGwGdKNB2PrWkL4fJrliEvmtwIKpfKun7cKkZztZWyaJtKA17T_/s1600/library_app.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: auto; margin-right: auto;&quot;&gt;&lt;img alt=&quot;&quot; border=&quot;0&quot; height=&quot;312&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhX0QpEAlGWDc5P9aFI6iTMc8ibAKHK4PSDgGFlrHhVQ01UBN7B5gjtAp3xircD7GROmmCA3Rg9XSSOssdVyCEWVDvgHmGwGdKNB2PrWkL4fJrliEvmtwIKpfKun7cKkZztZWyaJtKA17T_/s640/library_app.png&quot; title=&quot;Gangnam Style Cookbook Pattern&quot; width=&quot;640&quot; /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;tr-caption&quot; style=&quot;text-align: center;&quot;&gt;Gangnam Style Cookbook Pattern&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;br /&gt;
&lt;br /&gt;
Recently, there was an awesome &lt;a href=&quot;http://www.youtube.com/watch?v=x0LoqaKbu2g&amp;amp;feature=plcp&quot;&gt;Chef Hangout on Cookbook Reusability&lt;/a&gt; which you should definitely check out. Some participants said that editing resources with chef-rewind (it was called chef-edit at the time of the hangout) has a bad code smell, i.e. a pattern to be avoided. I argued then as I do now that this pattern is one of many tools we can use to make cookbooks reusable. I like it because it is the simplest thing that could possibly work. I could modify the underlying postgresql cookbook so that I can paremeterize those settings that I customize. In that case, I would still want to put the attributes for those parameters in the acme-postgresql recipe. For me personally, modifying a generic cookbook requires a lot of careful thought in order to avoid breaking functionality for users on other platforms. When I am pressed for time and doubt that I will get around to pushing my changes upstream, I prefer to use chef-rewind to override specific resources.&lt;br /&gt;
&lt;br /&gt;
This bears more attention. In any open-source project, regardless of how well run it is, it is easier to pull upstream changes than push changes upstream. The team at Opscode does a great job of integrating changes in my humble opinion, but they have to make sure that any change you introduce doesn&#39;t break functionality for other users. For this reason, I recommend avoiding changes to the Opscode cookbooks unless there is a compelling reason to. This you way you will benefit from their ongoing maintenance and updates of the community cookbooks.&lt;br /&gt;
&lt;br /&gt;
When should you only write one cookbook rather than two? Whenever you are writing something that is purely generic, you only need one cookbook. As soon as you start putting in application-specific data, I recommend splitting that application cookbook into a wrapper cookbook. I recommend this even if you never intend to open-source your generic cookbook. The flexibility you gain will save your ass later.&lt;br /&gt;
&lt;br /&gt;
On the &lt;a href=&quot;http://www.youtube.com/watch?v=x0LoqaKbu2g&amp;amp;feature=plcp&quot;&gt;Cookbook Reusability Hangout&lt;/a&gt; there was a lot of talk of providing better abstractions and the need to provide general purpose LWRPs and DSLs for popular software applications. Adam Jacob made a great counterpoint with this argument &quot;You could write a complete Ruby DSL for haproxy but would it be worth the engineering effort? I doubt it.&quot; Note: This is paraphrased. I tend to agree with Adam here, you could write a DSL for some configuration languages but sometimes it isn&#39;t worth the effort for the more complex ones. It especially isn&#39;t worth it if the DSL is more complex or harder to interpret than the original. Remember, the source configuration language may be a pain in the ass but at least it is documented and its problems known. The same likely cannot be said for your new DSL or LWRP. An LWRP has to be an order of magnitude simpler and more intuitive than the outputted source in order to be worth the effort.&lt;br /&gt;
&lt;br /&gt;
I recently had the pleasure to work on a &lt;a href=&quot;https://github.com/pyr/collectd-dsl&quot;&gt;DSL for collectd plugins&lt;/a&gt; with Pierre Yves Ritschard. I really this DSL works because the collectd configuration language is ridiculously simple. Here is an example:&lt;br /&gt;
&lt;br /&gt;
&lt;script src=&quot;https://gist.github.com/4052187.js?file=collectd_dsl.rb&quot;&gt;&lt;/script&gt;

&lt;br /&gt;
&lt;pre&gt;config = Collectd::DSL.parse do
  load_plugin :redis
  load_plugin :java
  load_plugin :disk

  plugin :disk do
    disk &quot;/dev/sda&quot;
    disk &quot;/dev/sdb&quot;
    ignore_selected &quot;false&quot;
  end
end
&lt;/pre&gt;
&lt;pre&gt;&lt;/pre&gt;
&lt;br /&gt;
With collectd, the scope of configuring plugins is really quite narrow and provides an excellent opportunity for a DSL. This is where DSL&#39;s and LWRPs really shine: Providing conventions for either small problems or subsets of large problems. For example, I think it would be foolhardy to write a general purpose Ruby DSL for JBoss&#39;s XML configuration which covers tens of different J2EE service profiles from messaging to mail to clustered caching. I do believe, however, that it would be feasible to write a DSL for the most common set of configurations for JBoss&#39;s Web Profile.&lt;br /&gt;
&lt;br /&gt;
Let&#39;s step back for a second and think about how we would use the collectd DSL from the above example. We could add a recipe to the collectd cookbook collectd::acme_plugins that uses that DSL for our custom-configured plugins. However, we would be far better off creating a new cookbook acme-collectd with the recipe named plugins. Whether or not you choose to use roles, wrapper cookbooks give you a lot of flexibility.&lt;br /&gt;
&lt;br /&gt;
I too would love to parameterize all the cookbooks and LWRP all the things but we need to make sure that our abstractions are significantly easier to use than the source configuration languages. We also need an array of strategies to make cookbooks more reusable rather than one true path. In this post, I strongly advocate the &lt;i&gt;&lt;b&gt;Gangnam Style&lt;/b&gt;&lt;/i&gt; pattern to wrap a generic cookbook with one which holds application-specific logic and data. Whatever whacky patterns we come up with, we will never move forward as a community (and profession) if we do not succeed in making cookbooks reusable.&lt;br /&gt;
&lt;i&gt;&lt;br /&gt;&lt;/i&gt;
&lt;i&gt;P.S. Nathen Harvey helped edit this post&lt;/i&gt;&lt;br /&gt;
&lt;i&gt;P.P.S. Thanks to those who participated in the Chef Hangout on Cookbook Reusability which greatly stimulated my thinking on this topic&lt;/i&gt;&lt;/div&gt;
</content><link rel='replies' type='application/atom+xml' href='http://devopsanywhere.blogspot.com/feeds/2987920115480194189/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://devopsanywhere.blogspot.com/2012/11/how-to-write-reusable-chef-cookbooks.html#comment-form' title='19 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1083699665345453745/posts/default/2987920115480194189'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1083699665345453745/posts/default/2987920115480194189'/><link rel='alternate' type='text/html' href='http://devopsanywhere.blogspot.com/2012/11/how-to-write-reusable-chef-cookbooks.html' title='How to Write Reusable Chef Cookbooks, Gangnam Style'/><author><name>Anonymous</name><uri>http://www.blogger.com/profile/10631977500882582704</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgwyiIT7a1uXvQAKl0syl_6pk8fTjbKUeEL-0VIXMUmttp6HhuD4HDFV-uze6TJjRuqd3LDWuPxrw8nDt_nouyacrpYVpLkQUJZrytoBUCMBaA1WJoh0rDJz4d-XtmlFD8g8iyYNN53NYrh/s72-c/psy_hands.png" height="72" width="72"/><thr:total>19</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1083699665345453745.post-2947293054379148575</id><published>2012-11-08T01:01:00.002-08:00</published><updated>2012-11-11T08:13:35.650-08:00</updated><title type='text'>Rewinding Chef Resources</title><content type='html'>&lt;div dir=&quot;ltr&quot; style=&quot;text-align: left;&quot; trbidi=&quot;on&quot;&gt;
&lt;b&gt;&lt;i&gt;Note: &amp;nbsp;11 Nov 2012, the chef-edit gem was renamed chef-rewind&lt;/i&gt;&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;MsoNormal&quot;&gt;
Earlier this week I realized that I misunderstood how duplicate resources are handled. When you use a resource twice, it actually is actioned &amp;nbsp;twice,
not once. The second instance will inherit attributes from the first instance but not its action.&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;MsoNormal&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class=&quot;MsoNormal&quot;&gt;
For example,&lt;/div&gt;
&lt;div class=&quot;MsoNormal&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;pre&gt;&lt;div class=&quot;MsoNormal&quot;&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;# jboss/recipes/default.rb&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;MsoNormal&quot;&gt;
&lt;pre&gt;&lt;div style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;
template “/usr/local/jboss/standalone/standalone.xml” do
  source “standalone.xml.erb”
  owner “jboss”
  mode “0755”
  notifies&amp;nbsp;resources(“service[jboss]”), :restart, :immediately
end&lt;/div&gt;
&lt;/pre&gt;
&lt;div class=&quot;MsoNormal&quot;&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;
&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;MsoNormal&quot;&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;# esb/recipes/default.rb&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;MsoNormal&quot;&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;include_recipe “jboss”&lt;/span&gt;&lt;/div&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;
&lt;/span&gt;
&lt;br /&gt;
&lt;div class=&quot;MsoNormal&quot;&gt;
&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;template “/usr/local/jboss/standalone/standalone.xml” do&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;MsoNormal&quot;&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; source&amp;nbsp; “prod-standalone.xml.erb”&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;MsoNormal&quot;&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; owner “esb”&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;MsoNormal&quot;&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; notifies&amp;nbsp;&amp;nbsp;&amp;nbsp;
    resources(“service[jboss]”), :restart, :immediately&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;MsoNormal&quot;&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;end&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;MsoNormal&quot;&gt;
&lt;/div&gt;
&lt;span style=&quot;font-family: Arial, Helvetica, sans-serif;&quot;&gt;
&lt;/span&gt;&lt;/div&gt;
&lt;/pre&gt;
&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: left;&quot;&gt;
&lt;span style=&quot;font-family: Times, &#39;Times New Roman&#39;, serif;&quot;&gt;What actually happens here is that &amp;nbsp;the second template inherits the&amp;nbsp; “mode” of the 1&lt;sup&gt;st&lt;/sup&gt; template, but beyond that, itis a separate resourceservice restarted twice, on every chef run.&amp;nbsp; This is a big problem.called “&lt;a href=&quot;https://github.com/bryanwb/chef-rewind&quot;&gt;chef-rewind&lt;/a&gt;” and it adds an addition function to chef for rewinding an&amp;nbsp;existing resource so it is only actioned once. I packaged it as a ruby gem and
not a cookbook. You can install it using `chef_gem`&amp;nbsp;When you run chef, the file will be template twice and the&amp;nbsp;I wrote a ruby gem last night that should fix this.&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Arial, Helvetica, sans-serif;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;MsoNormal&quot;&gt;
&lt;/div&gt;
&lt;pre&gt;&lt;div class=&quot;MsoNormal&quot;&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;# jboss/recipes/default.rb&lt;/span&gt;&lt;/div&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;
&lt;/span&gt;&lt;div class=&quot;MsoNormal&quot;&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;template “/usr/local/jboss/standalone/standalone.xml” do&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;MsoNormal&quot;&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; source&amp;nbsp; “standalone.xml.erb”&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;MsoNormal&quot;&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; owner “jboss”&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;MsoNormal&quot;&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; mode&amp;nbsp;&amp;nbsp; “0755”&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;MsoNormal&quot;&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; notifies&amp;nbsp;&amp;nbsp;&amp;nbsp;
    resources(“service[jboss]”), :restart, :immediately&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;MsoNormal&quot;&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;end&lt;/span&gt;&lt;/div&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;
&lt;/span&gt;&lt;div class=&quot;MsoNormal&quot;&gt;
&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;# esb/recipes/default.rb&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;MsoNormal&quot;&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;include_recipe “jboss”&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;MsoNormal&quot;&gt;
&lt;b&gt;&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;chef_gem “chef-rewind”&lt;/span&gt;&lt;/b&gt;&lt;/div&gt;
&lt;div class=&quot;MsoNormal&quot;&gt;
&lt;b&gt;&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;require ‘chef/rewind’&lt;/span&gt;&lt;/b&gt;&lt;/div&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;
&lt;/span&gt;&lt;div class=&quot;MsoNormal&quot;&gt;
&lt;b&gt;&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;rewind&lt;/span&gt;&lt;/b&gt;&lt;b&gt;&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&amp;nbsp;:template =&amp;gt; &quot;/usr/local/jboss/standalone/standalone.xml” do&lt;/span&gt;&lt;/b&gt;&lt;/div&gt;
&lt;div class=&quot;MsoNormal&quot;&gt;
&lt;b&gt;&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; source&amp;nbsp; “prod-standalone.xml.erb”&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;
&lt;b&gt;&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;    cookbook_name &quot;esb&quot;&lt;/span&gt;&lt;/b&gt;&lt;/div&gt;
&lt;div class=&quot;MsoNormal&quot;&gt;
&lt;b&gt;&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; owner “esb”&lt;/span&gt;&lt;/b&gt;&lt;/div&gt;
&lt;div class=&quot;MsoNormal&quot;&gt;
&lt;b&gt;&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;end&lt;/span&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/b&gt;&lt;/div&gt;
&lt;pre&gt;&lt;/pre&gt;
&lt;span style=&quot;font-family: Arial, Helvetica, sans-serif;&quot;&gt;
&lt;/span&gt;&lt;span style=&quot;font-family: Times, &#39;Times New Roman&#39;, serif;&quot;&gt;Pay special attention the `cookbook_name` attribute. Without it, the resource will look for it in the jboss cookbook.
&lt;/span&gt;&lt;div class=&quot;MsoNormal&quot;&gt;
&lt;/div&gt;
&lt;/pre&gt;
&lt;div class=&quot;MsoNormal&quot;&gt;
This is very alpha right now and I will be testing it today. Feedback would be very much appreciated.&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;MsoNormal&quot;&gt;
&lt;/div&gt;
&lt;/div&gt;
</content><link rel='replies' type='application/atom+xml' href='http://devopsanywhere.blogspot.com/feeds/2947293054379148575/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://devopsanywhere.blogspot.com/2012/11/editing-chef-resources.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1083699665345453745/posts/default/2947293054379148575'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1083699665345453745/posts/default/2947293054379148575'/><link rel='alternate' type='text/html' href='http://devopsanywhere.blogspot.com/2012/11/editing-chef-resources.html' title='Rewinding Chef Resources'/><author><name>Anonymous</name><uri>http://www.blogger.com/profile/10631977500882582704</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1083699665345453745.post-1669157846509750690</id><published>2012-10-20T12:50:00.000-07:00</published><updated>2012-10-20T23:28:06.396-07:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="chef"/><category scheme="http://www.blogger.com/atom/ns#" term="devops"/><title type='text'>A Year with Chef</title><content type='html'>&lt;div dir=&quot;ltr&quot; style=&quot;text-align: left;&quot; trbidi=&quot;on&quot;&gt;
It literally snuck up on me the other day that I had written a year ago a blog post entitled &lt;a href=&quot;http://devopsanywhere.blogspot.it/2011/10/month-with-chef.html&quot;&gt;&quot;A Month with Chef.&quot;&lt;/a&gt; With the Opscode Community Summit happening this coming week, I think it might be time for a few reflections.&lt;br /&gt;
&lt;br /&gt;
It is a little staggering to think about how use of Chef has impacted my work over the last 12 months. In large part because of Chef I was able to roll out over 130 virtual machines in a tiny fraction of the time that it took me to do with my bespoke python and bash scripts.&amp;nbsp;I also rolled out comprehensive monitoring with collectd, statsd, logstash, and graphite for all of my VMs. I simply couldn&#39;t have accomplished that without Chef. I still don&#39;t have full JVM monitoring but I am working on that.&amp;nbsp;Lastly, Chef has kept my job interesting. I love being a sysadmin but often this job can be tedious. Chef alleviated that tedium to a large extent.&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-size: large;&quot;&gt;Lessons Learned&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
So that&#39;s what Chef has done for me, but along the way there was a whole lot learning, mistakes, and learning from mistakes. There are many lessons that stick out most in my mind but a couple more than the others.&lt;br /&gt;
&lt;br /&gt;
First off, &lt;a href=&quot;https://github.com/reset&quot;&gt;follow Jamie Winsor&lt;/a&gt; on github and &lt;a href=&quot;http://vialstudios.com/guide-authoring-cookbooks.html&quot;&gt;follow the workflow&lt;/a&gt; that RiotGames team has come up with. Jamie and company folded many of their best practices in the &lt;a href=&quot;http://berkshelf.com/&quot;&gt;Berkshelf&lt;/a&gt; tool. I have experimented with a number of different workflow tools but &lt;i&gt;The Berkshelf Way&lt;/i&gt; works best for me. Jamie wrote up an &lt;a href=&quot;http://vialstudios.com/guide-authoring-cookbooks.html&quot;&gt;excellent guide&lt;/a&gt; on how to develop application cookbooks. Read it and live by it. I had already come to some of the same conclusions but many were new to me. I had the pleasure of &lt;a href=&quot;http://foodfightshow.org/2012/08/jamie-winsor-and-michael-ivey-skool-us-on-berkshelf.html&quot;&gt;interviewing Jamie&lt;/a&gt; for the &lt;a href=&quot;http://foodfightshow.org/&quot;&gt;Food Fight podcast&lt;/a&gt;. If you are into Chef or just curious, you should definitley give a listen.&lt;br /&gt;
&lt;br /&gt;
The next most important lesson that you should really use &lt;a href=&quot;http://pryrepl.org/&quot;&gt;pry&lt;/a&gt; in order to learn Ruby and Chef. Pry is an improved read-eval-print-loop for Ruby that will help you inspect, explore, and understand Chef. It is irb on mega-steroids. Pry isn&#39;t something you use once you are more advanced with Ruby but rather I recommend pry to learn Ruby from scratch. Go watch Josh Peek&#39;s &lt;a href=&quot;http://pryrepl.org/screencasts.html&quot;&gt;10-minute intro video&lt;/a&gt; _now_. Debugging a recipe is as easy as inserting &lt;span style=&quot;color: blue; font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;require &#39;pry&#39;; binding.pry&lt;/span&gt; . With pry-nav, you can easily step through your running Chef code.&lt;br /&gt;
&lt;br /&gt;
Here are the rest of my lessons with the ones recommended by the _Berkshelf_Way_ denoted by (BW)&lt;br /&gt;
&lt;br /&gt;
&lt;ul style=&quot;text-align: left;&quot;&gt;
&lt;li&gt;Roles are bad. Don&#39;t use them. Roles make it hard to collaborate on and test cookbooks in a distributed manner. Use a wrapper cookbook instead&amp;nbsp;(BW).&lt;/li&gt;
&lt;li&gt;Use wrapper cookbooks to add information and settings specific to your organization to a more generic cookbook. For example, use a acme-postgres cookbook to override the default values and add corporate-specific policies to the mainline postgresql cookbook (BW).&lt;/li&gt;
&lt;li&gt;Use chef-solo when developing cookbooks even when you will use chef-server to deploy them. It will give you far faster feedback (BW).&lt;/li&gt;
&lt;li&gt;Every cookbook must live in its own git repository.&lt;/li&gt;
&lt;li&gt;Whenever possible, add tests to your cookbooks. It will save your sanity, seriously.&lt;/li&gt;
&lt;li&gt;As a sysadmin, you won&#39;t be able to keep your cookbooks up-to-date without getting your developers involved in writing them.&lt;/li&gt;
&lt;li&gt;You can&#39;t automate something you don&#39;t understand. You can&#39;t write a good postgresql cookbook when you know nothing about postgresql. You can write a lousy postgresql cookbook for a learning experience, but throw it away and start fresh once you know what the Hell you&#39;re doing.&lt;/li&gt;
&lt;li&gt;Ruby is a lot of fun, see earlier point on pry.&lt;/li&gt;
&lt;li&gt;The amount of instability in gems and the Ruby VM itself often drive me to the brink of insanity. The amount of effort that it takes to get Ruby 1.9.x installed on an arbitrary machine is ridiculous.&lt;/li&gt;
&lt;li&gt;Update your cookbook&#39;s version in metadata.rb with every significant change.&lt;/li&gt;
&lt;li&gt;open-source your cookbooks whenever possible. You will get valuable feedback that will improve their quality and make them more secure. Further, interacting with the larger open-source community can vastly improve your skills.&lt;/li&gt;
&lt;li&gt;Follow &lt;a href=&quot;https://github.com/acrmp&quot;&gt;Andrew Crump&lt;/a&gt; on Github. He is author of Chefspec, foodcritic, and a key contributor to minitest-chef and test-kitchen.&amp;nbsp;&lt;/li&gt;
&lt;/ul&gt;
&lt;span style=&quot;font-size: large;&quot;&gt;What is Needed Now&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
More than anything, Chef needs a comprehensive guide book. I know that Stephen Nelson-Smith is working on the&amp;nbsp;&lt;a href=&quot;http://shop.oreilly.com/product/0636920025146.do&quot;&gt;Definitive Guide to Chef&lt;/a&gt;. Unfortunately, the release date for that book is uncertain. James Turnbull and Jeff McCune did a kickass job with&amp;nbsp;&lt;a href=&quot;http://www.apress.com/9781430230571&quot;&gt;Pro Puppet&lt;/a&gt;&amp;nbsp;and Chef desperately needs the equivalent.&lt;br /&gt;
&lt;br /&gt;
Here are some additional things that are needed:&lt;br /&gt;
&lt;br /&gt;
&lt;ul style=&quot;text-align: left;&quot;&gt;
&lt;li&gt;We need a lightweight orchestration tool that &amp;nbsp;works when managing several vagrant vms and to deploy a cluster on vmware. Rake tasks don&#39;t cut it and Apache Zookeeper is definitely not lightweight.&lt;/li&gt;
&lt;li&gt;Some kind of maintainership program, culture, or outright cult to encourage people to maintain cookbooks for a variety of operating systems.&amp;nbsp;&lt;/li&gt;
&lt;li&gt;Better testing tooling. Test-kitchen is a good step but much more remains to be done such as better integration with Continuous Integration systems and support for Berkshelf.&lt;/li&gt;
&lt;li&gt;Make it easier for newbies to get started w/ Ruby. &amp;nbsp;This is the biggest hurdle for newbies. ruby 1.9 is easy to work w/ _once_ you get it installed. It really needs to be as easy as &amp;nbsp;&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;sudo apt-get install -y ruby19&lt;/span&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
&lt;span style=&quot;font-size: large;&quot;&gt;Chef Compared to Ansible, Pallet, and Salt Stack&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
I did write up a &lt;a href=&quot;http://devopsanywhere.blogspot.it/2011/10/puppet-vs-chef-fight.html&quot;&gt;detailed comparison&lt;/a&gt; with Puppet but I have not given newer frameworks such as ansible, saltstack, and pallet the attention they deserve. Nor have I done a proper analysis of CFEngine 3. I have been remiss in that, &lt;i&gt;mea culpa&lt;/i&gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-size: large;&quot;&gt;In Summary&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
The Chef tool and community are far more mature than they were 12 months ago. I expect to see exponential growth in the community and use of Chef itself. The hardest part of working with Chef is managing to keep up with the rapid pace of development and community contributions. Luckily, Nathen Harvey does a fantastic job of summing up the latest developments with his What&#39;s Cooking segment on the &lt;a href=&quot;http://foodfightshow.org/&quot;&gt;Food Fight Show&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
To wrap up, the best thing about working with Chef for 12 months is that it has made me a better sysadmin.&lt;/div&gt;
</content><link rel='replies' type='application/atom+xml' href='http://devopsanywhere.blogspot.com/feeds/1669157846509750690/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://devopsanywhere.blogspot.com/2012/10/a-year-with-chef.html#comment-form' title='10 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1083699665345453745/posts/default/1669157846509750690'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1083699665345453745/posts/default/1669157846509750690'/><link rel='alternate' type='text/html' href='http://devopsanywhere.blogspot.com/2012/10/a-year-with-chef.html' title='A Year with Chef'/><author><name>Anonymous</name><uri>http://www.blogger.com/profile/10631977500882582704</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>10</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1083699665345453745.post-3222382105443439928</id><published>2012-07-02T00:25:00.004-07:00</published><updated>2013-02-14T05:00:36.067-08:00</updated><title type='text'>Stash those logs! Set up Logstash quickly with Chef + Berkshelf</title><content type='html'>&lt;div dir=&quot;ltr&quot; style=&quot;text-align: left;&quot; trbidi=&quot;on&quot;&gt;
&lt;div dir=&quot;ltr&quot; style=&quot;text-align: left;&quot; trbidi=&quot;on&quot;&gt;
&lt;span style=&quot;color: #333333; font-family: &#39;Helvetica Neue Light&#39;, HelveticaNeue-Light, &#39;Helvetica Neue&#39;, Helvetica, Arial, sans-serif; font-size: 14px; line-height: 19px;&quot;&gt;I have been spending a lot of time lately with the excellent&amp;nbsp;&lt;/span&gt;&lt;a href=&quot;http://logstash.net/&quot; style=&quot;-webkit-animation: 0ms !important; -webkit-transition: none !important; color: #009eb8; display: inline; font-family: &#39;Helvetica Neue Light&#39;, HelveticaNeue-Light, &#39;Helvetica Neue&#39;, Helvetica, Arial, sans-serif; font-size: 14px; line-height: 19px; outline: none; text-decoration: none;&quot;&gt;logstash&lt;/a&gt;&lt;span style=&quot;color: #333333; font-family: &#39;Helvetica Neue Light&#39;, HelveticaNeue-Light, &#39;Helvetica Neue&#39;, Helvetica, Arial, sans-serif; font-size: 14px; line-height: 19px;&quot;&gt;&amp;nbsp;tool. If you aren&#39;t familiar with logstash, it reads your logs files, can optionally filter and transform them, and can send them somewhere else for arbitrary purposes. Setting up logstash can be a bit complicated, especially once you add in&amp;nbsp;&lt;/span&gt;&lt;a href=&quot;http://www.elasticsearch.org/&quot; style=&quot;-webkit-animation: 0ms !important; -webkit-transition: none !important; color: #009eb8; display: inline; font-family: &#39;Helvetica Neue Light&#39;, HelveticaNeue-Light, &#39;Helvetica Neue&#39;, Helvetica, Arial, sans-serif; font-size: 14px; line-height: 19px; outline: none; text-decoration: none;&quot;&gt;elasticsearch&lt;/a&gt;&lt;span style=&quot;color: #333333; font-family: &#39;Helvetica Neue Light&#39;, HelveticaNeue-Light, &#39;Helvetica Neue&#39;, Helvetica, Arial, sans-serif; font-size: 14px; line-height: 19px;&quot;&gt;&amp;nbsp;as the backend. Luckily, there are some great chef cookbooks, from&amp;nbsp;&lt;/span&gt;&lt;a href=&quot;https://github.com/karmi&quot; style=&quot;-webkit-animation: 0ms !important; -webkit-transition: none !important; color: #009eb8; display: inline; font-family: &#39;Helvetica Neue Light&#39;, HelveticaNeue-Light, &#39;Helvetica Neue&#39;, Helvetica, Arial, sans-serif; font-size: 14px; line-height: 19px; outline: none; text-decoration: none;&quot;&gt;Karel Minarik&lt;/a&gt;&lt;span style=&quot;color: #333333; font-family: &#39;Helvetica Neue Light&#39;, HelveticaNeue-Light, &#39;Helvetica Neue&#39;, Helvetica, Arial, sans-serif; font-size: 14px; line-height: 19px;&quot;&gt;&amp;nbsp;and&amp;nbsp;&lt;/span&gt;&lt;a href=&quot;https://github.com/lusis&quot; style=&quot;-webkit-animation: 0ms !important; -webkit-transition: none !important; color: #009eb8; display: inline; font-family: &#39;Helvetica Neue Light&#39;, HelveticaNeue-Light, &#39;Helvetica Neue&#39;, Helvetica, Arial, sans-serif; font-size: 14px; line-height: 19px; outline: none; text-decoration: none;&quot;&gt;John E. Vincent&lt;/a&gt;&lt;span style=&quot;color: #333333; font-family: &#39;Helvetica Neue Light&#39;, HelveticaNeue-Light, &#39;Helvetica Neue&#39;, Helvetica, Arial, sans-serif; font-size: 14px; line-height: 19px;&quot;&gt;, for both elasticsearch and logstash. I have extended both cookbooks for my purposes, with pull requests pending as of this writing.&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;color: #333333; font-family: &#39;Helvetica Neue Light&#39;, HelveticaNeue-Light, &#39;Helvetica Neue&#39;, Helvetica, Arial, sans-serif; font-size: 14px; line-height: 19px;&quot;&gt;I use logstash to monitor my&amp;nbsp;&lt;/span&gt;&lt;a href=&quot;http://haproxy.1wt.eu/&quot; style=&quot;-webkit-animation: 0ms !important; -webkit-transition: none !important; color: #009eb8; display: inline; font-family: &#39;Helvetica Neue Light&#39;, HelveticaNeue-Light, &#39;Helvetica Neue&#39;, Helvetica, Arial, sans-serif; font-size: 14px; line-height: 19px; outline: none; text-decoration: none;&quot;&gt;haproxy&lt;/a&gt;&lt;span style=&quot;color: #333333; font-family: &#39;Helvetica Neue Light&#39;, HelveticaNeue-Light, &#39;Helvetica Neue&#39;, Helvetica, Arial, sans-serif; font-size: 14px; line-height: 19px;&quot;&gt;&amp;nbsp;front-end servers. Call me crazy but I like haproxy so much that I even use it do all of my front-end URL rewriting and redirects rather than using a more traditional tool like Apache or Nginx. At this time I only use Apache for my SSL termination. All actual HTTP serving is done by backend java application servers. Haproxy is in my humble opinion, more flexible, easier to configure, more performant than Apache except for one area. It is very easy to make apache send different kinds of logging information to separate log files. Haproxy sends all of its logging information to syslog and its up to you to break it apart. Enter logstash. As the great Lusis describes logstash.&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;blockquote class=&quot;tr_bq&quot; style=&quot;-webkit-animation: 0ms !important; -webkit-transition: none !important; color: #333333; font-family: &#39;Helvetica Neue Light&#39;, HelveticaNeue-Light, &#39;Helvetica Neue&#39;, Helvetica, Arial, sans-serif; font-size: 14px; line-height: 19px;&quot;&gt;
&lt;i style=&quot;-webkit-animation: 0 !important; -webkit-transition: none !important;&quot;&gt;Stuff comes in&lt;/i&gt;&lt;br /&gt;
&lt;i style=&quot;-webkit-animation: 0 !important; -webkit-transition: none !important;&quot;&gt;Bits get Twiddled&lt;/i&gt;&lt;br /&gt;
&lt;i style=&quot;-webkit-animation: 0 !important; -webkit-transition: none !important;&quot;&gt;Stuff comes out&lt;/i&gt;&lt;/blockquote&gt;
&lt;span style=&quot;color: #333333; font-family: &#39;Helvetica Neue Light&#39;, HelveticaNeue-Light, &#39;Helvetica Neue&#39;, Helvetica, Arial, sans-serif; font-size: 14px; line-height: 19px;&quot;&gt;For a good introduction to logstash, I recommend Lusis&amp;nbsp;&lt;/span&gt;&lt;a href=&quot;https://speakerdeck.com/u/lusis/p/logging-patterns-with-logstash-and-chef&quot; style=&quot;-webkit-animation: 0ms !important; -webkit-transition: none !important; color: #009eb8; display: inline; font-family: &#39;Helvetica Neue Light&#39;, HelveticaNeue-Light, &#39;Helvetica Neue&#39;, Helvetica, Arial, sans-serif; font-size: 14px; line-height: 19px; outline: none; text-decoration: none;&quot;&gt;slides from Chefconf&lt;/a&gt;&lt;span style=&quot;color: #333333; font-family: &#39;Helvetica Neue Light&#39;, HelveticaNeue-Light, &#39;Helvetica Neue&#39;, Helvetica, Arial, sans-serif; font-size: 14px; line-height: 19px;&quot;&gt;. I will only cover my immediate use case here. I need to add a logstash agent on each haproxy that sends them to a central logstash server that aggregates all the logs and makes them searchable by injecting them into elasticsearch.&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;color: #333333; font-family: &#39;Helvetica Neue Light&#39;, HelveticaNeue-Light, &#39;Helvetica Neue&#39;, Helvetica, Arial, sans-serif; font-size: 14px; line-height: 19px;&quot;&gt;Here is the basic configuration for the logstash agent on my haproxy servers&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;script src=&quot;https://gist.github.com/3018569.js?file=file-shipper-conf&quot;&gt;&lt;/script&gt;

&lt;div class=&quot;gistLoad&quot; data-id=&quot;3018569&quot; id=&quot;gist-3018569&quot;&gt;
&lt;/div&gt;
&lt;br /&gt;
&lt;span style=&quot;color: #333333; font-family: &#39;Helvetica Neue Light&#39;, HelveticaNeue-Light, &#39;Helvetica Neue&#39;, Helvetica, Arial, sans-serif; font-size: 14px; line-height: 19px;&quot;&gt;As you can problably intuit from shipper.conf, it reads from the haproxy.log file and sends it off to my main logstash_server using AMQP. I actually could read directly from syslog rather than the file. I just haven&#39;t gotten around to doing that yet. Then on my logstash_server I have the following configuration:&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;color: #333333; font-family: &#39;Helvetica Neue Light&#39;, HelveticaNeue-Light, &#39;Helvetica Neue&#39;, Helvetica, Arial, sans-serif; font-size: 14px; line-height: 19px;&quot;&gt;To actually install the agent on my haproxy server, I just add the Chef recipe&amp;nbsp;&lt;/span&gt;&lt;a href=&quot;https://github.com/bryanwb/chef-logstash/blob/master/recipes/agent.rb&quot; style=&quot;-webkit-animation: 0ms !important; -webkit-transition: none !important; color: #009eb8; display: inline; font-family: &#39;Helvetica Neue Light&#39;, HelveticaNeue-Light, &#39;Helvetica Neue&#39;, Helvetica, Arial, sans-serif; font-size: 14px; line-height: 19px; outline: none; text-decoration: none;&quot;&gt;logstash::agent&lt;/a&gt;&lt;span style=&quot;color: #333333; font-family: &#39;Helvetica Neue Light&#39;, HelveticaNeue-Light, &#39;Helvetica Neue&#39;, Helvetica, Arial, sans-serif; font-size: 14px; line-height: 19px;&quot;&gt;&amp;nbsp;to the run_list of my haproxy role, add a few attributes to the same haproxy role and voila! the agent is shipping logs. On the logstash server side, I add the following to my node&#39;s run_list plus a few odd attributes&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;color: #333333; font-family: &#39;Helvetica Neue Light&#39;, HelveticaNeue-Light, &#39;Helvetica Neue&#39;, Helvetica, Arial, sans-serif; font-size: 14px; line-height: 19px;&quot;&gt;&amp;nbsp; &amp;nbsp;&lt;/span&gt;&lt;span style=&quot;-webkit-animation: 0ms !important; -webkit-transition: none !important; color: #333333; font-family: &#39;Courier New&#39;, Courier, monospace; font-size: 14px; line-height: 19px;&quot;&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &quot;role[elasticsearch_server]&quot;, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;-webkit-animation: 0ms !important; -webkit-transition: none !important; color: #333333; font-family: &#39;Courier New&#39;, Courier, monospace; font-size: 14px; line-height: 19px;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&quot;recipe[logstash::server]&quot;, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;color: #333333; font-family: &#39;Courier New&#39;, Courier, monospace; font-size: 14px; line-height: 19px;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&quot;recipe[logstash::kibana]&quot;, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;-webkit-animation: 0ms !important; -webkit-transition: none !important; color: #333333; font-family: &#39;Courier New&#39;, Courier, monospace; font-size: 14px; line-height: 19px;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&quot;recipe[logstash::haproxy]&quot; &amp;nbsp; &amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;color: #333333; font-family: &#39;Helvetica Neue Light&#39;, HelveticaNeue-Light, &#39;Helvetica Neue&#39;, Helvetica, Arial, sans-serif; font-size: 14px; line-height: 19px;&quot;&gt;After my next node convergence you will see a pretty picture like this&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;img height=&quot;345&quot; src=&quot;http://rashidkpc.github.com/Kibana/images/screenshots/searchss.png&quot; style=&quot;-webkit-animation: 0ms !important; -webkit-border-image: url(data:image/png; -webkit-transition: none !important; border-image-repeat: stretch; border-image-slice: 9; border-image-source: url(data:image/png; border-image-width: 9px; border: 9px none; box-sizing: border-box; color: #333333; display: inline-block; font-family: &#39;Helvetica Neue Light&#39;, HelveticaNeue-Light, &#39;Helvetica Neue&#39;, Helvetica, Arial, sans-serif; font-size: 14px; height: auto; line-height: 19px; margin: 10px auto; max-width: 100%; padding: 8px;&quot; width=&quot;640&quot; /&gt;&lt;span style=&quot;color: #333333; font-family: &#39;Helvetica Neue Light&#39;, HelveticaNeue-Light, &#39;Helvetica Neue&#39;, Helvetica, Arial, sans-serif; font-size: 14px; line-height: 19px;&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;color: #333333; font-family: &#39;Helvetica Neue Light&#39;, HelveticaNeue-Light, &#39;Helvetica Neue&#39;, Helvetica, Arial, sans-serif; font-size: 14px; line-height: 19px;&quot;&gt;Wow! This is the excellent&amp;nbsp;&lt;/span&gt;&lt;a href=&quot;https://github.com/rashidkpc/Kibana&quot; style=&quot;-webkit-animation: 0ms !important; -webkit-transition: none !important; color: #009eb8; display: inline; font-family: &#39;Helvetica Neue Light&#39;, HelveticaNeue-Light, &#39;Helvetica Neue&#39;, Helvetica, Arial, sans-serif; font-size: 14px; line-height: 19px; outline: none; text-decoration: none;&quot;&gt;Kibana&lt;/a&gt;&lt;span style=&quot;color: #333333; font-family: &#39;Helvetica Neue Light&#39;, HelveticaNeue-Light, &#39;Helvetica Neue&#39;, Helvetica, Arial, sans-serif; font-size: 14px; line-height: 19px;&quot;&gt;&amp;nbsp;interface created by&amp;nbsp;&lt;/span&gt;&lt;a href=&quot;https://github.com/rashidkpc&quot; style=&quot;-webkit-animation: 0ms !important; -webkit-transition: none !important; color: #009eb8; display: inline; font-family: &#39;Helvetica Neue Light&#39;, HelveticaNeue-Light, &#39;Helvetica Neue&#39;, Helvetica, Arial, sans-serif; font-size: 14px; line-height: 19px; outline: none; text-decoration: none;&quot;&gt;Rashid Khan&lt;/a&gt;&lt;span style=&quot;color: #333333; font-family: &#39;Helvetica Neue Light&#39;, HelveticaNeue-Light, &#39;Helvetica Neue&#39;, Helvetica, Arial, sans-serif; font-size: 14px; line-height: 19px;&quot;&gt;. You may have realized that it is a little more complicated to put this together than I have let on. &amp;nbsp;Let me walk you down the steps of how I actually put it together. But first let&#39;s be clear what is happening here&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;color: #333333; font-family: &#39;Helvetica Neue Light&#39;, HelveticaNeue-Light, &#39;Helvetica Neue&#39;, Helvetica, Arial, sans-serif; font-size: 14px; line-height: 19px;&quot;&gt;1. Logstash agent on each haproxy server reads the log files and ships each individual entry over AMQP to the logstash_server&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;color: #333333; font-family: &#39;Helvetica Neue Light&#39;, HelveticaNeue-Light, &#39;Helvetica Neue&#39;, Helvetica, Arial, sans-serif; font-size: 14px; line-height: 19px;&quot;&gt;2. A rabbitmq-server on logstash_server receives the amqp messages and passes them to the logstash server&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;color: #333333; font-family: &#39;Helvetica Neue Light&#39;, HelveticaNeue-Light, &#39;Helvetica Neue&#39;, Helvetica, Arial, sans-serif; font-size: 14px; line-height: 19px;&quot;&gt;3. The logstash_server `groks` each entry, i.e. it parses the entry and labels named fields according to a pattern, in this case the HAPROXYHTTP&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;color: #333333; font-family: &#39;Helvetica Neue Light&#39;, HelveticaNeue-Light, &#39;Helvetica Neue&#39;, Helvetica, Arial, sans-serif; font-size: 14px; line-height: 19px;&quot;&gt;4. logstash_server puts the grokked log entries into elasticsearch so that they are searchable&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;color: #333333; font-family: &#39;Helvetica Neue Light&#39;, HelveticaNeue-Light, &#39;Helvetica Neue&#39;, Helvetica, Arial, sans-serif; font-size: 14px; line-height: 19px;&quot;&gt;5. You can use the pretty kibana interface to watch a live stream of log entries or query by any `grokked` field. Kibana queries elasticsearch directly using&amp;nbsp;&lt;/span&gt;&lt;a href=&quot;https://lucene.apache.org/core/old_versioned_docs/versions/3_5_0/queryparsersyntax.html&quot; style=&quot;-webkit-animation: 0ms !important; -webkit-transition: none !important; color: #009eb8; display: inline; font-family: &#39;Helvetica Neue Light&#39;, HelveticaNeue-Light, &#39;Helvetica Neue&#39;, Helvetica, Arial, sans-serif; font-size: 14px; line-height: 19px; outline: none; text-decoration: none;&quot;&gt;Lucene query syntax&lt;/a&gt;&lt;span style=&quot;color: #333333; font-family: &#39;Helvetica Neue Light&#39;, HelveticaNeue-Light, &#39;Helvetica Neue&#39;, Helvetica, Arial, sans-serif; font-size: 14px; line-height: 19px;&quot;&gt;. It does not talk directly to the logstash_server.&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;color: #333333; font-family: &#39;Helvetica Neue Light&#39;, HelveticaNeue-Light, &#39;Helvetica Neue&#39;, Helvetica, Arial, sans-serif; font-size: 14px; line-height: 19px;&quot;&gt;As you can see, that&#39;s a lot of moving parts! Each moving part requires its own Chef cookbook. This ends up being quite a lot of cookbooks to manage. Enter&amp;nbsp;&lt;/span&gt;&lt;a href=&quot;http://berkshelf.com/&quot; style=&quot;-webkit-animation: 0ms !important; -webkit-transition: none !important; color: #009eb8; display: inline; font-family: &#39;Helvetica Neue Light&#39;, HelveticaNeue-Light, &#39;Helvetica Neue&#39;, Helvetica, Arial, sans-serif; font-size: 14px; line-height: 19px; outline: none; text-decoration: none;&quot;&gt;Berkshelf&lt;/a&gt;&lt;span style=&quot;color: #333333; font-family: &#39;Helvetica Neue Light&#39;, HelveticaNeue-Light, &#39;Helvetica Neue&#39;, Helvetica, Arial, sans-serif; font-size: 14px; line-height: 19px;&quot;&gt;, an excellent tool for managing cookbooks, written by the great team at&amp;nbsp;&lt;/span&gt;&lt;a href=&quot;http://riotgames.com/&quot; style=&quot;-webkit-animation: 0ms !important; -webkit-transition: none !important; color: #009eb8; display: inline; font-family: &#39;Helvetica Neue Light&#39;, HelveticaNeue-Light, &#39;Helvetica Neue&#39;, Helvetica, Arial, sans-serif; font-size: 14px; line-height: 19px; outline: none; text-decoration: none;&quot;&gt;Riot Games&lt;/a&gt;&lt;span style=&quot;color: #333333; font-family: &#39;Helvetica Neue Light&#39;, HelveticaNeue-Light, &#39;Helvetica Neue&#39;, Helvetica, Arial, sans-serif; font-size: 14px; line-height: 19px;&quot;&gt;. We will use Berkshelf to do much of the heavy lifting for us. I will walk you through how to use berkshelf together with chef-solo to set up logstash.&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;color: #333333; font-family: &#39;Helvetica Neue Light&#39;, HelveticaNeue-Light, &#39;Helvetica Neue&#39;, Helvetica, Arial, sans-serif; font-size: 14px; line-height: 19px;&quot;&gt;Before we move on, you should know about the other &quot;moving part&quot; that everybody talks about, the awesome&lt;/span&gt;&lt;a href=&quot;http://graphite.wikidot.com/&quot; style=&quot;-webkit-animation: 0ms !important; -webkit-transition: none !important; color: #009eb8; display: inline; font-family: &#39;Helvetica Neue Light&#39;, HelveticaNeue-Light, &#39;Helvetica Neue&#39;, Helvetica, Arial, sans-serif; font-size: 14px; line-height: 19px; outline: none; text-decoration: none;&quot;&gt;Graphite&lt;/a&gt;&lt;span style=&quot;color: #333333; font-family: &#39;Helvetica Neue Light&#39;, HelveticaNeue-Light, &#39;Helvetica Neue&#39;, Helvetica, Arial, sans-serif; font-size: 14px; line-height: 19px;&quot;&gt;. Many, many people use logstash to glean metrics from log files and send information on to Graphite where it becomes pretty graphs. This is also a large part of Lusis aforementioned&amp;nbsp;&lt;/span&gt;&lt;a href=&quot;https://speakerdeck.com/u/lusis/p/logging-patterns-with-logstash-and-chef&quot; style=&quot;-webkit-animation: 0ms !important; -webkit-transition: none !important; color: #009eb8; display: inline; font-family: &#39;Helvetica Neue Light&#39;, HelveticaNeue-Light, &#39;Helvetica Neue&#39;, Helvetica, Arial, sans-serif; font-size: 14px; line-height: 19px; outline: none; text-decoration: none;&quot;&gt;presentation&lt;/a&gt;&lt;span style=&quot;color: #333333; font-family: &#39;Helvetica Neue Light&#39;, HelveticaNeue-Light, &#39;Helvetica Neue&#39;, Helvetica, Arial, sans-serif; font-size: 14px; line-height: 19px;&quot;&gt;. Unfortunately, I haven&#39;t started with Graphite yet but once I do I will have another juicy blog post to share with you.&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;-webkit-animation: 0ms !important; -webkit-transition: none !important; color: #333333; font-family: &#39;Helvetica Neue Light&#39;, HelveticaNeue-Light, &#39;Helvetica Neue&#39;, Helvetica, Arial, sans-serif; font-size: medium;&quot;&gt;Setting up Berkshelf&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;color: #333333; font-family: Helvetica Neue Light, HelveticaNeue-Light, Helvetica Neue, Helvetica, Arial, sans-serif;&quot;&gt;&lt;span style=&quot;font-size: 14px; line-height: 19px;&quot;&gt;It used to be a bit difficult to install Berkshelf, but now it couldn&#39;t be easier&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;color: #333333; font-family: Helvetica Neue Light, HelveticaNeue-Light, Helvetica Neue, Helvetica, Arial, sans-serif;&quot;&gt;&lt;span style=&quot;font-size: 14px; line-height: 19px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span style=&quot;color: #333333; font-family: &#39;Helvetica Neue Light&#39;, HelveticaNeue-Light, &#39;Helvetica Neue&#39;, Helvetica, Arial, sans-serif; font-size: 14px; line-height: 19px;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;/span&gt;&lt;span style=&quot;-webkit-animation: 0ms !important; -webkit-transition: none !important; color: #333333; font-family: &#39;Courier New&#39;, Courier, monospace; font-size: 14px; line-height: 19px;&quot;&gt;&amp;nbsp;&amp;nbsp;$ &amp;nbsp;gem install berkshelf&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;-webkit-animation: 0ms !important; -webkit-transition: none !important; color: #333333; font-family: &#39;Helvetica Neue Light&#39;, HelveticaNeue-Light, &#39;Helvetica Neue&#39;, Helvetica, Arial, sans-serif; font-size: medium;&quot;&gt;How Berkshelf Works&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;color: #333333; font-family: &#39;Helvetica Neue Light&#39;, HelveticaNeue-Light, &#39;Helvetica Neue&#39;, Helvetica, Arial, sans-serif; font-size: 14px; line-height: 19px;&quot;&gt;Simply insert the following at the top of your Vagrantfile and Berkshelf will ensure that your cookbooks are uploaded to your vagrant VM&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;color: #333333; font-family: &#39;Helvetica Neue Light&#39;, HelveticaNeue-Light, &#39;Helvetica Neue&#39;, Helvetica, Arial, sans-serif; font-size: 14px; line-height: 19px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;
&lt;span style=&quot;color: #333333; font-family: Helvetica Neue Light, HelveticaNeue-Light, Helvetica Neue, Helvetica, Arial, sans-serif;&quot;&gt;&lt;span style=&quot;font-size: 14px; line-height: 19px;&quot;&gt;&lt;i&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;/i&gt;require &#39;berkshelf/vagrant&#39;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;color: #333333; font-family: Helvetica Neue Light, HelveticaNeue-Light, Helvetica Neue, Helvetica, Arial, sans-serif;&quot;&gt;&lt;span style=&quot;font-size: 14px; line-height: 19px;&quot;&gt;To upload your cookbooks specified in your Berksfile to your chef-server, do the following&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;color: #333333; font-family: Helvetica Neue Light, HelveticaNeue-Light, Helvetica Neue, Helvetica, Arial, sans-serif;&quot;&gt;&lt;span style=&quot;font-size: 14px; line-height: 19px;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;color: #333333; font-family: Helvetica Neue Light, HelveticaNeue-Light, Helvetica Neue, Helvetica, Arial, sans-serif;&quot;&gt;&lt;span style=&quot;font-size: 14px; line-height: 19px;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; $ berks upload&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;color: #333333; font-family: &#39;Helvetica Neue Light&#39;, HelveticaNeue-Light, &#39;Helvetica Neue&#39;, Helvetica, Arial, sans-serif; font-size: 14px; line-height: 19px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;
&lt;span style=&quot;color: #333333; font-family: &#39;Helvetica Neue Light&#39;, HelveticaNeue-Light, &#39;Helvetica Neue&#39;, Helvetica, Arial, sans-serif; font-size: 14px; line-height: 19px;&quot;&gt;This Berksfile instantly gives your team a mechanism to work off the same set of cookbooks. Back in the dark ages of Chef, Oh 9 months ago, we all kept our cookbooks bunched together in a single git repository. This caused all kinds of &amp;nbsp;headaches if you actually wanted to push your changes to an individual cookbook back to Opscode or to someone else. Some months ago, Joshua Timberman split the monolithic&amp;nbsp;&lt;/span&gt;&lt;a href=&quot;https://github.com/opscode/cookbooks&quot; style=&quot;-webkit-animation: 0ms !important; -webkit-transition: none !important; color: #009eb8; display: inline; font-family: &#39;Helvetica Neue Light&#39;, HelveticaNeue-Light, &#39;Helvetica Neue&#39;, Helvetica, Arial, sans-serif; font-size: 14px; line-height: 19px; outline: none; text-decoration: none;&quot;&gt;https://github.com/opscode/cookbooks&lt;/a&gt;&lt;span style=&quot;color: #333333; font-family: &#39;Helvetica Neue Light&#39;, HelveticaNeue-Light, &#39;Helvetica Neue&#39;, Helvetica, Arial, sans-serif; font-size: 14px; line-height: 19px;&quot;&gt;&amp;nbsp;repository out into&amp;nbsp;&lt;/span&gt;&lt;a href=&quot;https://github.com/opscode-cookbooks&quot; style=&quot;-webkit-animation: 0ms !important; -webkit-transition: none !important; color: #009eb8; display: inline; font-family: &#39;Helvetica Neue Light&#39;, HelveticaNeue-Light, &#39;Helvetica Neue&#39;, Helvetica, Arial, sans-serif; font-size: 14px; line-height: 19px; outline: none; text-decoration: none;&quot;&gt;individual git repositories&lt;/a&gt;&lt;span style=&quot;color: #333333; font-family: &#39;Helvetica Neue Light&#39;, HelveticaNeue-Light, &#39;Helvetica Neue&#39;, Helvetica, Arial, sans-serif; font-size: 14px; line-height: 19px;&quot;&gt;. This has made it a million times easier to collaborate on cookbooks but much harder to work on a common set within a team.&amp;nbsp;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;color: #333333; font-family: &#39;Helvetica Neue Light&#39;, HelveticaNeue-Light, &#39;Helvetica Neue&#39;, Helvetica, Arial, sans-serif; font-size: 14px; line-height: 19px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;
&lt;span style=&quot;color: #333333; font-family: &#39;Helvetica Neue Light&#39;, HelveticaNeue-Light, &#39;Helvetica Neue&#39;, Helvetica, Arial, sans-serif; font-size: 14px; line-height: 19px;&quot;&gt;This scenario shows how Berkshelf can help a team collaborate on common set of cookbooks but we will use berkshelf for a different purpose. When working on a cookbook or set of cookbooks for an application, we don&#39;t need all of the cookbooks in the our top-level Berksfile at&amp;nbsp;&lt;/span&gt;&lt;i style=&quot;-webkit-animation: 0ms !important; -webkit-transition: none !important; color: #333333; font-family: &#39;Helvetica Neue Light&#39;, HelveticaNeue-Light, &#39;Helvetica Neue&#39;, Helvetica, Arial, sans-serif; font-size: 14px; line-height: 19px;&quot;&gt;~/chef-repo/Berksfile.&amp;nbsp;&lt;/i&gt;&lt;span style=&quot;-webkit-animation: 0ms !important; -webkit-transition: none !important; background-color: white; color: #333333; font-family: &#39;Helvetica Neue Light&#39;, HelveticaNeue-Light, &#39;Helvetica Neue&#39;, Helvetica, Arial, sans-serif; font-size: 14px; line-height: 19px;&quot;&gt;Further, we may be collaborating with people outside your organization who don&#39;t need or want to see all your corporate cookbooks. For ease of development, each cookbook needs a description of its dependencies. For this reason we will also have a Berksfile for the logstash cookbook that describes its dependencies.&amp;nbsp;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;color: #333333; font-family: &#39;Helvetica Neue Light&#39;, HelveticaNeue-Light, &#39;Helvetica Neue&#39;, Helvetica, Arial, sans-serif; font-size: 14px; line-height: 19px;&quot;&gt;Here is my Berksfile for logstash.&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;script src=&quot;https://gist.github.com/3019171.js?file=Berksfile&quot;&gt;&lt;/script&gt;

&lt;br /&gt;
&lt;div class=&quot;gistLoad&quot; data-id=&quot;3019171&quot; id=&quot;gist-3019171&quot;&gt;
Loading ....&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;-webkit-animation: 0ms !important; -webkit-transition: none !important; color: #333333; font-family: &#39;Helvetica Neue Light&#39;, HelveticaNeue-Light, &#39;Helvetica Neue&#39;, Helvetica, Arial, sans-serif; font-size: medium;&quot;&gt;Let&#39;s Get this Show on the Road!&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;color: #333333; font-family: &#39;Helvetica Neue Light&#39;, HelveticaNeue-Light, &#39;Helvetica Neue&#39;, Helvetica, Arial, sans-serif; font-size: 14px; line-height: 19px;&quot;&gt;Too much talking, let&#39;s get some work done. First, clone my chef-logstash repository.&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;-webkit-animation: 0ms !important; -webkit-transition: none !important; color: #333333; font-family: &#39;Courier New&#39;, Courier, monospace; font-size: 14px; line-height: 19px;&quot;&gt;$ cd ~/projects/&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;-webkit-animation: 0ms !important; -webkit-transition: none !important; color: #333333; font-family: &#39;Courier New&#39;, Courier, monospace; font-size: 14px; line-height: 19px;&quot;&gt;$ git clone&amp;nbsp;git://github.com/lusis/chef-logstash.git &amp;nbsp;logstash&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;-webkit-animation: 0ms !important; -webkit-transition: none !important; color: #333333; font-family: &#39;Courier New&#39;, Courier, monospace; font-size: 14px; line-height: 19px;&quot;&gt;$ cd logstash&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;-webkit-animation: 0ms !important; -webkit-transition: none !important; color: red; font-family: &#39;Helvetica Neue Light&#39;, HelveticaNeue-Light, &#39;Helvetica Neue&#39;, Helvetica, Arial, sans-serif; font-size: 14px; line-height: 19px;&quot;&gt;It is critical that you clone the repository as&amp;nbsp;&lt;b style=&quot;-webkit-animation: 0 !important; -webkit-transition: none !important;&quot;&gt;logstash&lt;/b&gt;&amp;nbsp;and not the default chef-logstash. Otherwise you will get a cryptic error message later on.&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;color: #333333; font-family: &#39;Helvetica Neue Light&#39;, HelveticaNeue-Light, &#39;Helvetica Neue&#39;, Helvetica, Arial, sans-serif; font-size: 14px; line-height: 19px;&quot;&gt;Next, let&#39;s fire up a vagrant VM using the Vagrant definitions that come with the logstash cookbook. I am assuming here that you are already familiar with Vagrant but if you are not, check it out&amp;nbsp;&lt;/span&gt;&lt;a href=&quot;http://vagrantup.com/&quot; style=&quot;-webkit-animation: 0ms !important; -webkit-transition: none !important; color: #009eb8; display: inline; font-family: &#39;Helvetica Neue Light&#39;, HelveticaNeue-Light, &#39;Helvetica Neue&#39;, Helvetica, Arial, sans-serif; font-size: 14px; line-height: 19px; outline: none; text-decoration: none;&quot;&gt;here&lt;/a&gt;&lt;span style=&quot;color: #333333; font-family: &#39;Helvetica Neue Light&#39;, HelveticaNeue-Light, &#39;Helvetica Neue&#39;, Helvetica, Arial, sans-serif; font-size: 14px; line-height: 19px;&quot;&gt;.&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;-webkit-animation: 0ms !important; -webkit-transition: none !important; color: #333333; font-family: &#39;Courier New&#39;, Courier, monospace; font-size: 14px; line-height: 19px;&quot;&gt;$ vagrant up lucid32&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;color: #333333; font-family: &#39;Helvetica Neue Light&#39;, HelveticaNeue-Light, &#39;Helvetica Neue&#39;, Helvetica, Arial, sans-serif; font-size: 14px; line-height: 19px;&quot;&gt;I also have included vagrant definitions for 64-bit Lucid and CentOS 32-bit.&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;color: #333333; font-family: &#39;Helvetica Neue Light&#39;, HelveticaNeue-Light, &#39;Helvetica Neue&#39;, Helvetica, Arial, sans-serif; font-size: 14px; line-height: 19px;&quot;&gt;This will take a while. Vagrant will fetch a vagrant box for 32-bit Ubuntu Lucid and then apply a set the set of Chef recipes to set up logstash. You should also see the result of some integration tests I have written for the elasticsearch cookbook using the&amp;nbsp;&lt;/span&gt;&lt;a href=&quot;https://github.com/btm/minitest-handler-cookbook&quot; style=&quot;-webkit-animation: 0ms !important; -webkit-transition: none !important; color: #009eb8; display: inline; font-family: &#39;Helvetica Neue Light&#39;, HelveticaNeue-Light, &#39;Helvetica Neue&#39;, Helvetica, Arial, sans-serif; font-size: 14px; line-height: 19px; outline: none; text-decoration: none;&quot;&gt;minitest-handler&lt;/a&gt;&lt;span style=&quot;color: #333333; font-family: &#39;Helvetica Neue Light&#39;, HelveticaNeue-Light, &#39;Helvetica Neue&#39;, Helvetica, Arial, sans-serif; font-size: 14px; line-height: 19px;&quot;&gt;.&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;color: #333333; font-family: &#39;Helvetica Neue Light&#39;, HelveticaNeue-Light, &#39;Helvetica Neue&#39;, Helvetica, Arial, sans-serif; font-size: 14px; line-height: 19px;&quot;&gt;You should see at the end of the run the output from the integration tests.&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;-webkit-animation: 0ms !important; -webkit-transition: none !important; color: #333333; font-family: &#39;Courier New&#39;, Courier, monospace; font-size: 14px; line-height: 19px;&quot;&gt;Finished tests in 8.395664s, 0.4764 tests/s, 0.4764 assertions/s.&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;-webkit-animation: 0ms !important; -webkit-transition: none !important; color: #333333; font-family: &#39;Courier New&#39;, Courier, monospace; font-size: 14px; line-height: 19px;&quot;&gt;&lt;br style=&quot;-webkit-animation: 0 !important; -webkit-transition: none !important;&quot; /&gt;&lt;/span&gt;
&lt;span style=&quot;-webkit-animation: 0ms !important; -webkit-transition: none !important; color: #333333; font-family: &#39;Courier New&#39;, Courier, monospace; font-size: 14px; line-height: 19px;&quot;&gt;4 tests, 4 assertions, 0 failures, 0 errors, 0 skips&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;-webkit-animation: 0ms !important; -webkit-transition: none !important; color: #333333; font-family: &#39;Courier New&#39;, Courier, monospace; font-size: 14px; line-height: 19px;&quot;&gt;[Mon, 02 Jul 2012 08:17:03 +0200] INFO: Report handlers complete&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;-webkit-animation: 0ms !important; -webkit-transition: none !important; color: #333333; font-family: &#39;Courier New&#39;, Courier, monospace; font-size: 14px; line-height: 19px;&quot;&gt;[Mon, 02 Jul 2012 08:17:03 +0200] DEBUG: Exiting&lt;/span&gt;&lt;br /&gt;
&lt;div style=&quot;-webkit-animation: 0ms !important; -webkit-transition: none !important; color: #333333; font-family: &#39;Helvetica Neue Light&#39;, HelveticaNeue-Light, &#39;Helvetica Neue&#39;, Helvetica, Arial, sans-serif; font-size: 14px; line-height: 19px; margin: 0px; outline: none; padding: 0px;&quot;&gt;
&lt;br style=&quot;-webkit-animation: 0 !important; -webkit-transition: none !important;&quot; /&gt;&lt;/div&gt;
&lt;div style=&quot;-webkit-animation: 0ms !important; -webkit-transition: none !important; color: #333333; font-family: &#39;Helvetica Neue Light&#39;, HelveticaNeue-Light, &#39;Helvetica Neue&#39;, Helvetica, Arial, sans-serif; font-size: 14px; line-height: 19px; margin: 0px; outline: none; padding: 0px;&quot;&gt;
You may also see the a bunch of invocations of the `curl` command in red. The integration tests use curl extensively and curl outputs its progress to stderr. You can disregard those.&lt;/div&gt;
&lt;div style=&quot;-webkit-animation: 0ms !important; -webkit-transition: none !important; color: #333333; font-family: &#39;Helvetica Neue Light&#39;, HelveticaNeue-Light, &#39;Helvetica Neue&#39;, Helvetica, Arial, sans-serif; font-size: 14px; line-height: 19px; margin: 0px; outline: none; padding: 0px;&quot;&gt;
&lt;/div&gt;
&lt;br /&gt;
&lt;div style=&quot;-webkit-animation: 0ms !important; -webkit-transition: none !important; color: #333333; font-family: &#39;Helvetica Neue Light&#39;, HelveticaNeue-Light, &#39;Helvetica Neue&#39;, Helvetica, Arial, sans-serif; font-size: 14px; line-height: 19px; margin: 0px; outline: none; padding: 0px;&quot;&gt;
Next, fire up a web browser with the using the IP address of your vagrant VM, something like http://192.168.2.x. &amp;nbsp;POW! There is&amp;nbsp;&lt;a href=&quot;https://github.com/rashidkpc/Kibana&quot; style=&quot;-webkit-animation: 0ms !important; -webkit-transition: none !important; color: #009eb8; display: inline; outline: none; text-decoration: none;&quot;&gt;Kibana&lt;/a&gt;, the wonderful web interface for Logstash created by&amp;nbsp;&lt;a href=&quot;https://github.com/rashidkpc&quot; style=&quot;-webkit-animation: 0ms !important; -webkit-transition: none !important; color: #009eb8; display: inline; outline: none; text-decoration: none;&quot;&gt;Rashid Khan&lt;/a&gt;. No logs are displayed as we haven&#39;t yet put any data into logstash.&lt;/div&gt;
&lt;div style=&quot;-webkit-animation: 0ms !important; -webkit-transition: none !important; color: #333333; font-family: &#39;Helvetica Neue Light&#39;, HelveticaNeue-Light, &#39;Helvetica Neue&#39;, Helvetica, Arial, sans-serif; font-size: 14px; line-height: 19px; margin: 0px; outline: none; padding: 0px;&quot;&gt;
&lt;br style=&quot;-webkit-animation: 0 !important; -webkit-transition: none !important;&quot; /&gt;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;-webkit-animation: 0ms !important; -webkit-transition: none !important; clear: both; color: #333333; font-family: &#39;Helvetica Neue Light&#39;, HelveticaNeue-Light, &#39;Helvetica Neue&#39;, Helvetica, Arial, sans-serif; font-size: 14px; line-height: 19px; margin: 0px; outline: none; padding: 0px; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiUA4Vn4jk6Yy9xtKzCyk4kBJeZwufSGOQvpYEyVe0edTua36vKusFQeMMy2NHsaxMIM-9FSg33MZj5YZgaKfvODUr7hSbLfsicpCIbBQNoAJocGpLtG6_V-EVEhNj5i66WPP2LV8Jt3g-p/s1600/kibana.jpg&quot; imageanchor=&quot;1&quot; style=&quot;-webkit-animation: 0ms !important; -webkit-transition: none !important; color: #009eb8; display: inline; margin-bottom: 0px !important; margin-left: 1em; margin-right: 1em; margin-top: 0px !important; outline: none; text-decoration: none;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;251&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiUA4Vn4jk6Yy9xtKzCyk4kBJeZwufSGOQvpYEyVe0edTua36vKusFQeMMy2NHsaxMIM-9FSg33MZj5YZgaKfvODUr7hSbLfsicpCIbBQNoAJocGpLtG6_V-EVEhNj5i66WPP2LV8Jt3g-p/s640/kibana.jpg&quot; style=&quot;-webkit-animation: 0 !important; -webkit-border-image: url(data:image/png; -webkit-transition: none !important; border-image-repeat: stretch; border-image-slice: 9; border-image-source: url(data:image/png; border-image-width: 9px; border: 9px none; box-sizing: border-box; display: inline-block; height: auto; margin: 10px auto; max-width: 100%; padding: 8px; position: relative;&quot; width=&quot;640&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div style=&quot;-webkit-animation: 0ms !important; -webkit-transition: none !important; color: #333333; font-family: &#39;Helvetica Neue Light&#39;, HelveticaNeue-Light, &#39;Helvetica Neue&#39;, Helvetica, Arial, sans-serif; font-size: 14px; line-height: 19px; margin: 0px; outline: none; padding: 0px;&quot;&gt;
Lets go into more detail about how the logstash cookbook works. The main logstash configuration file consists of what are essentially ruby hashes.&lt;/div&gt;
&lt;div style=&quot;-webkit-animation: 0ms !important; -webkit-transition: none !important; color: #333333; font-family: &#39;Helvetica Neue Light&#39;, HelveticaNeue-Light, &#39;Helvetica Neue&#39;, Helvetica, Arial, sans-serif; font-size: 14px; line-height: 19px; margin: 0px; outline: none; padding: 0px;&quot;&gt;
&lt;br style=&quot;-webkit-animation: 0 !important; -webkit-transition: none !important;&quot; /&gt;&lt;/div&gt;
&lt;div style=&quot;-webkit-animation: 0ms !important; -webkit-transition: none !important; color: #333333; font-family: &#39;Helvetica Neue Light&#39;, HelveticaNeue-Light, &#39;Helvetica Neue&#39;, Helvetica, Arial, sans-serif; font-size: 14px; line-height: 19px; margin: 0px; outline: none; padding: 0px;&quot;&gt;
Here is a sample logstash server configuration&lt;/div&gt;
&lt;div style=&quot;-webkit-animation: 0ms !important; -webkit-transition: none !important; color: #333333; font-family: &#39;Helvetica Neue Light&#39;, HelveticaNeue-Light, &#39;Helvetica Neue&#39;, Helvetica, Arial, sans-serif; font-size: 14px; line-height: 19px; margin: 0px; outline: none; padding: 0px;&quot;&gt;
&lt;br style=&quot;-webkit-animation: 0 !important; -webkit-transition: none !important;&quot; /&gt;&lt;/div&gt;
&lt;script src=&quot;https://gist.github.com/3031605.js?file=gistfile1.txt&quot;&gt;&lt;/script&gt;

&lt;br /&gt;
&lt;div class=&quot;gistLoad&quot; data-id=&quot;3031605&quot; id=&quot;gist-3031605&quot;&gt;
Loading ....&lt;/div&gt;
&lt;div style=&quot;-webkit-animation: 0ms !important; -webkit-transition: none !important; color: #333333; font-family: &#39;Helvetica Neue Light&#39;, HelveticaNeue-Light, &#39;Helvetica Neue&#39;, Helvetica, Arial, sans-serif; font-size: 14px; line-height: 19px; margin: 0px; outline: none; padding: 0px;&quot;&gt;
&lt;br /&gt;
&lt;div style=&quot;-webkit-animation: 0 !important; -webkit-transition: none !important; margin: 0px; outline: none; padding: 0px;&quot;&gt;
&lt;br style=&quot;-webkit-animation: 0 !important; -webkit-transition: none !important;&quot; /&gt;&lt;/div&gt;
&lt;div style=&quot;-webkit-animation: 0 !important; -webkit-transition: none !important; margin: 0px; outline: none; padding: 0px;&quot;&gt;
Instead of writing an&amp;nbsp;&lt;a href=&quot;http://wiki.opscode.com/display/chef/Opscode+LWRP+Resources&quot; style=&quot;-webkit-animation: 0ms !important; -webkit-transition: none !important; color: #009eb8; display: inline; outline: none; text-decoration: none;&quot;&gt;LWRP&lt;/a&gt;&amp;nbsp;for logstash. I make it very easy to template the the logstash configuration using attributes provided by a role or a node. Here is a sample role for configuring a logstash_server that matches the previous logstash.conf file.&lt;/div&gt;
&lt;div style=&quot;-webkit-animation: 0 !important; -webkit-transition: none !important; margin: 0px; outline: none; padding: 0px;&quot;&gt;
&lt;br style=&quot;-webkit-animation: 0 !important; -webkit-transition: none !important;&quot; /&gt;&lt;/div&gt;
&lt;div style=&quot;-webkit-animation: 0 !important; -webkit-transition: none !important; margin: 0px; outline: none; padding: 0px;&quot;&gt;
&lt;/div&gt;
&lt;div style=&quot;-webkit-animation: 0 !important; -webkit-transition: none !important; margin: 0px; outline: none; padding: 0px;&quot;&gt;
&lt;br style=&quot;-webkit-animation: 0 !important; -webkit-transition: none !important;&quot; /&gt;&lt;/div&gt;
&lt;script src=&quot;https://gist.github.com/3031583.js?file=logstash_server.rb&quot;&gt;&lt;/script&gt;

&lt;br /&gt;
&lt;div class=&quot;gistLoad&quot; data-id=&quot;3031583&quot; id=&quot;gist-3031583&quot;&gt;
Loading ....&lt;/div&gt;
&lt;div style=&quot;-webkit-animation: 0 !important; -webkit-transition: none !important; margin: 0px; outline: none; padding: 0px;&quot;&gt;
&lt;span style=&quot;-webkit-animation: 0ms !important; -webkit-transition: none !important; background-color: white;&quot;&gt;All you have to do is provide a ruby hash and the logstash templates will render them them into logstash configurations. There are more details in the&amp;nbsp;&lt;a href=&quot;https://github.com/bryanwb/chef-logstash/blob/master/README.md&quot; style=&quot;-webkit-animation: 0ms !important; -webkit-transition: none !important; color: #009eb8; display: inline; outline: none; text-decoration: none;&quot;&gt;README&lt;/a&gt;.&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;-webkit-animation: 0ms !important; -webkit-transition: none !important; background-color: white;&quot;&gt;&lt;br style=&quot;-webkit-animation: 0 !important; -webkit-transition: none !important;&quot; /&gt;&lt;/span&gt;
&lt;span style=&quot;-webkit-animation: 0ms !important; -webkit-transition: none !important; background-color: white;&quot;&gt;There is a lot more to the awesome&amp;nbsp;&lt;/span&gt;&lt;a href=&quot;http://logstash.net/&quot; style=&quot;-webkit-animation: 0ms !important; -webkit-transition: none !important; background-color: white; color: #009eb8; display: inline; outline: none; text-decoration: none;&quot;&gt;logstash&lt;/a&gt;&lt;span style=&quot;-webkit-animation: 0ms !important; -webkit-transition: none !important; background-color: white;&quot;&gt;&amp;nbsp;and its underlying dependencies like&amp;nbsp;&lt;/span&gt;&lt;a href=&quot;http://www.elasticsearch.org/&quot; style=&quot;-webkit-animation: 0ms !important; -webkit-transition: none !important; background-color: white; color: #009eb8; display: inline; outline: none; text-decoration: none;&quot;&gt;elasticsearch&lt;/a&gt;&lt;span style=&quot;-webkit-animation: 0ms !important; -webkit-transition: none !important; background-color: white;&quot;&gt;. &amp;nbsp;Even if you are not looking to implement logstash any time soon, you should seriously take a look at using&amp;nbsp;&lt;a href=&quot;http://berkshelf.com/&quot; style=&quot;-webkit-animation: 0ms !important; -webkit-transition: none !important; color: #009eb8; display: inline; outline: none; text-decoration: none;&quot;&gt;Berkshelf&lt;/a&gt;&amp;nbsp;for managing your cookbook dependencies. Let&#39;s hope I find time in the next month to write about Logstash + Graphite.&lt;/span&gt;&lt;/div&gt;
&lt;div style=&quot;-webkit-animation: 0 !important; -webkit-transition: none !important; margin: 0px; outline: none; padding: 0px;&quot;&gt;
&lt;span style=&quot;-webkit-animation: 0ms !important; -webkit-transition: none !important; background-color: white;&quot;&gt;&lt;br style=&quot;-webkit-animation: 0 !important; -webkit-transition: none !important;&quot; /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div style=&quot;-webkit-animation: 0 !important; -webkit-transition: none !important; margin: 0px; outline: none; padding: 0px;&quot;&gt;
P.S. Thanks to Jamie Winsor (Berkshelf) and Karel Minarik (elasticsearch) for their assistance in working with their respective projects.&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;script src=&quot;https://raw.github.com/moski/gist-Blogger/master/public/gistLoader.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
&lt;/div&gt;
</content><link rel='replies' type='application/atom+xml' href='http://devopsanywhere.blogspot.com/feeds/3222382105443439928/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://devopsanywhere.blogspot.com/2012/07/stash-those-logs-set-up-logstash.html#comment-form' title='9 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1083699665345453745/posts/default/3222382105443439928'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1083699665345453745/posts/default/3222382105443439928'/><link rel='alternate' type='text/html' href='http://devopsanywhere.blogspot.com/2012/07/stash-those-logs-set-up-logstash.html' title='Stash those logs! Set up Logstash quickly with Chef + Berkshelf'/><author><name>Anonymous</name><uri>http://www.blogger.com/profile/10631977500882582704</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiUA4Vn4jk6Yy9xtKzCyk4kBJeZwufSGOQvpYEyVe0edTua36vKusFQeMMy2NHsaxMIM-9FSg33MZj5YZgaKfvODUr7hSbLfsicpCIbBQNoAJocGpLtG6_V-EVEhNj5i66WPP2LV8Jt3g-p/s72-c/kibana.jpg" height="72" width="72"/><thr:total>9</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1083699665345453745.post-8574806147870272493</id><published>2012-04-30T00:18:00.002-07:00</published><updated>2012-12-12T07:51:41.096-08:00</updated><title type='text'>Real Tests, Real Simple with Minitest, Vagrant, and Toft</title><content type='html'>&lt;div dir=&quot;ltr&quot; style=&quot;text-align: left;&quot; trbidi=&quot;on&quot;&gt;
I have put a lot of work into my Ark cookbook lately and it has grown to such complexity that it my existing set of workflow and tools were not enough. I needed some way to sanity check my code. I needed tests.&lt;br /&gt;
&lt;br /&gt;
You can&#39;t refactor with confidence without tests. I have fully rewritten ark several times already. After making serious changes, I then had to spend roughly 20 minutes manually testing the cookbook to ensure that &amp;nbsp;it still worked the way I intended it to. This manual testing was getting tedious, really tedious.&lt;br /&gt;
&lt;br /&gt;
Looking at my various options, I first took a look at Cucumber. There are some nice tools out there like simple_cuke, cuken, and ironfan-ci. I made some attempts at using simple_cuke but they failed fairly miserably. That&#39;s because I thought I could use Cucumber without having to actually learn it. Cucumber is &amp;nbsp;a powerful and somewhat complex tool. To benefit from using Cucumber, I was really going to have to read the The Cucumber Book, something I don&#39;t have time for right now. I needed the simplest thing that could possibly work. Further, the real benefit of Cucumber appears to be the communication it facilitates between customer and engineer. In this case I am the client and the extra layer of communication is unnecessary.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Enter MiniTest&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
Luckily for me, BTM and Andrew Crump have been doing &lt;a href=&quot;https://github.com/btm/minitest-handler-cookbook&quot;&gt;great work&lt;/a&gt; adapting David Calavera&#39;s chef-minitest-handler&amp;nbsp;https://github.com/calavera/minitest-chef-handler. MiniTest is the simplest thing that could possibly work. It works by gathering all the files that match the path &amp;nbsp;files/default/tests/minitest/*_test.rb for the cookbooks in your run_list into /var/chef/minitest/. Once your regular chef run completes, the minitest-handler cookbook executes each of those tests and displays the results.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Note:&lt;/b&gt; As of 30 April, 2012 there is a &lt;a href=&quot;https://github.com/btm/minitest-handler-cookbook/issues/6&quot;&gt;known bug&lt;/a&gt; in minitest-handler that requires you run chef-client twice in a row for the tests to actually execute.&lt;br /&gt;
&lt;b&gt;Update:&lt;/b&gt;&amp;nbsp;&amp;nbsp;Set the network type to bridged and you won&#39;t have this problem &lt;span style=&quot;background-color: lime;&quot;&gt;config.vm.network :bridged&lt;/span&gt; &amp;nbsp; &lt;br /&gt;
&lt;div&gt;
However, running in bridged mode may require sudo.&lt;/div&gt;
&lt;br /&gt;
My ark cookbook is really just an LWRP. The default recipe does nothing more than install the unzip package on those *nix distributions that don&#39;t have it by default. I created an ark::test recipe that exercises all of the features of the ark resource. Here is a snippet of it.&lt;br /&gt;
&lt;br /&gt;
&lt;a href=&quot;https://github.com/bryanwb/chef-ark/blob/master/recipes/test.rb&quot;&gt;ark/recipes/test.rb&lt;/a&gt;&lt;br /&gt;
&lt;script src=&quot;https://gist.github.com/2555849.js&quot;&gt;
&lt;/script&gt;
&lt;div class=&quot;gistLoad&quot; data-id=&quot;2555849&quot; id=&quot;gist-2555849&quot;&gt;Loading ....&lt;/div&gt;

Next, &amp;nbsp;I have my actual MiniTest tests classes, scoped according to my recipe &quot;test&quot;&lt;br /&gt;
&lt;br /&gt;
&lt;a href=&quot;https://github.com/bryanwb/chef-ark/blob/master/files/default/tests/minitest/ark_cherry_pick_test.rb&quot;&gt;ark/files/default/tests/minitest/ark_test.rb&lt;/a&gt;&lt;br /&gt;
&lt;script src=&quot;https://gist.github.com/2555851.js?file=ark_cherry_pick_test.rb&quot;&gt;

&lt;/script&gt;
&lt;div class=&quot;gistLoad&quot; data-id=&quot;2555851&quot; id=&quot;gist-2555851&quot;&gt;Loading ....&lt;/div&gt;

To run these tests I have to first add &lt;a href=&quot;https://github.com/opscode-cookbooks/chef_handler&quot;&gt;chef_handler&lt;/a&gt; and &lt;a href=&quot;https://github.com/btm/minitest-handler-cookbook&quot;&gt;minitest-handler&lt;/a&gt; to the beginning of my run_list. Note that the minitest-handler-cookbook doesn&#39;t yet support chef-solo, but I &lt;a href=&quot;https://github.com/bryanwb/minitest-handler-cookbook&quot;&gt;patched it&lt;/a&gt; over the weekend so that it does.&lt;br /&gt;
&lt;br /&gt;
Here is what the output of the tests looks like&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEho_I0VebliTA_5lDQvzAu6ydtenTQWBDMHjOfHF-I4xtuAFK_Faa-jd0t80Ee5sG-5lu_nW7qDZBnQN396aVXzKpLrf7w6Db5cZiM9NiMqt1sPC9Va1AW8KPcr3cShW-me01DvE48jeTIb/s1600/minitest-run.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;433&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEho_I0VebliTA_5lDQvzAu6ydtenTQWBDMHjOfHF-I4xtuAFK_Faa-jd0t80Ee5sG-5lu_nW7qDZBnQN396aVXzKpLrf7w6Db5cZiM9NiMqt1sPC9Va1AW8KPcr3cShW-me01DvE48jeTIb/s640/minitest-run.png&quot; width=&quot;640&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
I originally wrote my tests using MiniTest::Unit test cases. However, just a few days ago I discovered the awesomeness that Andrew Crump has built into MiniTest::Spec and a whole set of helper modules that really simplify the code you have to write.&lt;br /&gt;
&lt;br /&gt;
Here is a snippet to test whether a file exists and has the correct owner&lt;br /&gt;
&lt;br /&gt;
&lt;script src=&quot;https://gist.github.com/2555888.js&quot;&gt;

&lt;/script&gt;
&lt;div class=&quot;gistLoad&quot; data-id=&quot;2555888&quot; id=&quot;gist-2555888&quot;&gt;Loading ....&lt;/div&gt;

I especially love all of the resource matchers that let you connect to the actual resource objects created during your Chef run and to check whether their configuration matches the actual system state.&lt;br /&gt;
&lt;br /&gt;
For some detailed examples, check out this &lt;a href=&quot;https://github.com/calavera/minitest-chef-handler/blob/v0.4.0/examples/spec_examples/files/default/tests/minitest/example_test.rb&quot;&gt;example&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;The Not so Simple Part&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
Ok, that was the easy part. The harder part is to run your tests on a clean environment. You need a relatively fresh VM to ensure that the tests are actually testing changes made by your cookbook and not some change made eons ago for another purpose. The simplest tool for this is &lt;a href=&quot;http://vagrantup.com/&quot;&gt;Vagrant&lt;/a&gt;. Here is the &lt;a href=&quot;https://github.com/bryanwb/chef-ark/blob/master/Vagrantfile&quot;&gt;Vagrantfile&lt;/a&gt; I use to test the ark cookbook.&lt;br /&gt;
&lt;script src=&quot;https://gist.github.com/2555902.js?file=Vagrantfile&quot;&gt;
&lt;/script&gt;
&lt;div class=&quot;gistLoad&quot; data-id=&quot;2555902&quot; id=&quot;gist-2555902&quot;&gt;Loading ....&lt;/div&gt;

&lt;br /&gt;
Here are the commands you run to provision your new server using vagrant
&lt;br /&gt;

&lt;script src=&quot;https://gist.github.com/2555919.js?file=commands.sh&quot;&gt;
&lt;/script&gt;
&lt;div class=&quot;gistLoad&quot; data-id=&quot;2555919&quot; id=&quot;gist-2555919&quot;&gt;Loading ....&lt;/div&gt;
 

&lt;br /&gt;
&lt;br /&gt;
Note when using Vagrant that bridging your VM&#39;s network to your wireless network connection is not a straightforward process, at least not on my linux laptop. If you run linux as your primary OS, I recommend you spare yourself the pain of trying to bridge your VM to wlan0 and just stick an Ethernet cable into your laptop.&lt;br /&gt;
&lt;br /&gt;
While Vagrant is an awesome tool it is not the best tool for all situations. One issue I have is that my corporate workstation is a very locked down Windows Vista installation. I do virtually all of my work within an Ubuntu virtual machine running on top of Virtualbox. Vagrant uses virtualbox to create new virtual machines and there is no mechanism to run virtualbox within virtualbox. Earlier this year I attempted to get ruby and vagrant running on Windows Vista but after 4 hours I didn&#39;t even have ruby running on Vista.&lt;br /&gt;
&lt;br /&gt;
Another issue with Virtualbox is that it&#39;s flexibility comes at a cost. Virtualbox runs entirely in userspace which means it is less performant than other virtualization tools such as KVM and &lt;a href=&quot;http://lxc.sourceforge.net/&quot;&gt;linux containers&lt;/a&gt; (LXC). This performance lag could become very noticeable once you try to spin up a 4-node postgresql cluster. Of the three virtualization technologies mentioned here, LXC adds the least overhead as each container shares the same copy of the running kernel. There may be other optimizations that LXC provides which I am not aware of.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Enter LXC and Toft&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
As mentioned earlier, LXC has the least overhead of the other virtualization technologies available. &lt;a href=&quot;http://exceedhl.github.com/toft/&quot;&gt;Toft&lt;/a&gt; is a ruby library for testing chef and puppet cookbooks using LXC containers. Toft has a beautiful interface for working with containers as you can see in the following code. &lt;br /&gt;
&lt;br /&gt;
&lt;script src=&quot;https://gist.github.com/2556111.js?file=Toftfile&quot;&gt;
&lt;div class=&quot;gistLoad&quot; data-id=&quot;2556111&quot; id=&quot;gist-2556111&quot;&gt;Loading ....&lt;/div&gt;
&lt;/script&gt;

I can easily see spinning up a multi-node cluster with toft, running my tests, then destroying the whole setup.&lt;br /&gt;
&lt;br /&gt;
While toft has an excellent interface it is a young project with some rough edges, some of which have more to do with LXC than the toft library itself. To get started with toft, there are some nice guides on the &amp;nbsp;&lt;a href=&quot;https://github.com/exceedhl/toft/wiki&quot;&gt;project wiki&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
I very unpleasantly discovered that the version of the cgroup-lite package for Ubuntu 11.10 installed with LXC &lt;b&gt;will make your system unbootable&lt;/b&gt;. The solution is to install cgroup-lite from the oneiric-proposed repository.&lt;br /&gt;
&lt;br /&gt;
&lt;script src=&quot;https://gist.github.com/2556136.js?file=gistfile1.txt&quot;&gt;
&lt;/script&gt;
&lt;div class=&quot;gistLoad&quot; data-id=&quot;2556136&quot; id=&quot;gist-2556136&quot;&gt;Loading ....&lt;/div&gt;

&lt;br /&gt;
Another pitfall is that the bind9 and dhcpd servers installed along with LXC will report erroneous information after initial installation. The fix is easy. Run the `lxc-prepare-host` command and you will be in business.&lt;br /&gt;
&lt;br /&gt;
Finally, at this time Toft only works with Ruby 1.8.7 and does not support Ruby 1.9.*&lt;br /&gt;
&lt;br /&gt;
As noted in the Vagrant section, I highly recommend connecting your laptop to Ethernet if your primary OS is Linux.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Summary&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
Testing is an exciting and increasing critical part of developing infrastructure. While the existing tools need some polish, you can get a lot done with them. The linkbait title of this post is a bit disingenous. Testing w/ minitest is a breeze, but using vagrant and toft are not straightforward affairs. Toft, in particular, is extremely promising and worthy of your attention. It is extremely well-suited to many of the usecases that Vagrant is not.&lt;/div&gt;
&lt;script src=&quot;https://raw.github.com/moski/gist-Blogger/master/public/gistLoader.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;</content><link rel='replies' type='application/atom+xml' href='http://devopsanywhere.blogspot.com/feeds/8574806147870272493/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://devopsanywhere.blogspot.com/2012/04/real-tests-real-simple-with-minitest.html#comment-form' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1083699665345453745/posts/default/8574806147870272493'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1083699665345453745/posts/default/8574806147870272493'/><link rel='alternate' type='text/html' href='http://devopsanywhere.blogspot.com/2012/04/real-tests-real-simple-with-minitest.html' title='Real Tests, Real Simple with Minitest, Vagrant, and Toft'/><author><name>Anonymous</name><uri>http://www.blogger.com/profile/10631977500882582704</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEho_I0VebliTA_5lDQvzAu6ydtenTQWBDMHjOfHF-I4xtuAFK_Faa-jd0t80Ee5sG-5lu_nW7qDZBnQN396aVXzKpLrf7w6Db5cZiM9NiMqt1sPC9Va1AW8KPcr3cShW-me01DvE48jeTIb/s72-c/minitest-run.png" height="72" width="72"/><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1083699665345453745.post-2306787837364988551</id><published>2012-03-21T01:36:00.001-07:00</published><updated>2012-04-14T03:08:01.573-07:00</updated><title type='text'>Unpacking and Installing from Archives with the Ark Resource</title><content type='html'>&lt;div dir=&quot;ltr&quot; style=&quot;text-align: left;&quot; trbidi=&quot;on&quot;&gt;
&lt;br /&gt;
&lt;b&gt;Updated 14 April 2012: The ark API has changed!&amp;nbsp;&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;i&gt;The ark_put, ark_dump, ark_cherry_pick have been rolled into the main ark library as the actions :put, :dump, and :cherry_pick. Please see the updated &lt;a href=&quot;https://github.com/bryanwb/chef-ark&quot;&gt;README&lt;/a&gt;&lt;/i&gt;&lt;br /&gt;
&lt;br /&gt;
There are many wheels that sysadmins reinvent but the one I see reinvented most frequently is the unpacking of a tarball and placing its contents in an arbitrary location. This task seems trivial but there are many slight variations but critical variations to handle. Most chef users resorts to a combination of remote_file, bash, and link resources. This gets the job done but it is a lot of boilerplate for an essentially simple task and it is ridiculously easy to inject errors. I first wrote the &lt;a href=&quot;https://github.com/bryanwb/cookbooks/tree/master/java&quot;&gt;java_ark&lt;/a&gt; Lightweight Resource Provider to handle this. Then I discovered Infochimps excellent &lt;a href=&quot;https://github.com/infochimps-labs/ironfan-pantry/tree/master/cookbooks/install_from&quot;&gt;install_from_release&lt;/a&gt; LWRP.&lt;br /&gt;
&lt;br /&gt;
Unfortunately, install_from_release did not do everything I need so I had to extend it further. In the process of extending install_from_release, I mangled Infochimps beautiful code into an unworkable mess. I have now refactored that mess into something that is more maintainable and extensible. Please meet the &lt;a href=&quot;https://github.com/bryanwb/chef-ark&quot;&gt;&lt;b&gt;ark&lt;/b&gt; resource&lt;/a&gt;. Think of ar&lt;b&gt;k&lt;/b&gt; as an archive but &lt;b&gt;K&lt;/b&gt;ewler. You can thank Joshua Timberman for the name as he didn&#39;t care for my original name for it, `cpr` for Crappy Package Resource. CPR was a play on the medical term CardioPulmonary Resuscitation. &amp;nbsp;Ark does not yet handle all of the functionality that install_from_release does&lt;b&gt;. &lt;/b&gt;Install_from_release not not only unpacks tarballs but can build with make, ant, and more. Ark does not currently support ant, make, or setup.py but it wouldn&#39;t be too much effort to add that support.&lt;br /&gt;
&lt;br /&gt;
Let&#39;s get back to the problem that ark solves. For many of us, the packages available from your given *nix distribution are too old for our needs. This is especially true in the Java ecosystem. The latest stable version of Tomcat is 7.0.26 yet only 7.0.21 is available on ubuntu 11.10. Tomcat 7 isn&#39;t even in the main RHEL 6 channels. My customers insist on having the latest security fixes, so installation from rpm/deb isn&#39;t an option. Installing the Oracle JDK is an even thornier issue as it is no longer available in Ubuntu nor RHEL software channels.&lt;br /&gt;
&lt;br /&gt;
Here is an example of how I would install the Oracle JDK in the bad old days.&lt;br /&gt;
&lt;br /&gt;
&lt;script src=&quot;https://gist.github.com/2145520.js?file=gistfile1.rb&quot;&gt;
&lt;/script&gt;
&lt;br /&gt;
&lt;br /&gt;
Here is how I accomplish the same with ark.&lt;br /&gt;
&lt;br /&gt;
&lt;script src=&quot;https://gist.github.com/2145527.js?file=gistfile1.rb&quot;&gt;
&lt;/script&gt;
&lt;br /&gt;
&lt;br /&gt;
Wow! That&#39;s a lot easier, and frankly more intuitive. Pretty soon I found myself repeating several variations on the ark resource. At first I accomplished this by adding more attributes to the ark resource. This made the resource more verbose, intuitive, and made the code harder to maintain. A few weeks ago I read Nikolay Sturm&#39;s blog post on &lt;a href=&quot;http://blog.nistu.de/2012/03/04/reusability-in-configuration-management-systems/&quot;&gt;Cookbook Reusability&lt;/a&gt; and then interviewed him for &lt;a href=&quot;http://www.foodfightshow.org/2012/03/episode-6-cookbook-reusability-with.html&quot;&gt;the Food Fight Show&lt;/a&gt;. &amp;nbsp;Through Nikolay, I discovered the &lt;a href=&quot;http://www.objectmentor.com/resources/articles/isp.pdf&quot;&gt;Interface Segregation Principle&lt;/a&gt;. &amp;nbsp;Rather than adding more options to the ark resource, I totally refactored ark from an LWRP into a Provider and Resource classes that subclass Chef::Provider::ArkBase and Chef::Resource::ArkBase.&lt;br /&gt;
&lt;br /&gt;
Here is the ark_put resource which handles the simplest case:&lt;br /&gt;
&lt;br /&gt;
&lt;script src=&quot;https://gist.github.com/2145553.js?file=gistfile1.rb&quot;&gt;
&lt;/script&gt;
&lt;br /&gt;
ark_put simply unpacks ivy to the default location /usr/local/ivy, it does not create any symbolic links
&lt;br /&gt;
I often have to download arbitrary collections of dependencies and place them in a lib/ directory. I do this frequently for tomcat-based applications. I just need to &quot;dump&quot; the dependencies in a specified directory that likely already holds a number of library files. This situation is a little more complicated as I need a way to determine whether or not the archive has previously been unpacked. With the ark and ark_put resources I simply check if the destination directory is empty. This logic won&#39;t work for a directory like tomcat/lib that holds library files from the initial tomcat installation. For this reason, I have to specify a &quot;creates&quot; attribute which specifies the file whose presence indicates that the ark has already been unpacked. Additionally, I need to discard any file hierarchy inside the archive.
&lt;br /&gt;
&lt;br /&gt;
&lt;script src=&quot;https://gist.github.com/2145566.js?file=gistfile1.rb&quot;&gt;
&lt;/script&gt;
&lt;br /&gt;
ark_dump will place all the *.jar files in the archive into /usr/local/tomcat/lib/. Note: ark_dump currently only supports *.zip archives.
&lt;br /&gt;
&lt;br /&gt;
My friends at Oracle seem bent on making me work for my salary. I have encountered on several occasions the need to extract a single file from a tarball and place it in a arbitrary location. In this case that single file will be specified by the &quot;creates&quot; attribute. In this case I extract the JDBC connector for MySQL. 
&lt;br /&gt;
&lt;br /&gt;
&lt;script src=&quot;https://gist.github.com/2145592.js?file=gistfile1.rb&quot;&gt;
&lt;/script&gt;
&lt;br /&gt;
&lt;br /&gt;
That&#39;s the state of the ark resource at the moment. If you are interested to use it and/or extend it, check it out on &lt;a href=&quot;https://github.com/bryanwb/chef-ark&quot;&gt;github&lt;/a&gt;. You should note that it is not a collection of&amp;nbsp;&lt;a href=&quot;http://wiki.opscode.com/display/chef/Lightweight+Resources+and+Providers+(LWRP)&quot;&gt;LWRP&lt;/a&gt;s&amp;nbsp;but actual Provider and Resource classes. &amp;nbsp;LWRPs are great to get started with but don&#39;t provide the same facility for code reuse that pure Ruby does. Thanks to Nikolay Sturm for inspiring me to venture beyond the LWRP DSL and to MrFlip (Philip Kromer) for creating the awesome install_from cookbook. I hope that ark will eventually support all of the functionality that install_from_release does.&lt;br /&gt;
&lt;br /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://devopsanywhere.blogspot.com/feeds/2306787837364988551/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://devopsanywhere.blogspot.com/2012/03/managing-archives-with-ark-resource.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1083699665345453745/posts/default/2306787837364988551'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1083699665345453745/posts/default/2306787837364988551'/><link rel='alternate' type='text/html' href='http://devopsanywhere.blogspot.com/2012/03/managing-archives-with-ark-resource.html' title='Unpacking and Installing from Archives with the Ark Resource'/><author><name>Anonymous</name><uri>http://www.blogger.com/profile/10631977500882582704</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1083699665345453745.post-3303981299926653566</id><published>2012-02-06T22:50:00.000-08:00</published><updated>2012-02-07T00:17:37.658-08:00</updated><title type='text'>FOSDEM Summary</title><content type='html'>&lt;div dir=&quot;ltr&quot; style=&quot;text-align: left;&quot; trbidi=&quot;on&quot;&gt;
&lt;br /&gt;
I thoroughly enjoyed &lt;a href=&quot;http://fosdem.org/&quot;&gt;FOSDEM&lt;/a&gt;. The weather sucked, the beer was great,&amp;nbsp;and the people were wonderful. Thanks to the FOSDEM organizers for&amp;nbsp;putting on such a great conference. What follows is a very rough summary of my experience.&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;http://blog.bn2vs.com/wp-content/uploads/2010/02/Fosdem_2010_logo.jpg&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;320&quot; src=&quot;http://blog.bn2vs.com/wp-content/uploads/2010/02/Fosdem_2010_logo.jpg&quot; width=&quot;228&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
I spent most of my time in the Virtualization room. There were a&amp;nbsp;number of interesting talks there.&amp;nbsp;I didn&#39;t spend much time in the Configuration Management Devroom, that&amp;nbsp;is not because the content there was lacking but because I felt more&amp;nbsp;knowledegeable about the subjects there than in the Network/IO,&lt;br /&gt;
virtualization, and hypervisor talks where I was pretty much ignorant. From what I could tell, the&lt;br /&gt;
organizers did a fine job organizing the Systems and Configuration&amp;nbsp;Management Devroom.&lt;br /&gt;
&lt;br /&gt;
One of the best parts of going to a conference like this is meeting&amp;nbsp;in person that you have collaborated with via e-mail and IRC. I met up&amp;nbsp;w/ Cheffolk Andrea Campi, Juan Jesus Croissier (juanje), Nicholas&lt;br /&gt;
Szalay (nico), Stefan Jourdan, and Greg Karekinian (sp?). I have interacted with these guys quite&amp;nbsp;extensively over the last four months, so it was awesome to finally&amp;nbsp;meet them. Juanje has a very different use case for Chef than most&amp;nbsp;users. He manages thousands of desktop machines running GNOME. He must&amp;nbsp;take care not to overwrite the users custom settings, a challenge I&amp;nbsp;have never had to deal with. For this reason he created an LWRP to&amp;nbsp;manage portions of a file. Nico has written a nagios check that will&amp;nbsp;report failing chef runs. I need to start using that.&lt;br /&gt;
&lt;br /&gt;
The best moment of FOSDEM for me was a very personal one. I ran into&amp;nbsp;Sulochan Acharya, a friend of mine from Nepal. We worked together to&amp;nbsp;build the &lt;a href=&quot;http://www.olenepal.org/&quot;&gt;One Laptop Per Child project in Nepal&lt;/a&gt;. I didn&#39;t even know he was in Europe nor still working&amp;nbsp;in IT. Now he works at Rackspace on Openstack-related stuff. It is a&amp;nbsp;small, small open-source world.&lt;br /&gt;
&lt;br /&gt;
Best talks I attended were Anil Madhavapeddy&#39;s &quot;&lt;a href=&quot;http://fosdem.org/2012/schedule/event/unixio&quot;&gt;Wild West of UNIX I/O&lt;/a&gt;&quot;&amp;nbsp;and Charles Nutter&#39;s JRuby talk. Anil talked about the unpredictable&amp;nbsp;behavior that we see in UNIX I/O in virtualized environments. In a&lt;br /&gt;
multicore world, hypervisors don&#39;t know enough about the underlying&amp;nbsp;architecture to make intelligent decisions about I/O between CPU&amp;nbsp;cores. This leads to very unpredictable I/O results. According to&amp;nbsp;Anil, this requires a better I/O abstraction that is aware of the&amp;nbsp;underlying microarchitecture--CPU layout, interconnects, NUMA--and can&amp;nbsp;make intelligent choices for the developer. Anil calls his&amp;nbsp;next-generation I/O framework &lt;a href=&quot;http://anil.recoil.org/papers/drafts/2012-resolve-draft1.pdf&quot;&gt;FABLE&lt;/a&gt;, which is still in very early&amp;nbsp;development. Charles Nutter is a great speaker though his&lt;br /&gt;
talk was a bit over my head. He focused on the &quot;impossible&quot; challenges&amp;nbsp;of implementing Ruby on the JVM and how his team overcame them.&lt;br /&gt;
&lt;br /&gt;
I missed the ZIO and CERN talks. Both talked about next-generation I/O&amp;nbsp;frameworks. Also sadly missed Jonathan Ellis&#39;s talk on &quot;Overcoming JVM&amp;nbsp;limitations in Cassandra&quot;. I spent no time w/ the Mozilla track, &amp;nbsp;which&amp;nbsp;is a shame as I love how they manage their community and the kinds of&amp;nbsp;projects they work on.&lt;br /&gt;
&lt;br /&gt;
I was struck by the large number of projects that featured web frontends&amp;nbsp;written in Ruby on Rails. Besides Horizon, the Openstack web UI, it seemed that&amp;nbsp;virtually every other web UI I saw was Rails. Ironically, there were&amp;nbsp;no talks specifically about Ruby nor Rails at FOSDEM.&lt;br /&gt;
&lt;br /&gt;
Red Hat is doing a lot of activity in the DevOps space. oVirt a web UI&amp;nbsp;for managing VMs. Matahari a system administration API which looks&amp;nbsp;interesting but seems like it is still in early development.&amp;nbsp;I had the pleasure of talking w/ Ohad Levy, a very sharp fellow who develops &lt;a href=&quot;http://theforeman.org/&quot;&gt;Foreman&lt;/a&gt;, a&amp;nbsp;front-end to Puppet and is employed by Red Hat.&lt;br /&gt;
&lt;br /&gt;
I found out about the meta-project &lt;a href=&quot;http://www.katello.org/&quot;&gt;Katello&lt;/a&gt;&amp;nbsp;from Red Hat that contains many&amp;nbsp;components to automate system administration. To my limited knowledge,&amp;nbsp;it includes &lt;a href=&quot;http://matahariproject.org/&quot;&gt;Matahari&lt;/a&gt;&amp;nbsp;for low-level administration, Puppet for&amp;nbsp;configuration management, Foreman as a nice GUI to manage your&amp;nbsp;configurations and server provisioning, &lt;a href=&quot;http://www.ovirt.org/&quot;&gt;oVirt&lt;/a&gt; to manage your KVM hosts a la VMware&#39;s vSphere,&amp;nbsp;and pacemaker-cloud for high-availability across different cloud&amp;nbsp;providers. I believe the combined stack is at alpha level. I would&lt;br /&gt;
love to know if Chef could be used in place of Puppet.&lt;br /&gt;
&lt;br /&gt;
Met the very smart Marek Goldmann who is doing a lot of work packaging JBOSS for&amp;nbsp;Fedora in addition to his &lt;a href=&quot;http://boxgrinder.org/&quot;&gt;boxgrinder&lt;/a&gt; project. It seems like there is a fair amount amount of overlap between&amp;nbsp;what he and are trying to do in this regard. I need to spend some time hanging out&amp;nbsp;on #fedora-java to see how we can avoid duplicating efforts.&lt;br /&gt;
&lt;br /&gt;
My greatest regret is that I myself didn&#39;t give a presentation. I didn&#39;t&amp;nbsp;think I had anything to say that others would be interested, but that&amp;nbsp;view was wholly wrong. There was a lot of interest in Chef but&amp;nbsp;unfortunately not much content.&lt;br /&gt;
&lt;br /&gt;
I met a couple of people who had listened to my podcast, &lt;a href=&quot;http://www.foodfightshow.org/&quot;&gt;Food Fight&lt;/a&gt;,&amp;nbsp;but they told me it was &quot;unlistenable&quot; due to the recording quality. Guess I will have to improve the&amp;nbsp;audio quality :(&lt;br /&gt;
&lt;br /&gt;
I was very lucky to have dinner with a group that included the DevOps&amp;nbsp;gurus Kris Buytaert and &amp;nbsp;Patrick DeBois. After following both of them&amp;nbsp;on Twitter for a number of months it was really interesting to see&amp;nbsp;what they are orking on. These guys really are the &quot;Belgian Braintrust&quot; of&amp;nbsp;DevOps not to mention that Patrick actually invented the term. If I&amp;nbsp;recall correctly, both Patrick and Kris are spending a lot of time&lt;br /&gt;
lately working on monitoring and logging. Not only are Kris and Patrick DevOps heroes but they are also genuinely nice guys.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Beer&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
Belgians make the best beer in the world and they enjoy it at all&amp;nbsp;hours and in all places. Quite a number of people enjoys fine brews&amp;nbsp;during presentations and meetups. The Opensuse stand actually gave&amp;nbsp;away opensuse beer. Note to self, avoid the 10 % alchohol beer when&amp;nbsp;trying to stay alert. Stick to the delicious 4% blonde beers.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Final Thoughts&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
Openstack is the real deal, not just a cool idea. It will really be&amp;nbsp;ready for production use this year. I had my doubts about an&amp;nbsp;open-source project led by an industry consortium but what I saw made me put them&lt;br /&gt;
aside. Particularly impressive was Ryan Lane&#39;s explanation of how&amp;nbsp;Wikipedia is using Openstack for its infrastructure.&lt;br /&gt;
&lt;br /&gt;
There is awesome stuff happening with KVM, both in terms of&amp;nbsp;performance and tooling.&lt;br /&gt;
&lt;br /&gt;
There was a lot of interest in Chef but I didn&#39;t meet that many people&amp;nbsp;who had actually used it. This must be remedied. I really should have given a&amp;nbsp;talk and put more effort into planning a Chef meetup.&lt;br /&gt;
&lt;br /&gt;
I will definitely be back next year and hopefully as a presenter.&lt;br /&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://devopsanywhere.blogspot.com/feeds/3303981299926653566/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://devopsanywhere.blogspot.com/2012/02/fosdem-summary.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1083699665345453745/posts/default/3303981299926653566'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1083699665345453745/posts/default/3303981299926653566'/><link rel='alternate' type='text/html' href='http://devopsanywhere.blogspot.com/2012/02/fosdem-summary.html' title='FOSDEM Summary'/><author><name>Anonymous</name><uri>http://www.blogger.com/profile/10631977500882582704</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1083699665345453745.post-8978922748173487787</id><published>2012-01-15T22:23:00.000-08:00</published><updated>2012-01-16T22:01:52.280-08:00</updated><title type='text'>Announcing the Food Fight Podcast</title><content type='html'>&lt;div dir=&quot;ltr&quot; style=&quot;text-align: left;&quot; trbidi=&quot;on&quot;&gt;
&lt;div dir=&quot;ltr&quot; style=&quot;text-align: left;&quot; trbidi=&quot;on&quot;&gt;
I just published the inaugural episode of &lt;a href=&quot;http://traffic.libsyn.com/foodfight/ff_ep01_2.mp3&quot;&gt;Food Fight&lt;/a&gt;, the Chef community podcast that I host together with &lt;a href=&quot;https://plus.google.com/116714115351408264605/posts&quot;&gt;Matt Ray&lt;/a&gt;. The podcast will cover not only the developments within the Chef community but also larger world of DevOps. Enjoy!&lt;/div&gt;
&lt;a href=&quot;http://www.foodfightshow.org/&quot;&gt;
&lt;img alt=&quot;Food Fight&quot; height=&quot;98px; &quot; id=&quot;Header1_headerimg&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjjDlxYvuXIQBmiIT466xkeith0T-xIiSOQFP_W8nALvnzdP6f-I-cCwOURv-5BvaK0MVbixCH_nFWnn_9-3KyAmJxkxJ0suBoz3gPT8DmqcdjCUGv1ZOiIH84rWPqicoeb2S7szQrjs-A/s1600/FoodFightbanner100px.png&quot; style=&quot;display: block;&quot; width=&quot;400px; &quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;a href=&quot;http://feeds.feedburner.com/TheFoodFightShow&quot;&gt;
&lt;img alt=&quot;subscribe to feed&quot; src=&quot;http://static.tumblr.com/njo56hx/TOektl8f1/feed_rss.png&quot; /&gt;
&lt;/a&gt;</content><link rel='replies' type='application/atom+xml' href='http://devopsanywhere.blogspot.com/feeds/8978922748173487787/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://devopsanywhere.blogspot.com/2012/01/announcing-food-fight-podcast.html#comment-form' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1083699665345453745/posts/default/8978922748173487787'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1083699665345453745/posts/default/8978922748173487787'/><link rel='alternate' type='text/html' href='http://devopsanywhere.blogspot.com/2012/01/announcing-food-fight-podcast.html' title='Announcing the Food Fight Podcast'/><author><name>Anonymous</name><uri>http://www.blogger.com/profile/10631977500882582704</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjjDlxYvuXIQBmiIT466xkeith0T-xIiSOQFP_W8nALvnzdP6f-I-cCwOURv-5BvaK0MVbixCH_nFWnn_9-3KyAmJxkxJ0suBoz3gPT8DmqcdjCUGv1ZOiIH84rWPqicoeb2S7szQrjs-A/s72-c/FoodFightbanner100px.png" height="72" width="72"/><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1083699665345453745.post-7620106825714769374</id><published>2012-01-04T14:08:00.000-08:00</published><updated>2012-01-09T22:06:15.983-08:00</updated><title type='text'>Chef in 2012</title><content type='html'>&lt;div dir=&quot;ltr&quot; style=&quot;text-align: left;&quot; trbidi=&quot;on&quot;&gt;
&lt;table cellpadding=&quot;0&quot; cellspacing=&quot;0&quot; class=&quot;tr-caption-container&quot; style=&quot;float: right; text-align: right;&quot;&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td style=&quot;text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjzHJ9oam9aR_YKEjRbqF1lw7KzUekw1LyRyPRL0ZavqvVQ0msoAmrF1V7wVmlG11vKBuFY0vr6csKfPsTNDYGbLp_hufVVchFplID-dbKUKyD7Zl1DftEMuoKltSGCPPwGasHNKISe0DuI/s1600/chef-2.png&quot; imageanchor=&quot;1&quot; style=&quot;clear: right; margin-bottom: 1em; margin-left: auto; margin-right: auto;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;320&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjzHJ9oam9aR_YKEjRbqF1lw7KzUekw1LyRyPRL0ZavqvVQ0msoAmrF1V7wVmlG11vKBuFY0vr6csKfPsTNDYGbLp_hufVVchFplID-dbKUKyD7Zl1DftEMuoKltSGCPPwGasHNKISe0DuI/s320/chef-2.png&quot; width=&quot;258&quot; /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;tr-caption&quot; style=&quot;text-align: center;&quot;&gt;image by &lt;a href=&quot;http://www.hypertexthero.com/&quot;&gt;Simon Griffee&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;i&gt;Note: &lt;a href=&quot;http://petey5king.github.com/who.html&quot;&gt;Petey King&lt;/a&gt; has written a great &lt;a href=&quot;http://petey5king.github.com/2012/01/07/response-to-chef-in-2012.html&quot;&gt;response&lt;/a&gt; to this post. Definitely worth a look.&lt;/i&gt;&lt;br /&gt;
&lt;br /&gt;
I discovered Chef in the last last quarter of 2011 and turned my world upside down, work-wise at least, in a really awesome way. Over the holiday season I had some time to reflect about where Chef as a piece of software and as a community of people might go in 2012.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Packaging Cookbooks&lt;/b&gt;&lt;br /&gt;
&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;br /&gt;
Cookbooks are starting to more and more look like packages, with complex dependencies between them. I am not aware of any cookbooks that only work with Ruby 1.9.* but I expect we will see a number of them in 2012. I personally believe that we need to use an existing package management system rather than creating yet another one. RPM, DEB, dmg are all out of the question because they are operating system specific. Ruby Gems seems to be the best choice though I am not very knowledgeable about ruby gems. If you think this a terrible idea, please do let me know what problems ruby gems pose. I envision the scenario where your cookbook_path in knife.rb&lt;br /&gt;
&lt;script src=&quot;https://gist.github.com/1555727.js&quot;&gt;
 
&lt;/script&gt;
&lt;br /&gt;
&lt;br /&gt;
As you can see from my example, you still would be use cookbooks as they currently are, but also allow chef to look for additional cookbooks in your GEM_PATH. Cookbook gems would have to be prefixed with something like &quot;chef-ckbk-&quot; to indicate to knife which gems are cookbooks.&lt;br /&gt;
&lt;br /&gt;
Using ruby gems does present a couple challenges, particularly with &lt;a href=&quot;http://beginrescueend.com/&quot;&gt;rvm&lt;/a&gt;, which completely compartmentalizes gems from one ruby version to another. This means that changing your ruby interpreter &amp;nbsp;requires you install anew a large portion of your cookbooks. Using gems may also require a lot of people to change the structure of their cookbooks. Perhaps, moving moving all the directories to under gem_name/lib/ subdirectory.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Testing 1, 2, 3&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
There still isn&#39;t a broad consensus on how to automate the testing of chef cookbooks. There was some nice progress during 2011 with &lt;a href=&quot;http://acrmp.github.com/foodcritic/&quot;&gt;foodcritic&lt;/a&gt; (lint for cookbooks), &lt;a href=&quot;https://github.com/fujin/minitest-cookbook&quot;&gt;chef-minitest&lt;/a&gt; (unit-testing?), and &lt;a href=&quot;https://github.com/Atalanta/cucumber-chef&quot;&gt;cucumber-chef&lt;/a&gt; but those tools are all still early days. Testing is a particular pain point as testing a minor change to a cookbook may require testing against 5 different linux distributions. I really hope we see more progress on this front though I can&#39;t point to any particular initiatives. I personally hope to spend some quality time with minitest in the next couple weeks.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Other Miscellaneous Technical Needs&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
Selinux support is currently very limited. Some people feel that selinux shouldn&#39;t be used in the first place, however, many sysadmins don&#39;t have the luxury to make this choice themselves but are required by an external corporate or legal body to use selinux. As Andrea Campi has pointed out on the Chef mailing list, there are a number of consulting firms, such as &lt;a href=&quot;http://zephirworks.com/&quot;&gt;ZephirWorks&lt;/a&gt;, that have the capacity to implement better selinux support if someone steps forward with funding.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;table cellpadding=&quot;0&quot; cellspacing=&quot;0&quot; class=&quot;tr-caption-container&quot; style=&quot;float: right; margin-left: 1em; text-align: right;&quot;&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td style=&quot;text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhG54hbegGMPC_iU3jjif9nm4vpuIr4m5MR2mnRTCtvCCnqz3GeI5gWH_Pq_1-OLdya_ufLlkXHBx02RKQ-x2In9_5MJPCTcZgO_kPkJ5UaLTS2ePj9RW4nQy665WH2qxcAKwjZA6mFdvPw/s1600/chef-4.png&quot; imageanchor=&quot;1&quot; style=&quot;clear: right; margin-bottom: 1em; margin-left: auto; margin-right: auto;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;274&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhG54hbegGMPC_iU3jjif9nm4vpuIr4m5MR2mnRTCtvCCnqz3GeI5gWH_Pq_1-OLdya_ufLlkXHBx02RKQ-x2In9_5MJPCTcZgO_kPkJ5UaLTS2ePj9RW4nQy665WH2qxcAKwjZA6mFdvPw/s320/chef-4.png&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;tr-caption&quot; style=&quot;text-align: center;&quot;&gt;Image by Simon Griffee&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
The java application stack also needs a lot of love. The current set of tomcat, jetty, maven cookbooks only support minimal configurations. I am reorganizing these cookbooks around the &lt;a href=&quot;https://github.com/bryanwb/cookbooks/tree/master/java&quot;&gt;java_ark&lt;/a&gt; LWRP. In a nutshell, the java_ark LWRP extracts a tarball, adds any included executables in the path, and runs update-alternatives. Along with the jboss cookbook I have already started, I expect to put a lot of work into the java stack. If this is something you are interested in, suggestions, code criticism, and patches are most welcome.&lt;br /&gt;
&lt;br /&gt;
While chef-client and chef-server generally perform at acceptable levels, there are some pain points. For chef-client, memory usage can sometimes be an issue due to the node object ballooning in size during chef-client runs. If I recall correctly, Opscode is working hard on reducing memory usage so we should see some progress this year. On the server side, we can expect a lot of performance improvements as &lt;a href=&quot;http://wiki.opscode.com/display/chef/Opscode+Chef+Short-Term+Roadmap+and+Performance+Improvements&quot;&gt;chef-server moves from &lt;/a&gt;ruby + couchdb to erlang + mysql. This may happen sooner than one might normally expect as Opscode has already converted part of Hosted Chef to Erlang and MySQL, it just hasn&#39;t open-sourced that code yet.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Growing Community&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
2012 should be the year that the myths &quot;Chef is for programmers&quot; and &quot;Chef is hard&quot; are demolished. These myths sadly linger and inhibit adoption in my opinion. Perhaps part of the reason that some sysadmins think Chef is hard is that it is pure Ruby. Now Ruby is not a difficult language but it is unfamiliar to most sysadmins. Advocating Chef (and Puppet to a lesser extent) also means advocating ruby amongst sysadmins. How to do that? Here are a couple suggestions.&lt;br /&gt;
&lt;br /&gt;
&lt;ol style=&quot;text-align: left;&quot;&gt;
&lt;li&gt;Get ruby 1.9 into the default server installs for RHEL, Ubuntu, ArchLinux, etc. This could be quite a challenge as according to this &lt;a href=&quot;http://www.lucas-nussbaum.net/blog/?p=708&quot;&gt;blog post&lt;/a&gt;, there is almost nobody in the Ubuntu world doing any Ruby work. With the exception of the awesome Sergio Rubio, the same could be said for RHEL/CentOS/SL&lt;/li&gt;
&lt;li&gt;More blog articles on using Ruby to solve system administration problems and that sysadmins should consider using Ruby as their default scripting language&lt;/li&gt;
&lt;/ol&gt;
&lt;br /&gt;
All that talk about Ruby advocacy aside, Sysadmins will need to know less Ruby in 2012 in order to write Chef recipes. This is because we will see more and more LWRPs pop up. I love LWRPs. I think they are the best thing since dynamically loadable kernel modules.&lt;br /&gt;
&lt;br /&gt;
Chef is growing by leaps and bounds because it solves an important problem in configuration management. The greatest constraint to that growth is the supply of sysadmins willing to make the investment to learn it. At this point, the majority of the community are self-taught linux geeks who found Chef on their own. At the next stage of growth, Chef needs to be attractive to the group I call &quot;&lt;i&gt;the Professionals&lt;/i&gt;&quot;. &lt;i&gt;Professionals&lt;/i&gt; are talented engineers&amp;nbsp;who make system administration their job but not their life. They don&#39;t read blogs during their lunch hour and they don&#39;t hang out on IRC in the evenings. The &lt;i&gt;Professionals&lt;/i&gt; will typically learn Chef because their bosses tell them to. We need to make that learning process as smooth as possible.&lt;br /&gt;
&lt;br /&gt;
The Chef wiki is an incredible reference but we need a guided tour to accompany it. We really need the Chef equivalent to&amp;nbsp;&lt;a href=&quot;http://www.amazon.com/Pro-Git-Chacon/dp/1430218339/ref=sr_1_1?ie=UTF8&amp;amp;qid=1325713836&amp;amp;sr=8-1&quot;&gt;Pro Git&lt;/a&gt; and the &lt;a href=&quot;http://book.git-scm.com/&quot;&gt;Git Community Book site&lt;/a&gt;. These resources hold your hand and walk you through all the important parts, whispering comforting words when you get frustrated. I know there is work being done a Definitive Guide to Chef from a major publisher, but I don&#39;t know its status.&lt;br /&gt;
&lt;br /&gt;
Lastly on the subject of community, we need some mechanisms to summarize community activity.&lt;br /&gt;
The Chef project has a high velocity and I find it increasingly hard to keep up with. &amp;nbsp;The Opscode monthly newsletter is a good step in this direction. Additionally, I am starting a Chef podcast together with Opscode Technical Evangelist &lt;a href=&quot;http://devopsanywhere.blogspot.com/2012/01/chef-in-2012.html&quot;&gt;Matt Ray&lt;/a&gt;, focused on summarizing community activity and exploring important topics.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Dangers in 2012&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
I sometimes worry that Chef could become a victim of its own success. As I mentioned earlier, the greatest constraint to the growth of Chef is the supply of sysadmins willing and able to learn it. &amp;nbsp;If enough well-meaning software architects and aggressive CIOs force Chef on resistant ops teams, we will start hearing about implementations gone horribly wrong. Top-down adoption can only work if the ground below is fertile. That&#39;s my two cents.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;In Summary&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
Chef will be a success when the default installation instructions for application X point to a Chef cookbook. I think we will make solid progress towards this goal in 2012 but to really get there, a lot of &amp;nbsp;things have to happen first. I couldn&#39;t be more excited. Thanks to everyone in the Chef community for giving sysadmins like me such a great toy to play with. Happy Hacking!&lt;br /&gt;
&lt;br /&gt;
PS: Let me know if you like the Chef icons. My good buddy Simon Griffee created them after a brainstorming session fueled by &lt;a href=&quot;http://en.wikipedia.org/wiki/Sagrantino_di_Montefalco&quot;&gt;Sagrantino Di Montefalco&lt;/a&gt;.&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://devopsanywhere.blogspot.com/feeds/7620106825714769374/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://devopsanywhere.blogspot.com/2012/01/chef-in-2012.html#comment-form' title='6 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1083699665345453745/posts/default/7620106825714769374'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1083699665345453745/posts/default/7620106825714769374'/><link rel='alternate' type='text/html' href='http://devopsanywhere.blogspot.com/2012/01/chef-in-2012.html' title='Chef in 2012'/><author><name>Anonymous</name><uri>http://www.blogger.com/profile/10631977500882582704</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjzHJ9oam9aR_YKEjRbqF1lw7KzUekw1LyRyPRL0ZavqvVQ0msoAmrF1V7wVmlG11vKBuFY0vr6csKfPsTNDYGbLp_hufVVchFplID-dbKUKyD7Zl1DftEMuoKltSGCPPwGasHNKISe0DuI/s72-c/chef-2.png" height="72" width="72"/><thr:total>6</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1083699665345453745.post-9135539448009990670</id><published>2011-11-20T05:14:00.001-08:00</published><updated>2011-11-20T23:13:31.995-08:00</updated><title type='text'>Emacs for Sysadmins</title><content type='html'>&lt;div dir=&quot;ltr&quot; style=&quot;text-align: left;&quot; trbidi=&quot;on&quot;&gt;
I am not going to tell you that emacs is superior to vi, because it is not. For me, vi is far better for basic text editing. However, emacs has such powerful modes that I find myself using it more often than vi these days. Emacs has historically been favored by programmers and vi by sysadmins. I have written in the past &amp;nbsp;that sysadmins are becoming less like ninjas and more like pirates because of this crazy thing called devops.&lt;br /&gt;
&lt;br /&gt;
As a professional system administrator you can&#39;t choose between vi and emacs; you have to learn vi. There are just too many times you will be working on an arbitrary *nix that only has vi installed. You can choose to learn emacs in addition to vi. Vi lets you jump in and around files quickly. Nothing can match the speed of &lt;i&gt;hjkl&lt;/i&gt;, &lt;i&gt;g&lt;/i&gt;, &lt;i&gt;G&lt;/i&gt;, etc. for movement or &lt;i&gt;v&lt;/i&gt; + &lt;i&gt;y&lt;/i&gt; for copying text. However, we sysadmins are moving from managing individual servers to managing configurations. In the last several couple months I have spent at least 50% of my work time entirely within my chef-repo/ directory working on data bags, roles, and cookbooks. Inspired by the devotion of a number of Chef community members to emacs--notably Matt Ray, Stephen Nelson-Smith, Josh Timberman, among others--I decided to give emacs a try. On the whole, it has been a very positive experience. That is why I recommend sysadmins try emacs.&lt;br /&gt;
&lt;br /&gt;
&lt;table border=&quot;0&quot; style=&quot;width: 320px;&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;center&gt;&lt;strong&gt;Ninja&lt;/strong&gt;&lt;/center&gt;&lt;/td&gt;
&lt;td&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;center&gt;&lt;strong&gt;Pirate&lt;/strong&gt;&lt;/center&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;img alt=&quot;bill-joy1&quot; class=&quot;center size-thumbnail wp-image-1180&quot; height=&quot;150&quot; src=&quot;http://philosecurity.org/wp-content/uploads/2009/03/bill-joy1-150x150.jpg&quot; title=&quot;bill-joy1&quot; width=&quot;150&quot; /&gt;&lt;/td&gt;
&lt;td&gt;&lt;img alt=&quot;richard-stallman-small&quot; class=&quot;center size-thumbnail wp-image-1181&quot; height=&quot;150&quot; src=&quot;http://philosecurity.org/wp-content/uploads/2009/03/richard-stallman-small-150x150.jpg&quot; title=&quot;richard-stallman-small&quot; width=&quot;150&quot; /&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;center&gt;&lt;strong&gt;Bill Joy&lt;br /&gt;Vi Creator&lt;/strong&gt;&lt;br /&gt;&lt;em&gt;Hand placement conceals poison dart&lt;/em&gt;&lt;/center&gt;&lt;/td&gt;
&lt;td&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;center&gt;&lt;strong&gt;Richard Stallman&lt;br /&gt;Emacs Creator&lt;/strong&gt;&lt;br /&gt;&lt;em&gt;Note beard&lt;/em&gt;&lt;/center&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
from philosecurity blog &lt;a href=&quot;http://philosecurity.org/2009/03/23/pirates-and-ninjas-emacs-or-vi&quot;&gt;ninjas or pirates, emacs or vi&lt;/a&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-size: large;&quot;&gt;Why Emacs?&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
Emacs has some truly awesome modes. The default ruby, python, bash, xml, html seem to do more than their vim counterparts. I think this is large part because emacs&#39; extension language (elisp) is more powerful than vimscript. I made a stab at vimscript some years ago but came away quite frustrated. While I am not a lisp convert, it is a full-featured language that doesn&#39;t hold you back. Working with multiple buffers (10+) is extremely easy. Org-mode though, is what got me hooked.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-size: large;&quot;&gt;Why Not Emacs?&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
Using vi is like being in a relationship, you are involved. Using Emacs is like a marriage, you are committed, in large part because there is so much to learn. This is one of the reasons I don&#39;t recommend it for everyone.&lt;br /&gt;
&lt;br /&gt;
Further, vi is built for touch typists. You rarely, if ever, have to take your fingers off the home row keys. You can keep your fingers on the home row with emacs but that often means completing a number of key chords entirely with your left hand. Take for example opening a file, writing its contents to another file, and then closing emacs.&lt;br /&gt;
&lt;br /&gt;
C-x C-f &amp;nbsp;+ C-x C-w + C-x C-k&lt;br /&gt;
&lt;br /&gt;
If you keep your fingers on the home row, you will only use your left-hand for the above commands, except for the final &quot;k&quot;. You could start to feel some discomfort in your left hand if you did that key sequence several times in a row. For this reason a number of emacs addicts will hit the Control key with their right hand, the &quot;x&quot; with their left, Control again with the right, &quot;f&quot; with the left, and so on. This leads to a more &quot;hunt and peck&quot; typing style but saves your hands.&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-size: large;&quot;&gt;First, Learn How to be a Pirate&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-size: large;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;
Before you even start playing with emacs you should make sure to swap your Caps Lock and left Control key. Emacs commands use the Control key heavily and leaving it in the default position will soon leave you angry, crippled, and ready to kill Richard Stallman.&lt;br /&gt;
&lt;br /&gt;
Next, I recommend you organize your dotfiles on github or another source code repository. Being a pirate means you have booty and treasure to carry around. You need a ship to carry around all that treasure and for me that ship is &lt;a href=&quot;https://github.com/bryanwb/dotfiles&quot;&gt;github&lt;/a&gt;. The core of my dotfiles repo is the Rakefile, copied &lt;a href=&quot;http://github.com/ryanb/dotfiles/tree/master&quot;&gt;from Ryan Bates&#39; master&lt;/a&gt;, that makes it dead simple to install your dotfiles on a new machine. I don&#39;t install my dotfiles on every machine I work on, only the 2-3 I use most frequently.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;ol style=&quot;text-align: left;&quot;&gt;
&lt;li&gt;&amp;nbsp;create your own github/bitbucket/private github repo called dotfiles&lt;/li&gt;
&lt;li&gt;copy your existing dotfiles -- .bashrc, .vimrc, .emacs, etc -- to ~/dotfiles but without the leading &quot;.&quot; !&lt;/li&gt;
&lt;li&gt;download Ryan Bates &lt;a href=&quot;http://github.com/ryanb/dotfiles/tree/master&quot;&gt;Rakefile&lt;/a&gt;&amp;nbsp;and put it in ~/dotfiles&lt;/li&gt;
&lt;li&gt;to test, rename ~/.bashrc to to ~/.bashrc_bak then run $ cd ~/dotfiles/ &amp;amp;&amp;amp; rake install. &amp;nbsp;Your .bashrc should be back&lt;/li&gt;
&lt;li&gt;Push to your repository&lt;/li&gt;
&lt;/ol&gt;
&lt;br /&gt;
Whenever you make a change to your .emacs or .bashrc &amp;nbsp;on your ubuntu laptop at home, remember to push your changes and then run &quot;rake install&quot; on your work desktop.&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-size: large;&quot;&gt;Learning Emacs&lt;/span&gt;&lt;br /&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
OK, finally emacs. I recommend you buy Peepcode&#39;s &quot;&lt;a href=&quot;http://peepcode.com/products/meet-emacs&quot;&gt;Meet Emacs&lt;/a&gt;&quot; tutorial. It is only $12 and it is the best and most convincing emacs tutorial. It is well worth the money. If this tutorial doesn&#39;t convince you that emacs is worth your time stop, turn around, and go back to vi. One of the first things covered in &quot;Meet Emacs&quot; is how to install emacs 24 and the &lt;a href=&quot;https://github.com/technomancy/emacs-starter-kit&quot;&gt;emacs-starter-kit&lt;/a&gt;. The emacs starter kit will set of bunch of defaults that help you avoid many of emacs&#39; warts and show off some awesomeness such as ido-mode.&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-size: large;&quot;&gt;Org-Mode, Emacs Killer Feature&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
Ok, I have to admit that I have been working with emacs for longer than a few months. I have been using emacs&#39; &lt;a href=&quot;http://orgmode.org/&quot;&gt;Org-Mode&lt;/a&gt; to manage my life for the last several years, ever since I happened upon Abhijeet Chavan&#39;s &lt;a href=&quot;http://www.linuxjournal.com/article/9116&quot;&gt;great article&lt;/a&gt; in Linux Journal. Soon after that, I came across Scott Jaderholm&#39;s excellent &lt;a href=&quot;http://jaderholm.com/screencasts/org-mode/&quot;&gt;screencast&lt;/a&gt; for Org-mode. At the time I read the article, I was the Chief Technology Officer for a &lt;a href=&quot;http://olenepal.org/&quot;&gt;non-profit technology startup&lt;/a&gt; in Kathmandu, Nepal. I was completely overwhelmed by the sheer volume of different tasks I had to accomplish and all the attendant details, especially the details. I no longer have all that stress now that I am a regular sysadmin, but I do have a large number of very detailed tasks. Org-mode is in many ways my memory. It is also how I manage my attention span.&lt;br /&gt;
&lt;br /&gt;
Many people use Org-mode to implement the &lt;a href=&quot;http://en.wikipedia.org/wiki/Getting_Things_Done&quot;&gt;Getting Things Done&lt;/a&gt; methodology, pioneered by David Allen. I have bastardized it into my own system.&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjTGSMKEqT8G2mJ6xm5CqrPr5w404rU3_P_SS0xaZDLE_GCmsdPlg1cfe979ljdv-uMFTnf_faBVT96uSqE5LMQHYnZdVdzv8o6u7f9uvbnh65ymbNU8CsgzKkAA-WCWt0dlysU3o2eiAyY/s1600/Screenshot--home-hitman-org-mygtd.org.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;204&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjTGSMKEqT8G2mJ6xm5CqrPr5w404rU3_P_SS0xaZDLE_GCmsdPlg1cfe979ljdv-uMFTnf_faBVT96uSqE5LMQHYnZdVdzv8o6u7f9uvbnh65ymbNU8CsgzKkAA-WCWt0dlysU3o2eiAyY/s320/Screenshot--home-hitman-org-mygtd.org.png&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
Today is a list of general things that I want to get done today. This week, a list of tasks to complete this week. And of course, right now is a list of specific next actions, that I will complete starting at 1.&lt;br /&gt;
&lt;br /&gt;
When you are finished with a task, don&#39;t delete it. Archive it so you have a record of when you are done. Org-mode handily records the timestamp of when you completed the item.&lt;br /&gt;
&lt;br /&gt;
C-c $ &amp;nbsp; &amp;nbsp; &amp;nbsp; # archives a subtree to your archive file,&lt;br /&gt;
&lt;br /&gt;
If I finish reading the O&#39;Reilly Emacs Manual and then archive it, here is what the entry looks like.&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiPnF2LAulaKxTIKeE9F7ezj8JaExH0fE_vKUiWmPW7pXYYU12LvXE-Z5HhdVmJ-ugK09UEA78KIkKnKqXLYrcHtDogVgjeuxI-csjVL8I56MQ4wg0HHdqomrM_N5xEGCJe0D9zu0wv0siY/s1600/Screenshot--home-hitman-org-mygtd.org_archive.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;204&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiPnF2LAulaKxTIKeE9F7ezj8JaExH0fE_vKUiWmPW7pXYYU12LvXE-Z5HhdVmJ-ugK09UEA78KIkKnKqXLYrcHtDogVgjeuxI-csjVL8I56MQ4wg0HHdqomrM_N5xEGCJe0D9zu0wv0siY/s320/Screenshot--home-hitman-org-mygtd.org_archive.png&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
I love that I can move items in a numbered list almost effortlessly. M-&amp;lt;up&amp;gt; moves an item up and adjusts the numbering and M-&amp;lt;down&amp;gt; moves an item down in the list.&lt;br /&gt;
&lt;br /&gt;
I typically keep the following org-mode files and their associated archive files.&lt;br /&gt;
&lt;br /&gt;
&lt;ul style=&quot;text-align: left;&quot;&gt;
&lt;li&gt;mygtd.org -- my todo list, for today, this week, this month, and right now!&lt;/li&gt;
&lt;li&gt;meetings.org -- all meeting notes and preparation&lt;/li&gt;
&lt;li&gt;notes.org &amp;nbsp;-- this is where I keep notes while I work on a problem&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
The notes.org file deserves special attention. This is my running work log. As I diagnose a problem, I write up my possible hypotheses, then tests for these hypotheses. Finally, I record the results of testing those hypotheses, pass or fail.&lt;br /&gt;
&lt;br /&gt;
The true beauty of using emacs to manage your todo list is that you can grep through it to find a specific piece of information. This has saved my ass more times than I can count.&lt;br /&gt;
&lt;br /&gt;
Org-mode protip: put your *.org files in a Dropbox folder so you have access to them on your various machines. It may be tempting to put them on github but you should realize that those org files will quickly fill up with personal and corporate information.&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-size: large;&quot;&gt;Working with Buffers&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
I never found it that easy to work with multiple buffers or tabs in vim without doing extensive key rebinding. Buffers are something that emacs really gets right, especially when you have ido-mode turned on. I have found working with multiple &amp;nbsp;buffers really effective when working with several chef cookbooks at once.&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi9xn-z0hfeGDekmhAbg63s2A0jIpdkWIG8P_FxfSWfElKitvpesI5pDJCDsPRldKucx_X7KH0Q4R7M8Wyv2pMwtdwFvmZBt9OOxYHmJjgONWO1b0lF0_iAYq_-tFOatx6kjBporffJ3VmN/s1600/Screenshot-+*Minibuf-1*-1.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;204&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi9xn-z0hfeGDekmhAbg63s2A0jIpdkWIG8P_FxfSWfElKitvpesI5pDJCDsPRldKucx_X7KH0Q4R7M8Wyv2pMwtdwFvmZBt9OOxYHmJjgONWO1b0lF0_iAYq_-tFOatx6kjBporffJ3VmN/s320/Screenshot-+*Minibuf-1*-1.png&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;/div&gt;
&lt;br /&gt;
Let&#39;s say I am working in the sudo/recipes/default.rb recipe but want to jump back to the previous recipe I was working on, in this case iptables/recipes/default.rb. I type C-x b and ido-mode shows me a list of open buffers. To get the last buffer I was in before this, simply hit [RET] or I can start typing the name of the file and ido-mode will dynamically filter that list.&lt;br /&gt;
&lt;br /&gt;
C-x b &amp;nbsp;[RET] &amp;nbsp;to get to the last visited buffer&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-size: large;&quot;&gt;Dired-Mode&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
I have always heard that &lt;a href=&quot;https://www.midnight-commander.org/&quot;&gt;Midnight Commander&lt;/a&gt; is an awesome but I have never taken the time to learn it. I believe that Dired-Mode offers many of the features of Midnight Commander but lets you leverage the emacs skills you have picked up.&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhgTCDPYdjbXDDjyvWlCjtTn808T_UgdKB_wWkjBy0pRb5I61IcLoixggKh2GCwDxdSEgkXmiO86tiANcUVIXeq7WKT7GOD7t0fKj37mlhgi_a72H3eSMkxgWoKquIiX-qeAoFW8IAYMglI/s1600/Screenshot-cookbooks.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;206&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhgTCDPYdjbXDDjyvWlCjtTn808T_UgdKB_wWkjBy0pRb5I61IcLoixggKh2GCwDxdSEgkXmiO86tiANcUVIXeq7WKT7GOD7t0fKj37mlhgi_a72H3eSMkxgWoKquIiX-qeAoFW8IAYMglI/s320/Screenshot-cookbooks.png&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
Here are commands that I love&lt;br /&gt;
&lt;br /&gt;
&lt;table border=&quot;2&quot; bordercolor=&quot;#0033FF&quot; cellpadding=&quot;3&quot; cellspacing=&quot;3&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;th&gt;Key Binding&lt;/th&gt;
&lt;th&gt;Command&lt;/th&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;v&lt;/td&gt;
&lt;td&gt;View a file or directory in read-only mode&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;d&lt;/td&gt;
&lt;td&gt;mark a file or directory for deletion&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;C&lt;/td&gt;
&lt;td&gt;Copy a file&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;x&lt;/td&gt;
&lt;td&gt;execute changes marked, i.e. delete files marked for deletion&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;q&lt;/td&gt;
&lt;td&gt;close an open dired buffer&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;[RET]&lt;/td&gt;
&lt;td&gt;when u hit [RET] on a file, emacs opens it for editing&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;R&lt;/td&gt;
&lt;td&gt;Rename or move a file or directory&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;M-x find-grep-dired&lt;/td&gt;
&lt;td&gt;Grep a directory for a regex and then view the matching files in a Dired Buffer&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Q&lt;/td&gt;
&lt;td&gt;Find and replace a regex across multiple files&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;br /&gt;
&lt;br /&gt;
While Dired-Mode is very useful for managing files I find it most useful for browsing code. You can hit &quot;v&quot; to view as read-only then q to close that buffer when you are done. Viewing files in emacs means you get all that juicy syntax highlighting. This helps me make sense of those butt-ugly XML configuration files I encounter on jboss and tomcat installations.&lt;br /&gt;
&lt;br /&gt;
&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-size: large;&quot;&gt;Miscellaneous Stuff I find Useful in Emacs&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;ul style=&quot;text-align: left;&quot;&gt;
&lt;li&gt;Shell-Mode - This is very handy for moving text back and forth from a shell and code file. &amp;nbsp;&lt;i&gt;M-x shell-command-region&lt;/i&gt;&amp;nbsp;or &lt;i&gt;M-!&lt;/i&gt; lets you execute a shell command on a region of selected text&lt;/li&gt;
&lt;li&gt;Inf-Ruby-mode - lets you select a bunch of ruby code and immediately execute it in an irb session. I would love to see this work with &lt;a href=&quot;http://wiki.opscode.com/display/chef/Shef&quot;&gt;shef&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Modes for Languages you rarely touch - I rarely code in java but occasionally I have to read java code. java-mode helps me parse java without having to deal with Eclipse. Have to change a config file written in Erlang? There&#39;s a mode for that.&lt;/li&gt;
&lt;li&gt;Properly indenting text - select a region then &lt;i&gt;C-M-\&lt;/i&gt;&lt;/li&gt;
&lt;li&gt;Completion - &lt;i&gt;M-/&lt;/i&gt; will guess what you are trying to type based on open buffers&lt;/li&gt;
&lt;li&gt;Commenting out multiple lines of code -- select a region, &lt;i&gt;M-;&lt;/i&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-size: large;&quot;&gt;Emacs Shortcuts are Everywhere&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
In case you haven&#39;t already noticed, virtually every unix shell and programming REPL (irb, python, perl) supports Emacs keyboard shortcuts. This is because all those shells are built on top of libreadline, which implements a subset of emacs shortcuts. Even REPL&#39;s for newer JVM languages like scala, groovy, and clojure use a clone of libreadline, jline, that implements those same shortcuts.&lt;br /&gt;
&lt;br /&gt;
&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-size: large;&quot;&gt;Emacs Stuff I Haven&#39;t Learned Yet but Want to&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;ul style=&quot;text-align: left;&quot;&gt;
&lt;li&gt;Tramp-Mode -- editing files over SSH, this would be pretty sweet for configuring a bunch of Virtual Box VM&#39;s running on my desktop&lt;/li&gt;
&lt;li&gt;Calendar Integration with gmail - just haven&#39;t gotten around to this yet&lt;/li&gt;
&lt;li&gt;ERC - I debate whether to move from Xchat to irrsi or ERC (Emacs irc client). jury is still out&lt;/li&gt;
&lt;li&gt;gist - This is a mode that allows you to select a region and create a github gist from it&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-size: large;&quot;&gt;Wrapping Up&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
Emacs, despite conventional wisdom, can be very useful for systems administrators and not solely the domain of Lisp Hackers and not Exclusively for Middle-Aged Computer Scientists. While it may be One True Program for some people, it is not for everyone. The highlights of Emacs for me are:&lt;br /&gt;
&lt;ol style=&quot;text-align: left;&quot;&gt;
&lt;li&gt;Org-mode -- time management for busy sysadmins&lt;/li&gt;
&lt;li&gt;Dired Mode&amp;nbsp;&lt;/li&gt;
&lt;li&gt;Buffer Management&amp;nbsp;&lt;/li&gt;
&lt;/ol&gt;
&lt;div&gt;
If you have some tricks that you find especially useful for sysadmin work, please share them!&amp;nbsp;Here are some additional resources you may want to look at:&lt;br /&gt;
&lt;br /&gt;
&lt;ul style=&quot;text-align: left;&quot;&gt;
&lt;li&gt;&lt;a href=&quot;http://batsov.com/articles/2011/11/19/why-emacs/&quot;&gt;Why Emacs?&lt;/a&gt;&amp;nbsp;Borizhdar Batisov&#39;s excellent, more developer-focussed ode to emacs&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://www.youtube.com/user/rpdillon?blend=16&amp;amp;ob=5&quot;&gt;Hack Emacs&lt;/a&gt; Screencasts&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://www.masteringemacs.org/&quot;&gt;Mastering Emacs blog&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://www.google.it/url?sa=t&amp;amp;rct=j&amp;amp;q=emacswiki&amp;amp;source=web&amp;amp;cd=1&amp;amp;ved=0CCEQFjAA&amp;amp;url=http%3A%2F%2Fwww.emacswiki.org%2F&amp;amp;ei=cvDJTp-oA8_Lsga69cj5Dg&amp;amp;usg=AFQjCNGUR32VnH8IftoPDbPepFoTRlpUAg&quot;&gt;Emacswiki&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;#emacs on freenode.net&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://devopsanywhere.blogspot.com/feeds/9135539448009990670/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://devopsanywhere.blogspot.com/2011/11/emacs-for-sysadmins.html#comment-form' title='6 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1083699665345453745/posts/default/9135539448009990670'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1083699665345453745/posts/default/9135539448009990670'/><link rel='alternate' type='text/html' href='http://devopsanywhere.blogspot.com/2011/11/emacs-for-sysadmins.html' title='Emacs for Sysadmins'/><author><name>Anonymous</name><uri>http://www.blogger.com/profile/10631977500882582704</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjTGSMKEqT8G2mJ6xm5CqrPr5w404rU3_P_SS0xaZDLE_GCmsdPlg1cfe979ljdv-uMFTnf_faBVT96uSqE5LMQHYnZdVdzv8o6u7f9uvbnh65ymbNU8CsgzKkAA-WCWt0dlysU3o2eiAyY/s72-c/Screenshot--home-hitman-org-mygtd.org.png" height="72" width="72"/><thr:total>6</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1083699665345453745.post-3772433204669444190</id><published>2011-11-20T00:26:00.001-08:00</published><updated>2011-11-20T06:04:08.878-08:00</updated><title type='text'>Chef for Developers</title><content type='html'>&lt;div dir=&quot;ltr&quot; style=&quot;text-align: left;&quot; trbidi=&quot;on&quot;&gt;
&lt;br /&gt;
Last Friday I gave a presentation to a group of developers on how they can get started writing Chef cookbooks. I put about 5 hours into writing this presentation. To my chagrin, Warwick Poole released a &lt;a href=&quot;http://learnchef.getharvest.com/&quot;&gt;superior presentation&lt;/a&gt;&amp;nbsp;that same afternoon that does a better job of explaining the basic concepts of Chef. I strongly recommend checking out Warwick&#39;s &lt;a href=&quot;http://learnchef.getharvest.com/&quot;&gt;&quot;LearnChef&quot;&lt;/a&gt; if you haven&#39;t already. It is the single best introduction to Chef that I have seen so far. In more good news, Warwick informs me that he intends to create a 5 part series building on &quot;LearnChef.&quot; I very much look forward to it.&lt;br /&gt;
&lt;br /&gt;
My Chef presentation doesn&#39;t do as good a job explaining the core concepts of Chef but it does walk developers through some scenarios on how they can work with chef on a project. You can check it out below and even reuse my slide material by downloading the .ppt file&amp;nbsp;&lt;a href=&quot;https://docs.google.com/presentation/d/1ZLMwDeUCu84o6qWGlGfi3x-buhC2YorAYxD7v6hA92o/edit&quot;&gt;here&lt;/a&gt;. My slides borrow heavily from Joshua Timberman&#39;s excellent &lt;a href=&quot;http://wiki.opscode.com/download/attachments/2883634/Chef-101-OSCON_Preview.pdf?version=1&amp;amp;modificationDate=1278531594000&quot;&gt;Chef 101 presentation&lt;/a&gt;. The slides are under the Creative Commons 3.0 Unported CC-BY-SA. You can find the &lt;a href=&quot;http://wiki.opscode.com/display/chef/Chef+Presentations&quot;&gt;full list&lt;/a&gt; of publicly available Chef presentations on the Chef wiki.

&lt;br /&gt;
&lt;div id=&quot;__ss_10238978&quot; style=&quot;width: 425px;&quot;&gt;
&lt;strong style=&quot;display: block; margin: 12px 0 4px;&quot;&gt;&lt;a href=&quot;http://www.slideshare.net/bryanwb/chef-devops-and-you&quot; title=&quot;Chef, Devops, and You&quot;&gt;Chef, Devops, and You&lt;/a&gt;&lt;/strong&gt;&lt;object height=&quot;355&quot; id=&quot;__sse10238978&quot; width=&quot;425&quot;&gt;&lt;param name=&quot;movie&quot; value=&quot;http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=chef-101-bwb-v3-111120022114-phpapp01&amp;stripped_title=chef-devops-and-you&amp;userName=bryanwb&quot; /&gt;


&lt;param name=&quot;allowFullScreen&quot; value=&quot;true&quot;/&gt;


&lt;param name=&quot;allowScriptAccess&quot; value=&quot;always&quot;/&gt;


&lt;param name=&quot;wmode&quot; value=&quot;transparent&quot;/&gt;


&lt;embed name=&quot;__sse10238978&quot; src=&quot;http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=chef-101-bwb-v3-111120022114-phpapp01&amp;stripped_title=chef-devops-and-you&amp;userName=bryanwb&quot; type=&quot;application/x-shockwave-flash&quot; allowscriptaccess=&quot;always&quot; allowfullscreen=&quot;true&quot; wmode=&quot;transparent&quot; width=&quot;425&quot; height=&quot;355&quot;&gt;&lt;/embed&gt;&lt;/object&gt;&lt;br /&gt;
&lt;div style=&quot;padding: 5px 0 12px;&quot;&gt;
View more &lt;a href=&quot;http://www.slideshare.net/&quot;&gt;presentations&lt;/a&gt; from &lt;a href=&quot;http://www.slideshare.net/bryanwb&quot;&gt;Bryan Berry&lt;/a&gt;.&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://devopsanywhere.blogspot.com/feeds/3772433204669444190/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://devopsanywhere.blogspot.com/2011/11/chef-presentations.html#comment-form' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1083699665345453745/posts/default/3772433204669444190'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1083699665345453745/posts/default/3772433204669444190'/><link rel='alternate' type='text/html' href='http://devopsanywhere.blogspot.com/2011/11/chef-presentations.html' title='Chef for Developers'/><author><name>Anonymous</name><uri>http://www.blogger.com/profile/10631977500882582704</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1083699665345453745.post-2661785546577878625</id><published>2011-10-30T06:14:00.000-07:00</published><updated>2011-10-30T09:48:21.275-07:00</updated><title type='text'>A Month with Chef</title><content type='html'>&lt;div dir=&quot;ltr&quot; style=&quot;text-align: left;&quot; trbidi=&quot;on&quot;&gt;
It is hard to believe that I started using &lt;a href=&quot;http://wiki.opscode.com/display/chef/Home&quot;&gt;Chef&lt;/a&gt; only one month ago. The experience has hugely changed how I view the practice of system administration and started to unseat the deepest of ingrained habits. It has been mostly a smooth ride but there have been some significant bumps along the way. Here are my reflections on learning Chef, the community around it, putting it to work, and my hopes for the future of the project.&lt;br /&gt;
&lt;div class=&quot;p1&quot;&gt;
&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/div&gt;
&lt;div class=&quot;p1&quot;&gt;
&lt;b&gt;Learning Curve&lt;/b&gt;&lt;/div&gt;
&lt;div class=&quot;p2&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class=&quot;p1&quot;&gt;
There are roughly three technology components to learning chef, each with their own learning curve 1) the Chef software itself 2) git and 3) ruby. I found understanding Chef to be quite easy, in large part because of prior experience with Puppet. If you have never used a configuration management tool before, this can be a stumbling block. However, the biggest stumbling block of the three is probably git, not ruby and not the Chef software itself. Again, I had previous experience with git but even I ran into occasional git-induced hurdles.&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;p2&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class=&quot;p1&quot;&gt;
When you treat your &quot;infrastructure as code,&quot; you have to spend a fair amount of time managing that code. Git is the tool you will use to manage your chef repository, your cookbooks, pull updates the mainline opscode/cookbooks and push your patches to others. If you are a n00b to both &amp;nbsp;Chef and git, do yourself a favor and reach for &lt;a href=&quot;http://ftp.newartisans.com/pub/git.from.bottom.up.pdf&quot;&gt;&lt;span class=&quot;s1&quot;&gt;a good git tutorial&lt;/span&gt;&lt;/a&gt; before you get too deep into Chef.&lt;/div&gt;
&lt;div class=&quot;p2&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class=&quot;p1&quot;&gt;
The fact that Chef recipes are written in Ruby has turned out to be far less of an impediment than I thought. You can learn enough Ruby to write a recipe &lt;a href=&quot;http://wiki.opscode.com/display/chef/Just+Enough+Ruby+for+Chef&quot;&gt;&lt;span class=&quot;s1&quot;&gt;in less than twenty minutes&lt;/span&gt;&lt;/a&gt;. Further, with copy-and-paste plus playing with &lt;a href=&quot;http://en.wikipedia.org/wiki/Interactive_Ruby_Shell&quot;&gt;irb&lt;/a&gt; you can guess your way to getting a lot accomplished--though this isn&#39;t a good strategy for the long-term. For my own education, I read the &lt;a href=&quot;http://pragprog.com/book/ruby/programming-ruby&quot;&gt;&lt;span class=&quot;s2&quot;&gt;pickaxe book&lt;/span&gt;&lt;/a&gt; and Flanagan&#39;s &lt;a href=&quot;http://shop.oreilly.com/product/9780596516178.do&quot;&gt;&lt;span class=&quot;s2&quot;&gt;The Ruby Programming Language&lt;/span&gt;&lt;/a&gt;. Both were good but I prefer the Ruby Programming Language. I have heard from others that &lt;a href=&quot;http://rubykoans.com/&quot;&gt;Ruby Koans&lt;/a&gt; is an excellent way to learn Ruby though I haven&#39;t tried them myself.&lt;/div&gt;
&lt;div class=&quot;p2&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class=&quot;p1&quot;&gt;
My first impressions of Ruby the language are shaped in part by my experiences working in the Python world. Python is clean and neat and you can see the hand of &lt;a href=&quot;http://www.python.org/~guido/&quot;&gt;&lt;span class=&quot;s2&quot;&gt;Guido&lt;/span&gt;&lt;/a&gt;&amp;nbsp;guiding the language and standard library at every turn. Conversely, Ruby is creative, chaotic, and messy. It has bitten me in the ass several times that Ruby has hundreds of top-level methods and operators. To say that the namespaces are &quot;cluttered&quot; is an understatement. You have to be quite careful when creating new variables and method names. For instance, In one recipe I created the variables &quot;alias&quot; and &quot;rand&quot;, which are coincidentally top-level Ruby methods. Overwriting them caused some nasty side effects that took me a while to track down. If Ruby were a human being it would have a beautiful body, a terrible case of acne, and noticeable digestive problems. Worse yet, its clothes wouldn&#39;t match.&lt;/div&gt;
&lt;div class=&quot;p2&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class=&quot;p1&quot;&gt;
My biggest single problem with Ruby is that &lt;i&gt;shit breaks&lt;/i&gt;. Last week the main json gem was broken, causing pain throughout the Ruby world. With my first install of Chef-Server, the code-ray gem broke the chef-server-webui. As I am not a rubyist, it took me a non-trivial amount of time to figure out how to downgrade to an older version with the following command &lt;i&gt;$ gem install code-ray --version &#39;&amp;lt; 0.9.8&#39;.&lt;/i&gt; I have since discovered the concept of gem sets, which define dependencies to specific gems per specific versions. Why would you have to do this? Because you can&#39;t count that the latest gem release will be stable. Working with Python I rarely had these same kinds of problems. On the plus side, the Ruby community &lt;i&gt;moves fast&lt;/i&gt;. For whatever reason(s), new Ruby projects pop up quickly and continue to evolve at an astonishing pace. Tools like &lt;a href=&quot;https://github.com/wycats/thor/wiki&quot;&gt;&lt;span class=&quot;s2&quot;&gt;thor&lt;/span&gt;&lt;/a&gt;, &lt;a href=&quot;http://www.sinatrarb.com/&quot;&gt;&lt;span class=&quot;s2&quot;&gt;sinatra&lt;/span&gt;&lt;/a&gt;, &lt;a href=&quot;https://github.com/capistrano/capistrano/wiki/&quot;&gt;&lt;span class=&quot;s2&quot;&gt;capistrano&lt;/span&gt;&lt;/a&gt;, and &lt;a href=&quot;http://fog.io/1.0.0/index.html&quot;&gt;&lt;span class=&quot;s2&quot;&gt;fog&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt; &lt;/span&gt;&lt;/a&gt;all seemed to appear before &amp;nbsp;their Pythonic equivalents*.&lt;/div&gt;
&lt;div class=&quot;p3&quot;&gt;
&lt;i&gt;* software historians, please correct me if I am mistaken&lt;/i&gt;&lt;/div&gt;
&lt;div class=&quot;p2&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class=&quot;p1&quot;&gt;
It is easy to overlook that Chef assumes you already thoroughly understand your operating system and application stack. Chef makes experienced system administrators more productive. It also makes inexperienced system administrators more dangerous and can even hamper their learning. It is for this reason that I don&#39;t recommend that those new to *nix pick up Chef. You can&#39;t automate something you don&#39;t understand.&lt;/div&gt;
&lt;div class=&quot;p2&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class=&quot;p1&quot;&gt;
&lt;b&gt;Using Chef&lt;/b&gt;&lt;/div&gt;
&lt;div class=&quot;p2&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class=&quot;p1&quot;&gt;
My experience with Chef has not been all roses. Like Ruby, Chef moves fast. For a FOSS project, it is ridiculously young, first released in January 2009 and has not even reached version 1.0 yet. It still has significant bugs and Linux distribution support is still quite uneven, especially compared to &lt;a href=&quot;http://www.puppetlabs.com/&quot;&gt;Puppet&lt;/a&gt;. To their credit, the Opscoders acknowledge these issues. It must be noted, Opscode did not officially support Enterprise Linux until recently.&amp;nbsp; Further, despite its youth, I found the Chef-Server to be quite stable and easy to setup.&lt;/div&gt;
&lt;div class=&quot;p2&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class=&quot;p1&quot;&gt;
I had a nasty time with the initial installation. It took me over three days to complete, mostly due to a bug in Ohai that misreported the linux distribution. However, that was early October. I did a fresh install last week and it took me only 30 minutes, largely due to documentation improvements, bug fixes, and updated rpms for both EL 5 and 6.&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;p2&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class=&quot;p1&quot;&gt;
The &lt;a href=&quot;https://github.com/opscode/cookbooks&quot;&gt;opscode cookbooks&lt;/a&gt;, like the chef software, have spotty support for Enterprise Linux. One of the first cookbooks I tried to use was the selinux cookbook. I couldn&#39;t even upload that cookbook to my chef-server as it has a syntax error. I have sent a patch, logged a ticket, and sent a pull request to fix the error. That issue was not fixed the last time I checked. My pull request isn&#39;t lonely either. Last time I checked on github.com and I saw that there were 99 open pull requests &lt;a href=&quot;https://github.com/opscode/cookbooks/pulls&quot;&gt;in their queue&lt;/a&gt;. My impression is that the Opscoders are not intentionally ignoring such requests but are struggling to keep up with the rapid growth of Chef community and Opscode&#39;s paying customer base. I hope this improves in the months ahead.&lt;/div&gt;
&lt;div class=&quot;p2&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class=&quot;p1&quot;&gt;
Once I got Chef-server up and running, I felt a bit lost. Chef is a very flexible tool and not nearly as opinionated as Puppet. It is hard to decide where to get started. One can easily get lost among Chef&#39;s powerful abstractions such as definitions, providers, resources, and libraries. Worse, Chef doesn&#39;t have a definitive technical book to hold your hand through the entire process as James Turnbull&#39;s excellent &quot;&lt;a href=&quot;http://www.apress.com/9781430230571&quot;&gt;Pro Puppet&lt;/a&gt;&quot; does for Puppet.&lt;/div&gt;
&lt;div class=&quot;p2&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class=&quot;p1&quot;&gt;
After my initial bout of confusion I set to work on converting a 400-line RHEL 5 server provisioning shell script into a set of cookbooks. Amazingly, I was able to convert it to a set of Chef cookbooks in less than a week and a half. Even better, these cookbooks could be applied to an existing server at any time in its life, not just at installation time. Bonus, my bash script handled RHEL/CentOS 5-6 on x86_64 and i386 architectures whereas the original bash script only handled RHEL 5 x86_64. I must confess that part of my productivity gains stem from the fact that I am far more proficient in RHEL than I was when I originally wrote the Bash script. That said, I believe that using Chef for the server provisioning task took me 30-40% of the time it would have required to rewrite the Bash script to handle RHEL 6 and the i386 architecture.&lt;/div&gt;
&lt;div class=&quot;p2&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class=&quot;p1&quot;&gt;
I have made a lot of progress with Chef in this first month but I have yet to automate an entire application stack. Here are the tasks I hope to implement with Chef in the next few months:&lt;/div&gt;
&lt;ul class=&quot;ul1&quot;&gt;
&lt;li class=&quot;li1&quot;&gt;Consistently test my cookbooks with rspec or another testing tool&lt;/li&gt;
&lt;li class=&quot;li1&quot;&gt;Create a Jboss cookbook&lt;/li&gt;
&lt;li class=&quot;li1&quot;&gt;Cluster Tomcat instances&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;p3&quot;&gt;
&lt;div class=&quot;p1&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class=&quot;p2&quot;&gt;
&lt;b&gt;Best Practices thus Far&lt;/b&gt;&lt;/div&gt;
&lt;div class=&quot;p1&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class=&quot;p2&quot;&gt;
So here is a collection of the Chef &quot;best practices&quot; I have picked up in this first month. Given that it has only been a month, please take them with a grain of salt. Master Chefs, please don&#39;t hesitate to correct me if there is any incorrect information here.&lt;/div&gt;
&lt;div class=&quot;p1&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;ul class=&quot;ul1&quot;&gt;
&lt;li class=&quot;li2&quot;&gt;If you want to get started quickly, i.e. learn chef in a weekend, use hosted chef and micro instances on EC2. For me it was important to install the entire stack before using it because that is the kind of geek I am. It also sucked up a lot of time.&lt;/li&gt;
&lt;li class=&quot;li2&quot;&gt;Separate your ingredients (data) from your recipes. Don&#39;t hardcode your site-specific information like IP addresses or host names into the recipes. Put them in Data Bags, role attributes, or node attributes.&lt;/li&gt;
&lt;li class=&quot;li2&quot;&gt;Data Bags are for complex or global data like users or samba shares&lt;/li&gt;
&lt;li class=&quot;li2&quot;&gt;Role attributes and node attributes are best suited for simple values like host names for NTP servers, Nagios server, or whether to run X service as a independent daemon or under Xinted&lt;/li&gt;
&lt;li class=&quot;li2&quot;&gt;If you aren&#39;t already familiar with git, you should make learning the basics of git your #2 priority after completing the Chef Getting Started Guide. Since we&#39;re talking about &quot;Infrastructure as Code&quot; here, you have to become as serious about version control as a software developer is.&lt;/li&gt;
&lt;li class=&quot;li2&quot;&gt;After you clone the main chef repository, create the sub-folder site-cookbooks/ at the same level as cookbooks/ . Put your new cookbooks in site-cookbooks/ and make each one an individual git repository&lt;/li&gt;
&lt;li class=&quot;li2&quot;&gt;In .gitignore, add &quot;.chef&quot; and &quot;site-cookbooks&quot;. You store all authentication keys in your .chef/ so it is a directory that you really don&#39;t want to accidentally push to a public repository.&lt;/li&gt;
&lt;li class=&quot;li2&quot;&gt;Sign the &lt;a href=&quot;https://secure.echosign.com/public/hostedForm?formid=PJIF5694K6L&quot;&gt;CLA&lt;/a&gt; for Chef. You can&#39;t contribute fixes without doing so.&amp;nbsp;&lt;/li&gt;
&lt;li class=&quot;li2&quot;&gt;Don&#39;t use &lt;i&gt;$ knife role edit &amp;lt;role-name&amp;gt;;&lt;/i&gt; use the Ruby DSL instead. That way you have your roles under version control.&lt;/li&gt;
&lt;li class=&quot;li2&quot;&gt;Check, double-check, then ask on IRC before starting a cookbook from scratch. I wrote four different cookbooks before realizing that they duplicated functionality already present in the main &lt;a href=&quot;https://github.com/opscode/cookbooks&quot;&gt;opscode/cookbooks&lt;/a&gt;&lt;/li&gt;
&lt;li class=&quot;li2&quot;&gt;Use &lt;a href=&quot;http://wiki.opscode.com/display/chef/Shef&quot;&gt;shef&lt;/a&gt;, it is a wonderful tool to debug and explore how Chef works. Note that it does not load roles attributes at this time.&lt;/li&gt;
&lt;li class=&quot;li2&quot;&gt;Fat cookbooks, skinny recipes. You should put the recipes for both the client and server parts of an application in the same cookbook. This makes them easier to keep track of and forces you to make the recipes more modular.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;p2&quot;&gt;
Here are some Ruby tips that I have picked up&lt;/div&gt;
&lt;div class=&quot;p1&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class=&quot;p2&quot;&gt;
Put&amp;nbsp; &lt;i&gt;require &#39;irb/completion&#39;&lt;/i&gt; in your&amp;nbsp; ~/.irbrc, then you have auto completion in irb and in shef as it uses irb&lt;/div&gt;
&lt;div class=&quot;p1&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class=&quot;p2&quot;&gt;
For learning ruby, I actually prefer &lt;a href=&quot;http://rubygems.org/gems/pry&quot;&gt;&lt;span class=&quot;s1&quot;&gt;pry&lt;/span&gt;&lt;/a&gt; over irb, which reminds me of my beloved IPython. &amp;nbsp;I haven&#39;t yet figured out yet how to get shef to invoke pry rather than irb.&lt;/div&gt;
&lt;div class=&quot;p1&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class=&quot;p2&quot;&gt;
To install pry&lt;/div&gt;
&lt;div class=&quot;p1&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class=&quot;p2&quot;&gt;
&amp;nbsp; &lt;i&gt;$ gem install pry pry-doc&lt;/i&gt;&lt;/div&gt;
&lt;div class=&quot;p2&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class=&quot;p1&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class=&quot;p2&quot;&gt;
You also have to put &lt;i&gt;require &#39;irb/completion&#39;&lt;/i&gt; in your ~/.pryrc or type it in at the prompt. Here is an example of how tab completion works&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;p3&quot;&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjBVUuhYTDnLA1tokDJVzozDGTHPmjeAh3g4mUNXEaYnFx-7cQhr48ywmR6sdgY_x7Mo-6UaDtXyoUQJ7PFmP12MtznVS_jpc3WS8RGPdBZg4KUDN8gaJeGM658U8O1XdKTmy4XK0AifjjH/s1600/pry-term3.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;187&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjBVUuhYTDnLA1tokDJVzozDGTHPmjeAh3g4mUNXEaYnFx-7cQhr48ywmR6sdgY_x7Mo-6UaDtXyoUQJ7PFmP12MtznVS_jpc3WS8RGPdBZg4KUDN8gaJeGM658U8O1XdKTmy4XK0AifjjH/s320/pry-term3.png&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class=&quot;p3&quot;&gt;
The next step is to actually check the docs for what particular method does. The command for that is&lt;br /&gt;
&amp;nbsp; &amp;nbsp;pry&amp;gt;&lt;i&gt;&amp;nbsp;show-doc Object.method&lt;/i&gt;&lt;/div&gt;
&lt;div class=&quot;p4&quot;&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhzh3d6Pxl13ZOloG0yudI-H58lFkrB9dXIEofKszKm2i_ID-axSCNKM9I6UhS6iPMDUAdbujCbeJljVMD6uvcWt6g9T9Fk7p70MOWVQD4jPdivM5DarCEHU03dlOQohlDfayKajNZ4Exzh/s1600/term-pry1.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;226&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhzh3d6Pxl13ZOloG0yudI-H58lFkrB9dXIEofKszKm2i_ID-axSCNKM9I6UhS6iPMDUAdbujCbeJljVMD6uvcWt6g9T9Fk7p70MOWVQD4jPdivM5DarCEHU03dlOQohlDfayKajNZ4Exzh/s320/term-pry1.png&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
You can also read ri docs by simply typing &lt;i&gt;pry&amp;gt; ri Class#method&lt;/i&gt; like you would at the normal shell prompt.&lt;/div&gt;
&lt;div class=&quot;p2&quot;&gt;
&lt;div class=&quot;p1&quot;&gt;
&lt;br /&gt;
There are a couple tools that I intend to use in the near future, specifically &lt;a href=&quot;https://github.com/applicationsonline/librarian&quot;&gt;libarian-chef&lt;/a&gt; by Jay Feldblum, but haven&#39;t yet gotten the opportunity.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;p1&quot;&gt;
&lt;b&gt;More Pirate, Less Ninja&lt;/b&gt;&lt;/div&gt;
&lt;div class=&quot;p2&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class=&quot;p1&quot;&gt;
Chef has made a big impact on my work style. You definitely start working more like a developer, spending more time on your workstation and less SSH&#39;d into a random machine. It is hard to justify heavily customizing your own dotfiles when you spend most of your time on random machines where the only text editor you can count on being present is vi.&amp;nbsp;&lt;a href=&quot;http://philosecurity.org/2009/03/23/pirates-and-ninjas-emacs-or-vi&quot;&gt;&lt;span class=&quot;s1&quot;&gt;This article&lt;/span&gt;&lt;/a&gt;&amp;nbsp;describes vi users as ninjas and emacs users as pirates but I think many of the same comparisons apply to sysadmins and developers. Ninjas can&#39;t carry much around with them on their dark forays just like sysadmins can&#39;t lug around a bloated .vimrc or .emacs file. Pirates, on the other hand, stay on their ships where they have plenty of room for whiskey, stolen treasure, ( .emacs.d/ || .vim.d/ ), .screenrc, .zshrc, etc.&lt;/div&gt;
&lt;div class=&quot;p2&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class=&quot;p1&quot;&gt;
With Chef, I spend a lot more time working on cookbooks, roles, and data bags in &lt;i&gt;localhost:~/chef-repo/&lt;/i&gt;. Knife makes it very easy to manipulate your chef-server and chef-clients with fewer ssh console sessions. I think this work style may explain why there are many more emacs users in the chef-community than in your typical group of sysadmins. Historically, system administration has forced you to be a vi user but as a &quot;chef&quot; you can spend more time in emacs, sam, joe, or even *gasp* nano. I personally have heavily customized my .vimrc over the last month and even dabbled in zsh. I am not suggesting that Chef will turn you into an emacs user, but it will turn you into a pirate.&lt;/div&gt;
&lt;div class=&quot;p2&quot;&gt;
&lt;/div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class=&quot;p2&quot;&gt;
&lt;b&gt;Selling it to the Team&lt;/b&gt;&lt;/div&gt;
&lt;div class=&quot;p1&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class=&quot;p2&quot;&gt;
Managers love chef. They get the idea in the first five minutes and ask you weren&#39;t using Chef five years ago. They love it because 1) big, respected companies are using it 2) it makes system configuration far more transparent, i.e. you can see how systems are actually configured and not how you hope they are 3) it will help them deal with the never-ending requests for new Virtual Machines coming from the developers. It can be harder to sell it to those sysadmins who may know *nix like the back of their hands but are used to doing &amp;nbsp;everything by hand and have never gotten into the habit of automating tasks with their own shell scripts. It can also be hard to sell to those sysadmins who have already invested heavily in their own custom bash/Perl/Python/Tcl infrastructure framework.&lt;/div&gt;
&lt;div class=&quot;p1&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class=&quot;p2&quot;&gt;
Here is my pitch for Chef in a nutshell.&lt;/div&gt;
&lt;div class=&quot;p1&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class=&quot;p2&quot;&gt;
&lt;blockquote class=&quot;tr_bq&quot;&gt;
&lt;i&gt;A few years ago we had a ratio of &lt;/i&gt;&lt;b&gt;&lt;i&gt;n&lt;/i&gt;&lt;/b&gt;&lt;i&gt; machines per sysadmin. Now we have 3&lt;/i&gt;&lt;b&gt;&lt;i&gt;n&lt;/i&gt;&lt;/b&gt;&lt;i&gt; machines per admin. Next year we will likely have between 6-9&lt;/i&gt;&lt;b&gt;&lt;i&gt;n&lt;/i&gt;&lt;/b&gt;&lt;i&gt; machines per sysadmin. We are struggling mightily to support 3&lt;/i&gt;&lt;b&gt;&lt;i&gt;n&lt;/i&gt;&lt;/b&gt;&lt;i&gt; now and our current coping mechanisms will break down entirely when we move to 6&lt;/i&gt;&lt;b&gt;&lt;i&gt;n&lt;/i&gt;&lt;/b&gt;&lt;i&gt;. The only way we can cope is by moving from home-brewed infrastructure to a real configuration management system, such as Chef.&lt;/i&gt;&amp;nbsp;&amp;nbsp;&lt;/blockquote&gt;
&lt;blockquote class=&quot;tr_bq&quot;&gt;
&lt;i&gt;If you aren&#39;t comfortable with writing your own automation scripts, you are at least comfortable using the scripts of others. I don&#39;t expect everybody here to be able write their own cookbooks from scratch but I believe everyone here can learn how to reuse and modify existing cookbooks to meet our needs.&lt;/i&gt;&lt;/blockquote&gt;
&lt;/div&gt;
&lt;div class=&quot;p1&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class=&quot;p2&quot;&gt;
Frankly, I don&#39;t yet have a way to sell Chef to the &lt;a href=&quot;http://en.wikipedia.org/wiki/Not_Invented_Here&quot;&gt;&lt;span class=&quot;s1&quot;&gt;NotInventedHere&lt;/span&gt;&lt;/a&gt; crowd. Whatever benefits you bring up, Chef still wasn&#39;t their idea. One option would be to convince them that Chef just does what they have been doing all along and using Chef will free them from maintenance work for their current tools. Then they can focus on what really needs reinventing. Unfortunately, implementing Chef may require a substantial amount of their help and not leave them so much time to start that new pet project.&lt;/div&gt;
&lt;div class=&quot;p1&quot;&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;p1&quot;&gt;
&lt;b&gt;Thoughts on the Community&lt;/b&gt;&lt;/div&gt;
&lt;div class=&quot;p2&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class=&quot;p1&quot;&gt;
I feared that the Chef community would be populated with developers who were &quot;slumming&quot; as sysadmins. I found quite the opposite. The vast majority of the community are Unix-lovin&#39;, bash-spittin&#39; geeks who make their careers as sysadmins and not as a side project. In terms of geography, the community is overwhelmingly concentrated in North America. It can be tough to get a response on IRC during the morning in Europe while you will get tens of responses during the US West Coast&#39;s working hours. For all hours outside of the European morning, you can find a large numbers of core developers on IRC and they are extremely helpful.&lt;/div&gt;
&lt;div class=&quot;p2&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class=&quot;p1&quot;&gt;
The vast majority of chef users seem to work on Ubuntu, with Enterprise Linux a distant second. Surprisingly, there is a relatively large presence of OpenSolaris/Ilumos and I am not sure exactly why that is. Perhaps Solaris users are disproportionately drawn to automation tools?&lt;/div&gt;
&lt;div class=&quot;p2&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class=&quot;p1&quot;&gt;
When I can&#39;t get a quick answer on IRC, the two best channels are the 1) chef-users mailing list and 2) twitter. For some reason, the devops world has really, really gathered around twitter. I can get a quick answer at any hour by using the hashtag #opschef. However, this only works for questions that entirely fit into 110 characters. It is bad form to link to a mailing list post or extend the question across multiple tweets. For complicated questions, the mailing list is always the best place to go for help.&lt;/div&gt;
&lt;div class=&quot;p2&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class=&quot;p1&quot;&gt;
The community is extremely friendly and so far there are no trolls. However, this is typical of a young project. Early adopters by their nature tend to be more positive and self-sufficient. Most people on #chef are there because they discovered chef on their own and not because their boss mandated they use it.&amp;nbsp;&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class=&quot;p2&quot;&gt;
&lt;b&gt;My Short-Term Chef Wishlist&lt;/b&gt;&lt;br /&gt;
&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;br /&gt;
Here is my wishlist for the next 3-6 months&lt;/div&gt;
&lt;ul class=&quot;ul1&quot;&gt;
&lt;li class=&quot;li2&quot;&gt;Clear guidelines on how to collaborate on cookbooks and on how to push changes upstream to opscode/cookbooks (something which &lt;a href=&quot;http://twitter.com/#!/jtimberman&quot;&gt;jtimberman&lt;/a&gt; is already working on)&lt;/li&gt;
&lt;li class=&quot;li2&quot;&gt;Lower Memory Usage. Chef can really, really be a memory hog when you have several hundred nodes&lt;/li&gt;
&lt;li class=&quot;li2&quot;&gt;Better support for Enterprise Linux, both in core chef and the cookbooks&lt;/li&gt;
&lt;li class=&quot;li2&quot;&gt;A few weeks ago I would have said better documentation but they have already made huge strides in this regard&lt;/li&gt;
&lt;li class=&quot;li2&quot;&gt;A stronger connection to the FOSS community worldwide&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;p2&quot;&gt;
Chef will achieve world domination when the installation instructions for the average software application start not by pointing to a .rpm, .deb, or tarball but to a Chef cookbook. Key to achieving that are 1) making Chef awesome (of course) and 2) better engagement with the communities that manage software packaging in the public sphere--the FOSS geeks. These guys are the guerilla foot soldiers of software packaging. They write the man pages, manage a FOSS project&#39;s build servers, maintain wikis, etc. The phenomena of &quot;cloud computing&quot; couldn&#39;t exist today if it weren&#39;t for all their hard work at every layer of the GNU/Linux/*BSD stacks.&lt;/div&gt;
&lt;div class=&quot;p1&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class=&quot;p2&quot;&gt;
How can Chef win over the FOSS geeks? First, having a presence at conferences like &lt;a href=&quot;http://fosdem.org/&quot;&gt;&lt;span class=&quot;s1&quot;&gt;FOSDEM&lt;/span&gt;&lt;/a&gt;, &lt;a href=&quot;http://2011.osidays.com/&quot;&gt;&lt;span class=&quot;s1&quot;&gt;OSI&lt;/span&gt;&lt;/a&gt;, &lt;a href=&quot;http://fedoraproject.org/wiki/FUDCon&quot;&gt;&lt;span class=&quot;s1&quot;&gt;FUDCON&lt;/span&gt;&lt;/a&gt;, &lt;a href=&quot;http://en.wikipedia.org/wiki/FISL&quot;&gt;&lt;span class=&quot;s1&quot;&gt;FISL&lt;/span&gt;&lt;/a&gt;, etc. would be relatively inexpensive and give them a lot of bang for their buck.&amp;nbsp;Secondly, offering some version of free hosted chef for up to &lt;i&gt;n&lt;/i&gt; nodes for open-source projects and foundations like &lt;a href=&quot;http://www.softwarefreedom.org/&quot;&gt;&lt;span class=&quot;s1&quot;&gt;Software Freedom Law Center&lt;/span&gt;&lt;/a&gt;, &lt;a href=&quot;http://www.python.org/psf/&quot;&gt;&lt;span class=&quot;s1&quot;&gt;Python Software Foundation&lt;/span&gt;&lt;/a&gt;,&amp;nbsp;&lt;a href=&quot;http://sfconservancy.org/&quot;&gt;&lt;span class=&quot;s1&quot;&gt;Software Freedom Conservancy&lt;/span&gt;&lt;/a&gt;, etc.&lt;/div&gt;
&lt;div class=&quot;p1&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class=&quot;p2&quot;&gt;
&lt;b&gt;Wrapping up&lt;/b&gt;&lt;/div&gt;
&lt;div class=&quot;p1&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class=&quot;p2&quot;&gt;
So far, Chef has lived up to the hype. It has made me more productive in a relatively short amount of time. I can&#39;t imagine my future as a sysadmin without it. Configuration management--whether using chef, puppet, or other--will soon be an essential skill for a professional system administrator. Now how does Chef affect my work in the larger context of Devops? Where does it fit in my devops-toolchain? Well, those are subjects for another blog post entirely.&lt;br /&gt;
&lt;br /&gt;
&lt;a href=&quot;http://news.ycombinator.com/item?id=3174290&quot;&gt;Comments for this post&lt;/a&gt; are on Hacker News&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1083699665345453745/posts/default/2661785546577878625'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1083699665345453745/posts/default/2661785546577878625'/><link rel='alternate' type='text/html' href='http://devopsanywhere.blogspot.com/2011/10/month-with-chef.html' title='A Month with Chef'/><author><name>Anonymous</name><uri>http://www.blogger.com/profile/10631977500882582704</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjBVUuhYTDnLA1tokDJVzozDGTHPmjeAh3g4mUNXEaYnFx-7cQhr48ywmR6sdgY_x7Mo-6UaDtXyoUQJ7PFmP12MtznVS_jpc3WS8RGPdBZg4KUDN8gaJeGM658U8O1XdKTmy4XK0AifjjH/s72-c/pry-term3.png" height="72" width="72"/></entry><entry><id>tag:blogger.com,1999:blog-1083699665345453745.post-7581721509146540042</id><published>2011-10-16T02:22:00.000-07:00</published><updated>2012-12-29T12:44:32.102-08:00</updated><title type='text'>Why Chef?</title><content type='html'>&lt;div dir=&quot;ltr&quot; style=&quot;text-align: left;&quot; trbidi=&quot;on&quot;&gt;
&lt;div style=&quot;text-align: left;&quot; trbidi=&quot;on&quot;&gt;
Being a system administrator is alternately thrilling and tedious. The thrilling part is setting up an awesome, rock-solid system. The tedious part is doing that 10 or even 100 times more. Further, throughout your career you will configure certain applications again and again. You know the ones, sendmail, apache, samba, etc. Well, there have been many attempts to build a framework, an abstraction, for automating the process of configuring these well-worn tools and others. Today there is one such framework that finally gets it right, &lt;a href=&quot;http://wiki.opscode.com/display/chef/Home&quot;&gt;Chef&lt;/a&gt;. There are many, many reasons to use Chef but the&amp;nbsp;main reason you should use chef is this: &lt;b&gt;You&lt;/b&gt;, System Administrator, are too damn smart to spend the rest of your professional life reinventing the wheel.&lt;br /&gt;
&lt;br /&gt;
Let me tell you a little more about how wonderful Chef is, then I will show you briefly some technical highlights, and finally I will clear up some Chef myths.&lt;br /&gt;
&lt;br /&gt;
&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-size: large;&quot;&gt;The Top 5 Reasons to use Chef&lt;/span&gt;&lt;br /&gt;
&lt;ol style=&quot;text-align: left;&quot;&gt;
&lt;li&gt;Writing reams of documentation sucks. Chef drastically reduces the amount of documentation you have to write.&lt;/li&gt;
&lt;li&gt;Bash doesn&#39;t scale. Seriously.&lt;/li&gt;
&lt;li&gt;Technical Awesomeness&lt;/li&gt;
&lt;li&gt;Chef grows with you&lt;/li&gt;
&lt;li&gt;You can stop reinventing the wheel&lt;/li&gt;
&lt;/ol&gt;
&lt;div&gt;
Now let&#39;s talk about that awesomeness in more detail.&lt;br /&gt;
&lt;br /&gt;
&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-size: large;&quot;&gt;Write Less Documentation&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
Less docs? You&#39;re kidding me right? Actually, I&#39;m not. If you&#39;re like me, you&#39;r sick of annotating the your entire bash history. If you&#39;re not like me, you don&#39;t even bother. With Chef, your infrastructure literally is code rather than a collection of unique artifacts. Top-level readmes and a few well-placed code comments should be sufficient. Take a look at this recipe for a basic sendmail configuration.&lt;/div&gt;
&lt;br /&gt;
basic sendmail configuration with chef&lt;br /&gt;
&lt;script src=&quot;https://gist.github.com/1290564.js&quot;&gt;
 
&lt;/script&gt;
&lt;div class=&quot;gistLoad&quot; data-id=&quot;1290564&quot; id=&quot;gist-1290564&quot;&gt;Loading ....&lt;/div&gt;

&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Bash Doesn&#39;t Scale
&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
Bash is a wonderful thing, but like all UNIX tools, it is fundamentally limited by design. Bash doesn&#39;t have a code reuse mechanism more powerful than functions. It uses a single global namespace. These and other limitations have made it hard for us sysadmins to reuse and generalize our shell scripts across different distributions, let alone different versions of *nix. Lastly, it is quite difficult to write shell scripts that are idempotent, that is, they have the same effect whether run once or 100 times. This is particularly true when manipulating configuration files. Let&#39;s take a look at how you would configure /etc/sudoers with chef.&lt;br /&gt;
&lt;br /&gt;
&lt;script src=&quot;https://gist.github.com/1290581.js&quot;&gt;
 
&lt;/script&gt;
&lt;div class=&quot;gistLoad&quot; data-id=&quot;1290581&quot; id=&quot;gist-1290581&quot;&gt;Loading ....&lt;/div&gt;

&lt;br /&gt;
All the variables in this template are passed in from &lt;a href=&quot;https://github.com/opscode/cookbooks/blob/master/sudo/recipes/default.rb&quot;&gt;this recipe&lt;/a&gt;.&lt;b&gt;&amp;nbsp;&lt;/b&gt;If you think you can replicate this template using sed, please submit it as a comment so we can compare results.&lt;br /&gt;
&lt;br /&gt;
Last but not least, Bash can be just as unreadable and obfuscated as the darkest perl code. With Chef you have a high level, intuitive&amp;nbsp;&lt;a href=&quot;http://en.wikipedia.org/wiki/Domain-specific_language&quot;&gt;DSL&lt;/a&gt; for describing your configuration. Remember what I said about needing less documentation?&lt;br /&gt;
&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-size: large;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-size: large;&quot;&gt;Technical Awesomeness&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;NOSQL FTW&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
One of the virtues that many *nix tools share is that they store their configurations in text files rather than binary formats or in a database. Chef stores your system configurations in text and in a database. It accomplishes this by using the document-oriented database, &lt;a href=&quot;http://couchdb.apache.org/&quot;&gt;CouchDB&lt;/a&gt;.&amp;nbsp;This makes the configuration &amp;nbsp;searchable and higher performance. One of my annoyances with nagios is that I have to restart it every time I change any service or host. &amp;nbsp;There are no annoying restarts with Chef. Each Configuration change you make takes effect instantly. Further you can use your favorite text editor and the command line to make configuration changes. Finally, using a database means that Chef is easily accessed through a GUI. We sysadmins often look down on GUIs as crutches for the Windows crowd. The Chef web UI is excellent for visualizing your own infrastructure, something that is hard to do while staring at plain text.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Knowing is Half the Battle&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
Chef uses &lt;a href=&quot;http://wiki.opscode.com/display/chef/Ohai&quot;&gt;Ohai&lt;/a&gt; to collect data about your system. Your recipes can access these attributes and make decisions based on them. For example, you can determine which version of Red Hat you are using simply by looking up the value of &lt;i&gt;node[&#39;platform_version&#39;]&lt;/i&gt;. You don&#39;t have to &lt;i&gt;cat | grep | awk&lt;/i&gt; to find out which release you are on.&lt;br /&gt;
&lt;br /&gt;
Ohai makes cookbooks more dynamic and able to support different distributions. As we will see later, this is one of the reasons there are so many high-quality cookbooks available.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Search
&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
Search is a feature in Chef Server that allows you to query the configuration information of all other servers and of &lt;a href=&quot;http://wiki.opscode.com/display/chef/Data+Bags&quot;&gt;globally-defined databags&lt;/a&gt;. This allows you to do things like configure clusters where a&amp;nbsp;member of cluster needs to know not only about its own configuration but about the configurations of the other members of the cluster.&lt;br /&gt;
&lt;br /&gt;
Example of using search with data bags. For the full recipe go &lt;a href=&quot;https://github.com/opscode/cookbooks/blob/master/users/recipes/sysadmins.rb&quot;&gt;here&lt;/a&gt;.&lt;br /&gt;
&lt;script src=&quot;https://gist.github.com/1290657.js&quot;&gt;
 
&lt;/script&gt;
&lt;div class=&quot;gistLoad&quot; data-id=&quot;1290657&quot; id=&quot;gist-1290657&quot;&gt;Loading ....&lt;/div&gt;

&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Knife
&lt;/b&gt;&lt;br /&gt;
&lt;a href=&quot;http://wiki.opscode.com/display/chef/Knife&quot;&gt;Knife&lt;/a&gt; is one of the truly great command line tools. It is your primary mechanism for interacting with the chef-server. Knife shares many usage patterns with git. If you love git, you&#39;ll love knife.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;shef&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;a href=&quot;http://wiki.opscode.com/display/chef/Shef&quot;&gt;shef&lt;/a&gt; works the way you work, in an iterative manner. Most of us system administrators are self-taught and we learn best by doing. Fire up shef and you can on the fly play with attributes and create recipes. Further, you can connect to your server and download the cookbooks.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-size: large;&quot;&gt;Chef Grows with You&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
Chef uses pure &lt;a href=&quot;http://ruby-lang.org/&quot;&gt;Ruby&lt;/a&gt; as its configuration language, not a shackled subset of ruby, nor yet another custom configuration language.&amp;nbsp;You only have to learn a &lt;a href=&quot;http://wiki.opscode.com/display/chef/Just+Enough+Ruby+for+Chef&quot;&gt;small amount of ruby&lt;/a&gt; to get started with chef. Once you get beyond the basics of Chef, you can go farther with Ruby. Many of you are grumbling now because ruby sucks to compared to Perl/Python/TCL/&amp;lt;insert-interpeted-language-here&amp;gt;. Well, Ruby may pale in comparison to Python but it is still a powerful, full-featured language.&lt;br /&gt;
&lt;br /&gt;
Just like Perl, there is a lot of dark magic inside Ruby. It can&#39;t be used carelessly or it will bite you in the ass. Unlike Python, Ruby does not make it difficult to do the wrong thing.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-size: large;&quot;&gt;You can stop reinventing the wheel&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
Until Chef, we sysadmins did not have a truly modular way to abstract and share our system configurations. Please stop reading and&amp;nbsp;browse&amp;nbsp;&lt;a href=&quot;http://community.opscode.com/cookbooks&quot;&gt;http://community.opscode.com/cookbooks&lt;/a&gt;. Later on, you should look at the code in &amp;nbsp;&lt;a href=&quot;https://github.com/opscode/cookbooks&quot;&gt;https://github.com/opscode/cookbooks&lt;/a&gt;. You will discover that some turncoat sysadmins are giving away our trade secrets. Now is the time for you to do the same. In fact, you can rip out a large chunk of your shell scripts and replace them with Chef cookbooks. You will find that many existing recipes meet your requirements and you can easily add new recipes to existing cookbooks for your unmet requirements.&lt;br /&gt;
&lt;br /&gt;
Recently, I replaced a 500 line shell script with 7 cookbooks, 5 reused from community.opscode.com and 2 new ones written from scratch. In the process of replacing the shell script I actually wrote 4 cookbooks that unwittingly duplicated the functionality of existing cookbooks.&lt;br /&gt;
&lt;br /&gt;
The emergence of the cloud-computing, whether on the public cloud such as EC2 or internally with &lt;a href=&quot;http://www.openstack.org/&quot;&gt;openstack&lt;/a&gt;, means that we systems administrators will have to manage at least 10 times more systems. We have to become 10 times more productive. We have to shift from &quot;managing servers&quot; to &quot;managing configurations.&quot; Chef is one of key tools to accomplishing this.&lt;br /&gt;
&lt;br /&gt;
&lt;b style=&quot;font-weight: bold;&quot;&gt;One Big Fat Chef Caveat&lt;/b&gt;&lt;br /&gt;
&lt;b style=&quot;font-weight: bold;&quot;&gt;&lt;br /&gt;&lt;/b&gt;&lt;br /&gt;
Chef makes good sysadmins more productive. It does not turn junior sysadmins into experts. In fact, it makes them more dangerous. As I overheard on IRC one day, &quot;Chef is to sysadmins what C++ is to software engineering.&quot; This is very true.&amp;nbsp;You can automate system configurations with off-the-shelf cookbooks but you have to understand exactly what they do and test them very rigorously.&lt;br /&gt;
&lt;b&gt;&lt;br /&gt;
&lt;b&gt;Chef Myths&lt;/b&gt;&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
There are a few myths about Chef floating around the intertubes that need to be exploded. The biggest one is that you have to be a professional programmer to use Chef. This is untrue for a couple of reasons, including the assumption that system administrators don&#39;t program already. Writing complex shell scripts is programming. Creating Apache rewrite rules is quite close to programming.&amp;nbsp;Further, Chef doesn&#39;t require you to be a Rubyist to get started, just as you don&#39;t have to be a Bash Hacker to use the command line. Take a look at &lt;a href=&quot;http://devopsanywhere.blogspot.com/2011/10/stupid-simple-chef-tutorial-for-dirty.html&quot;&gt;this tutorial&lt;/a&gt; and you will see what I mean.&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;text-align: left;&quot; trbidi=&quot;on&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: left;&quot; trbidi=&quot;on&quot;&gt;
I hear murmurs now and then that Chef is &quot;insecure&quot; because the recipes are executed on the chef-client &amp;nbsp;rather than on the chef-server. I argue that chef is more secure because of this. If recipes were executed on the chef-server, there would be a risk that a single malignant recipe modified other recipes to turn your entire network into a botnet. This would turn your chef-server into a single point of failure and make it a powerful attack vector.&lt;/div&gt;
&lt;div style=&quot;text-align: left;&quot; trbidi=&quot;on&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: left;&quot; trbidi=&quot;on&quot;&gt;
Finally, some will argue that Chef sucks because every server you configure should be hand-crafted and beautifully unique in its own way. If you believe that, perhaps you should go into the virtual performance art and get out of the business of making the Internet awesome.&lt;/div&gt;
&lt;div style=&quot;text-align: left;&quot; trbidi=&quot;on&quot;&gt;
&lt;br /&gt;
&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-size: large;&quot;&gt;Wrapping Up&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
Chef is a truly powerful tool that every serious system administrator should consider using. It offers immense personal and professional benefits.&lt;br /&gt;
&lt;br /&gt;
Please post comments on &lt;a href=&quot;http://news.ycombinator.com/item?id=3117284&quot;&gt;Hacker News&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;i&gt;Marcus van Dam (m4rcu5) helped edit this post&lt;/i&gt;&lt;br /&gt;
&lt;i&gt;&lt;br /&gt;&lt;/i&gt;&lt;br /&gt;
&lt;i&gt;Note: The title of this post is a reference to Eric S. Raymond&#39;s great post &quot;&lt;a href=&quot;http://www.linuxjournal.com/article/3882&quot;&gt;Why Python?&lt;/a&gt;&quot; which inspired me to learn Python, a long, long time ago.&lt;/i&gt;&lt;/div&gt;
&lt;b&gt;
&lt;/b&gt;&lt;/div&gt;
&lt;script src=&quot;https://raw.github.com/moski/gist-Blogger/master/public/gistLoader.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1083699665345453745/posts/default/7581721509146540042'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1083699665345453745/posts/default/7581721509146540042'/><link rel='alternate' type='text/html' href='http://devopsanywhere.blogspot.com/2011/10/why-chef.html' title='Why Chef?'/><author><name>Anonymous</name><uri>http://www.blogger.com/profile/10631977500882582704</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-1083699665345453745.post-9112587608076747911</id><published>2011-10-09T07:46:00.000-07:00</published><updated>2013-06-09T21:59:51.670-07:00</updated><title type='text'>Puppet vs. Chef, Fight!</title><content type='html'>&lt;div dir=&quot;ltr&quot; style=&quot;text-align: left;&quot; trbidi=&quot;on&quot;&gt;
&lt;div dir=&quot;ltr&quot; style=&quot;text-align: left;&quot; trbidi=&quot;on&quot;&gt;
&lt;br /&gt;
&lt;i&gt;Update: see &lt;a href=&quot;http://blog.loof.fr/2011/10/puppet-vs-chef-fight.html&quot;&gt;Puppet vs. Chef&lt;/a&gt; en francais, not a translation but an original article inspired by this one&lt;/i&gt;&lt;br /&gt;
&lt;br /&gt;
If you aren&#39;t yet using Puppet or Chef for managing your *nix infrastructure, you should seriously consider it. The benefits are enormous. Frankly, I don&#39;t think you __can__ manage a modern infrastructure without using Puppet, Chef, or reinventing a configuration management framework with your own custom scripts. However, you can&#39;t use both Chef and Puppet together, so which should you choose?&lt;br /&gt;
&lt;br /&gt;
If you&#39;re like me, you obsess over tool choices. You agonize for weeks over these decisions. Why? Because you will end up putting a huge personal investment in the chosen tool.&amp;nbsp;There isn&#39;t all that much on the relative benefits of Puppet vs. Chef besides this &lt;a href=&quot;http://www.quora.com/What-are-the-key-reasons-to-choose-Puppet-over-Chef-or-vice-versa&quot;&gt;quora thread&lt;/a&gt;. Below you will find my completely subjective, non-comprehensive study of the matter. TL;DR, Chef wins but by only a narrow margin.&lt;br /&gt;
&lt;br /&gt;
&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-size: large;&quot;&gt;The Criteria&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;ol style=&quot;text-align: left;&quot;&gt;
&lt;li&gt;Community Strength&lt;/li&gt;
&lt;li&gt;Leadership&lt;/li&gt;
&lt;li&gt;Corporate Adoption&lt;/li&gt;
&lt;li&gt;Technical Merits&lt;/li&gt;
&lt;li&gt;Hands-on Experience&lt;/li&gt;
&lt;/ol&gt;
&lt;br /&gt;
&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-size: large;&quot;&gt;Community Strength&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Community Size&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
Number of people on IRC on Sunday Oct 9th, 2011 10 AM GMT&lt;br /&gt;
#puppet &amp;nbsp; 541 users&lt;br /&gt;
#chef &amp;nbsp; &amp;nbsp; &amp;nbsp; 233 users&lt;br /&gt;
&lt;br /&gt;
Mailing Lists&lt;br /&gt;
puppet-users &amp;nbsp;3363 members, 5961 topics&lt;br /&gt;
chef: 600 members, # of topics unknown&lt;br /&gt;
&lt;br /&gt;
Regarding IRC, Chef seems much more U.S.-centric. It can be hard to get answers during the European workday. The situation is probably better for Asian users as they can catch the North American community when it is early evening on the West Coast of the United States. That is not true for Puppet, where you can get an answer at any time of day or night. R.I. Pienaar is based in London and seems to be on IRC at all hours. Somehow he manages to kick out awesome code and be continuously available.&amp;nbsp;Further, James Turnbull doesn&#39;t seem to sleep either and is incredibly helpful.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Quality of Cookbook Sites&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;a href=&quot;http://community.opscode.com/cookbooks&quot;&gt;http://community.opscode.com/cookbooks&lt;/a&gt;&lt;br /&gt;
&lt;a href=&quot;http://forge.puppetlabs.com/&quot;&gt;http://forge.puppetlabs.com/&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
Github Repositories:&lt;br /&gt;
puppet:&amp;nbsp;&amp;nbsp;&lt;a href=&quot;https://github.com/search?q=puppet&quot;&gt;1622 repositories&lt;/a&gt;&lt;br /&gt;
chef: &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;a href=&quot;https://github.com/search?q=chef&quot;&gt;1299 repositories&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
While Chef is much younger project than Puppet, it is really impressive how many cookbooks there are and their respective quality, especially when Chef is less than half the age of Puppet. From what I can tell, most people bypass the community sites and go straight to github to find their Chef cookbooks or puppet modules.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Documentation, Official and Informal&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
Both Puppet and Chef have excellent reference documentation. In my opinion, the Puppet docs help you get up and running much faster. &lt;a href=&quot;http://www.amazon.com/Pro-Puppet-James-Turnbull/dp/1430230576/ref=pd_sim_b1&quot;&gt;Pro Puppet&lt;/a&gt;, by Puppet Labs engineer James Turnbull, is an awesome introduction to Puppet. I found it immensely helpful. There is a 50-page O&#39;Reilly publication on Chef, &lt;a href=&quot;http://www.amazon.com/Test-Driven-Infrastructure-Chef-Stephen-Nelson-Smith/dp/1449304818/ref=sr_1_1?ie=UTF8&amp;amp;qid=1318151239&amp;amp;sr=8-1&quot;&gt;Test-Driven Infrastructure with Chef&lt;/a&gt;, but it cannot match the breadth of Pro Puppet.&amp;nbsp;&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: inherit;&quot;&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;background-color: white; color: #222222;&quot;&gt;&amp;nbsp;I have heard that O&#39;Reilly are going&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;background-color: white; color: #222222;&quot;&gt;to be publishing a feature-length definitive guide, scheduled to be&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;background-color: white; color: #222222;&quot;&gt;out by the Summer of 2012.&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
The Chef community definitely tends more towards programmers and rubyists than systems administrators. I think that puppet meets the needs of the majority of its users so well that they never try Chef.&lt;br /&gt;
&lt;br /&gt;
&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-size: large;&quot;&gt;Leadership&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
We all know that leaders can make or break open-source projects. The BDFL&#39;s personality shapes the project more than the actual code. What would linux be without Linus Torvalds&#39; stewardship?&amp;nbsp;I am wary to bet against Puppet founder Luke Kanies. He is both a genius and a visionary. He reminds me a little of &lt;a href=&quot;http://en.wikipedia.org/wiki/Steve_Jobs&quot;&gt;another Reed College alumnus&lt;/a&gt;. I highly recommend listening to&amp;nbsp;&lt;a href=&quot;http://devopscafe.org/show/2010/12/20/episode-17.html&quot;&gt;Luke Kanies interview&lt;/a&gt;&amp;nbsp;on DevOps Cafe. He shows himself to be very intelligent and very opinionated. My understanding is that his original motivation for creating Puppet was to make life better for the average sysadmin.&lt;br /&gt;
&lt;br /&gt;
The resumes of the Opscode team are just amazing. CTO Chris Brown and co-founder Jesse Robbins were core infrastructure engineers at Amazon, the company that perhaps more than any other understands how to manage infrastructure at scale. Listen to co-founder&amp;nbsp;&lt;a href=&quot;http://devopscafe.org/show/2011/9/20/devops-cafe-episode-19.html&quot;&gt;Jesse Robbin&#39;s Interview&lt;/a&gt;&amp;nbsp;and you will find him to be very pragmatic about infrastructure and less opinionated than Luke. His motivation was to create an open-source tool that solved the kinds of infrastructure problems he dealt with while working at Amazon.com.&lt;br /&gt;
&lt;br /&gt;
On the funding side, both companies have closed substantial Series B funding rounds. We&#39;re talking more that 10 million dollars each. Both of these companies can throw a number of talented software engineers at the devops problem domain for a while to come.&lt;br /&gt;
&lt;br /&gt;
&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-size: large;&quot;&gt;Corporate Adoption&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
I believe that both Puppet and Opscode corporations will become extremely successful.&amp;nbsp;Jesse Robbins explains this best in &lt;a href=&quot;http://www.virtual-strategy.com/2011/09/30/qa-jesse-robbins-opscode&quot;&gt;Virtual Strategy Magazine&lt;/a&gt;.&lt;br /&gt;
&lt;blockquote&gt;
&lt;span class=&quot;Apple-style-span&quot; style=&quot;background-color: white; font-family: &#39;Lucida Grande&#39;, Tahoma, Helvetica, sans-serif; font-size: 13px; line-height: 19px;&quot;&gt;&amp;nbsp;Our primary competitor is the in-house, home-grown tooling that every systems engineer has had to cobble together to deal with their legacy environments. That’s our principal competitor.&amp;nbsp;&lt;/span&gt;&lt;/blockquote&gt;
That&#39;s right. The biggest competitor to Chef and Puppet isn&#39;t each other but that hairball nest of Bash and Perl that holds your data center together.&lt;br /&gt;
&lt;br /&gt;
Still, Puppet has an amazing customer list but Chef is also racking up wins.&amp;nbsp;If &lt;a href=&quot;http://puppetlabs.com/puppet/puppet-enterprise/&quot;&gt;Puppet Enterprise 2.0&lt;/a&gt; delivers half of what its press release promises, it will be a huge success. Puppet Enterprise&#39;s integration with &lt;a href=&quot;http://puppetlabs.com/mcollective/introduction/&quot;&gt;mcollective&lt;/a&gt; is particularly exciting.&lt;br /&gt;
&lt;br /&gt;
I am particularly impressed that a number of companies have built their own internal provisioning tools on top of Chef, notably Rackspace Cloud Builders and Dell&#39;s Openstack team.&lt;br /&gt;
&lt;br /&gt;
&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-size: large;&quot;&gt;Technical Merits&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
Puppet is designed to be approachable by systems administrators. It is not necessarily written to empower rubyists.&amp;nbsp;Writing Puppet manifests, at least initially, feels much like writing nagios or apache configurations. However, it starts feeling much like programming once you get beyond simple resource specification.&lt;br /&gt;
&lt;br /&gt;
Chef is designed to help engineers manage the configuration of their infrastructure at scale. It does not have the same focus on easy-of-use, nor is it as opinionated as Puppet. Now let&#39;s look at a few salient features.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Syntax&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
Here are examples of how to create a user in first Puppet and then chef
&lt;br /&gt;
&lt;pre&gt;from http://docs.puppetlabs.com/learning/ral.html
user { &#39;dave&#39;:
      ensure     =&amp;gt; present,
      uid        =&amp;gt; &#39;507&#39;,
      gid        =&amp;gt; &#39;admin&#39;,
      shell      =&amp;gt; &#39;/bin/zsh&#39;,
      home       =&amp;gt; &#39;/home/dave&#39;,
      managehome =&amp;gt; true,
}
&lt;/pre&gt;
&lt;br /&gt;
Now in Chef
&lt;br /&gt;
&lt;pre&gt;user &quot;root&quot; do
    username &quot;root&quot;
    password &quot;$1$PdV3HPti$WXmqrQEVj88fVTHevErxq.&quot;
    shell &quot;/bin/bash&quot;
    system true
    supports :manage_home =&amp;gt; true 
end
&lt;/pre&gt;
&lt;br /&gt;
They don&#39;t look terribly different, but now let&#39;s throw some Ruby into the mix. In the following example, I iterate through a list of users stored in a data bag
&lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;data_bag(&#39;users&#39;).each do |user_name|
   u = data_bag_item(&#39;users&#39;, user_name)
   user user_name do	
        username user_name
        password u[&#39;password&#39;]
        shell u[&#39;shell&#39;]
        supports :manage_home =&amp;gt; u[&#39;manage_home&#39;] 
   end
end
&lt;/pre&gt;
&lt;br /&gt;
Now you should have a better sense of the difference between Puppet and Chef.&amp;nbsp;Some may have a valid criticism that Chef lets you do too much by allowing you use regular Ruby. I have to admit that undisciplined use of Ruby is as dangerous if not more dangerous as perl or bash abuse. At the same time, it is quite empowering. The Chef community really needs some kind of chef-lint tool to tell you when you&#39;re doing something you shouldn&#39;t.&lt;big&gt;&lt;b&gt;Update:&lt;/b&gt;&lt;/big&gt; &lt;a href=&quot;https://github.com/acrmp/foodcritic&quot;&gt;Foodcritic&lt;/a&gt; now excellently fills that need.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Debugging&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
I miss noop mode in puppet, though this is on the way for Chef. It is a wonderful way to see how your puppet configuration differs from what is actually on disk without actually changing anything. I have heard some refer to noop mode as &quot;Lie to me mode&quot; though I have yet to have it bite me in the ass. I might feel very differently if I had experienced that personally. I also liked how puppet spit out the text of rendered templates to the console. Maybe you can do this with Chef as well, but I haven&#39;t figured out how to yet.&lt;big&gt;&lt;b&gt;Update:&lt;/b&gt;&lt;/big&gt;Chef now has the equivalent of noop mode with its why-run mode.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Chef&#39;s Secret Sauce&amp;nbsp;&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
Chef&#39;s&amp;nbsp;&lt;a href=&quot;http://wiki.opscode.com/display/chef/Data+Bags&quot;&gt;Data Bags&lt;/a&gt;&amp;nbsp;are incredibly useful. They are a very nice way to feed lists of users to multiple cookbooks. Think of them as global variables for your chef-server. One the benefits of data bags is that they allow you to separate your corporate information from your cookbooks. Thus, making it easier for Chef users to open-source their cookbooks. Puppet has extlookup but that is quite a bit more limited than data bags.&amp;nbsp;It looks like Puppet maybe getting something similar to data bags with&amp;nbsp;&lt;a href=&quot;http://wiki.opscode.com/display/chef/Data+Bags&quot;&gt;Hiera&lt;/a&gt;.&lt;br /&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
I also have to praise the &lt;a href=&quot;http://wiki.opscode.com/display/chef/Search&quot;&gt;Search&lt;/a&gt; function. It is an extemely intuitive way to to tie together dependencies between nodes, such as between a nagios server and its clients. Puppet has a way to &quot;export&quot; resources but I could never get my head around how that worked.&lt;/div&gt;
&lt;br /&gt;
In my experience, Chef has a more powerful read-eval-print-loop (&lt;a href=&quot;http://wiki.opscode.com/display/chef/Shef&quot;&gt;shef&lt;/a&gt;) than Puppet does. I use shef quite frequently and I cannot understate its helfulness. Puppet does not have a similar repl as far as I am aware.&lt;br /&gt;
&lt;br /&gt;
Server-side, Chef is much more complex but also seems to be better thought out. I love the fact that Chef uses a document-oriented database. This combines the benefits of using files to store your configuration (easy to understand) with the benefits of using a database (speed).&lt;br /&gt;
&lt;br /&gt;
&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-size: large;&quot;&gt;Hands-On&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
I don&#39;t believe there are many in the Puppet community that have extensively experimented with Chef before choosing Puppet. There are many in the Chef community that have worked previously with Puppet and found that it did not meet their needs.&lt;br /&gt;
&lt;br /&gt;
I started working with Puppet in June of this year and quickly fell in love. I read Pro Puppet and did all the exercises. Next I set to rewriting my 400 line linux provisioning script in puppet manifests. At first it &amp;nbsp;went well but then things got more complicated. I kept tripping over the DSL&#39;s syntax and was surprised that there weren&#39;t more puppet modules in puppetforge or github. I felt that I had to learn both the Puppet DSL and Ruby to really to be effective with Puppet. I started thinking that the grass might be greener on the other side.&lt;br /&gt;
&lt;br /&gt;
Two things convinced me to try out Chef. The first was the announcements by&amp;nbsp;&lt;a href=&quot;https://github.com/dellcloudedge/crowbar&quot;&gt;Dell&lt;/a&gt;&amp;nbsp;and Rackspace that they had built there Openstack provisioners on top of Chef. If the people pioneering devops chose to build their platform &lt;i&gt;on top of&lt;/i&gt; Chef, then it definitely deserved my attention. The next was&amp;nbsp;&lt;a href=&quot;http://devopscafe.org/show/2011/9/20/devops-cafe-episode-19.html&quot;&gt;Jesse Robbins&#39; interview&lt;/a&gt;&amp;nbsp;on DevopsCafe. He made all the action in the Chef community sound so exciting that I had to go check it out for myself.&lt;br /&gt;
&lt;br /&gt;
It took me three days to get Chef Server up and running on RHEL 5.7.&amp;nbsp;Next, I started writing my own cookbooks. Now I have nearly converted that linux provisioning script to a cookbook. Not counting the time it took me to set up the server, it took me roughly half the time it took with Puppet.&lt;br /&gt;
&lt;br /&gt;
It was easy to get started with Puppet, but things became more complicated with time. With Chef I am having the opposite experience.&amp;nbsp;Again, the single biggest drawback to Chef is that it has a steeper learning curve than Puppet. Further, most of the existing tutorials focus on the deeper concepts in Chef rather than giving novices quick gratification. To this end, I have started the&amp;nbsp;&lt;a href=&quot;http://devopsanywhere.blogspot.com/2011/10/stupid-simple-chef-tutorial-for-dirty.html&quot;&gt;&quot;Dirty Chef&quot;&lt;/a&gt;&amp;nbsp;series of tutorials.&lt;br /&gt;
&lt;br /&gt;
&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-size: large;&quot;&gt;Summary&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;u&gt;Final Scorecard&lt;/u&gt;&lt;br /&gt;
Community &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;-- &amp;nbsp;Puppet wins&lt;br /&gt;
Leadership &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; -- &amp;nbsp;Draw&lt;br /&gt;
Corporate Adoption -- &amp;nbsp;Draw&lt;br /&gt;
Technical Merits &amp;nbsp; &amp;nbsp; &amp;nbsp;-- &amp;nbsp;Chef&lt;br /&gt;
Hands-On &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;-- &amp;nbsp;Chef&lt;br /&gt;
&lt;br /&gt;
According to this non-scientific criteria, Chef is the better tool. In my humble opinion, Chef is technically superior. Don&#39;t buy the argument &quot;Chef requires you to be a programmer, Puppet doesn&#39;t.&quot;&amp;nbsp;While Puppet is geared towards non-programmers, it becomes regular programming once you do anything moderately complicated.&amp;nbsp;That&#39;s when Puppet&#39;s DSL becomes more of a liability than an asset and where Chef really shines. Now while chef is the winner of my little bake-off, it is not without faults. Puppet has far better support for RHEL/Centos and it does have a larger, more responsive community.&lt;br /&gt;
&lt;br /&gt;
Dear Puppet community, please know that I write this blog post with great ambivalence and I still love you. Jame Turnbull and R.I. Pienaar, thanks for all your help via IRC, Twitter, and the mailing list. Puppet Labs is developing a toolchain that is much larger than just the puppetmaster. This toolchain may turn out to be superior to what Opscode and its respective partners come up with.&lt;br /&gt;
&lt;br /&gt;
On a final note, please know that both of these tools are good enough for configuration management and are only one part of a larger &lt;a href=&quot;https://groups.google.com/forum/#!forum/devops-toolchain&quot;&gt;toolchain&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
P.S. I will delete any comments that trash either Puppet or Chef. They are both excellent tools, built by&lt;br /&gt;
visionaries.&lt;br /&gt;
&lt;br /&gt;
&lt;i&gt;Most of the discussion related this article seems to be happening on &lt;a href=&quot;http://news.ycombinator.com/item?id=3090800&quot;&gt;Hacker News&lt;/a&gt;.&lt;/i&gt;&lt;/div&gt;
&lt;/div&gt;
</content><link rel='replies' type='application/atom+xml' href='http://devopsanywhere.blogspot.com/feeds/9112587608076747911/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://devopsanywhere.blogspot.com/2011/10/puppet-vs-chef-fight.html#comment-form' title='42 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1083699665345453745/posts/default/9112587608076747911'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1083699665345453745/posts/default/9112587608076747911'/><link rel='alternate' type='text/html' href='http://devopsanywhere.blogspot.com/2011/10/puppet-vs-chef-fight.html' title='Puppet vs. Chef, Fight!'/><author><name>Anonymous</name><uri>http://www.blogger.com/profile/10631977500882582704</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>42</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1083699665345453745.post-2643145307113580497</id><published>2011-10-07T00:55:00.000-07:00</published><updated>2011-10-11T02:39:21.669-07:00</updated><title type='text'>A Stupid, Simple Chef Tutorial for Dirty, Lazy Fry Cooks (Like Me) Part I</title><content type='html'>&lt;div dir=&quot;ltr&quot; style=&quot;text-align: left;&quot; trbidi=&quot;on&quot;&gt;
&lt;div dir=&quot;ltr&quot; style=&quot;text-align: left;&quot; trbidi=&quot;on&quot;&gt;
&lt;i&gt;disclaimer: I am not a chef expert. To really learn chef, you need to go to the &lt;a href=&quot;http://wiki.opscode.com/display/chef/Home&quot;&gt;wiki&lt;/a&gt;&lt;/i&gt;&lt;br /&gt;
&lt;br /&gt;
I really like the &lt;a href=&quot;http://wiki.opscode.com/display/chef/Home&quot;&gt;chef&lt;/a&gt; documentation, I really do. It is an excellent reference. It is the devops equivalent of the manual they must use at the &lt;a href=&quot;http://www.cordonbleu.edu/&quot;&gt;Le Cordon Bleu&lt;/a&gt; cooking school. But I have to admit that sometimes I am just a dirty, lazy fry cook, especially when playing with a new technology. I want instant gratification or at least in under 30 minutes. &amp;nbsp;What I love about the Puppet documentation, is that it gets &lt;a href=&quot;http://docs.puppetlabs.com/learning/manifests.html&quot;&gt;you started quickly&lt;/a&gt;, before you begin optimizing and modularizing and all that other crap that good devops chefs do. To that end, I have created a &lt;a href=&quot;https://github.com/bryanwb/dirty-chef&quot;&gt;chef repository&lt;/a&gt; that is exactly what you shouldn&#39;t do in production but is hopefully useful for learning.&lt;br /&gt;
&lt;br /&gt;
&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: inherit;&quot;&gt;In this tutorial,&amp;nbsp;&lt;span class=&quot;Apple-style-span&quot; style=&quot;background-color: #f8f8f8; line-height: 20px;&quot;&gt;I am going to use chef-solo for the purpose of the tutorial. Chef-solo simply means running chef with out connecting to central chef server that provides you with cookbooks and some other functionality. Chef-server is awesome but currently a pain in the butt to set up. I am also going to use RHEL 6.0 but you can use CentOS.&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span class=&quot;Apple-style-span&quot; style=&quot;line-height: 20px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-size: large; line-height: 20px;&quot;&gt;Why Chef?&lt;/span&gt;&lt;br /&gt;
&lt;span class=&quot;Apple-style-span&quot; style=&quot;line-height: 20px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span class=&quot;Apple-style-span&quot; style=&quot;line-height: 20px;&quot;&gt;If you aren&#39;t yet using configuration management with Chef, Puppet, or similar tool you&#39;re just plain &lt;b&gt;doing it wrong&lt;/b&gt;. I&#39;m doing it wrong. I cobble together my infrastructure with a combination of kickstart, &amp;nbsp;bash scripts, &lt;a href=&quot;http://fabfile.org/&quot;&gt;fabfiles&lt;/a&gt;, and random python. But the diversity of applications I support and the sheer number of virtual machines are increasing rapidly. My agglomeration of virtual glue and duct tape is starting to look more like a house of cards and less like modern infrastructure.&lt;/span&gt;&lt;br /&gt;
&lt;span class=&quot;Apple-style-span&quot; style=&quot;line-height: 20px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span class=&quot;Apple-style-span&quot; style=&quot;line-height: 20px;&quot;&gt;In the immortal words of Puppet founder Luke Kanies:&lt;/span&gt;&lt;br /&gt;
&lt;span class=&quot;Apple-style-span&quot; style=&quot;line-height: 20px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;
&lt;div style=&quot;text-align: center;&quot;&gt;
&lt;span class=&quot;Apple-style-span&quot; style=&quot;line-height: 20px;&quot;&gt;&lt;b&gt;&quot;SSH in a for loop just doesn&#39;t cut it anymore.&quot;&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: center;&quot;&gt;
&lt;span class=&quot;Apple-style-span&quot; style=&quot;line-height: 20px;&quot;&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;
&lt;span class=&quot;Apple-style-span&quot; style=&quot;line-height: 20px;&quot;&gt;To build Luke&#39;s statement, our imperative bash/perl/python scripts are lousy for customizing server templates to specific node attributes and they suck at maintaining system state.&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;line-height: 20px;&quot;&gt;I&lt;/span&gt;&amp;nbsp;have tried both Puppet and &amp;nbsp;Chef and I prefer Chef for a number of reasons. The main ones are that it has a more elegant and easier to use &lt;a href=&quot;http://blog.loftninjas.org/2011/02/16/the-power-of-chef-and-ruby/&quot;&gt;DSL&lt;/a&gt; and that chef-server has the awesome &lt;a href=&quot;http://wiki.opscode.com/display/chef/Search&quot;&gt;search functionality&lt;/a&gt;.&lt;br /&gt;
&lt;span class=&quot;Apple-style-span&quot; style=&quot;line-height: 20px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-size: large;&quot;&gt;Installation&amp;nbsp;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
Install my chef repository somewhere on your system. I recommend /opt.&lt;br /&gt;
&lt;br /&gt;
&lt;code&gt;
$&amp;nbsp;&lt;/code&gt;&lt;code&gt;git clone git://github.com/bryanwb/dirty-chef.git&amp;nbsp;&lt;/code&gt;&lt;br /&gt;
&lt;br /&gt;
Next install chef. &amp;nbsp;Here is the &lt;a href=&quot;http://wiki.opscode.com/display/chef/Bootstrap+Chef+RubyGems+Installation&quot;&gt;main install guide&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
This should work on either CENTOS/RHEL 5 or 6&lt;br /&gt;
&lt;br /&gt;
For RHEL 5&lt;br /&gt;
&lt;br /&gt;
&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: monospace; font-size: 16px;&quot;&gt;&lt;/span&gt;&lt;br /&gt;
&lt;pre style=&quot;font-size: 14px;&quot;&gt;$ rpm -Uvh http://rbel.co/rbel5&lt;/pre&gt;
&lt;br /&gt;
&lt;br /&gt;
For RHEL 6&lt;br /&gt;
&lt;br /&gt;
&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: monospace; font-size: 16px;&quot;&gt;&lt;/span&gt;&lt;br /&gt;
&lt;pre style=&quot;font-size: 14px;&quot;&gt;rpm -Uvh http://rbel.co/rbel6&lt;/pre&gt;
&lt;br /&gt;
&lt;br /&gt;
Finally, on either&lt;br /&gt;
&lt;br /&gt;
&lt;code&gt;
$ yum install -y rubygem-chef ruby-shadow&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;
Now edit solo.rb, you &lt;b&gt;have to edit&lt;/b&gt; these paths to reflect the actual location of dirty-chef otherwise chef-solo will not work&lt;br /&gt;
&lt;br /&gt;
file:solo.rb&lt;br /&gt;
&lt;code&gt;
file_cache_path  &quot;/opt/dirty-chef/&quot;&amp;nbsp;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;cookbook_path  &quot;/opt/dirty-chef/cookbooks&quot;&amp;nbsp;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;data_bag_path  &quot;/opt/dirty-chef/databags&quot;
&lt;/code&gt;

&lt;br /&gt;
&lt;br /&gt;
If you are using RHEL 5 see the install link above, it has steps for RHEL 5 but they are more complicated

Run the following command&lt;br /&gt;
&lt;br /&gt;
&lt;code&gt;$ ohai | less&amp;nbsp;&lt;/code&gt;&lt;br /&gt;
&lt;br /&gt;
This shows you all the info that chef knows about your system. You can do reasoning in your recipes based on these values.&lt;br /&gt;
&lt;br /&gt;
&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-size: large;&quot;&gt;Start Cooking&amp;nbsp;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
Here is a stupid hello world&lt;br /&gt;
&lt;br /&gt;
&lt;code&gt;$ cd dirty-chef&amp;nbsp;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;$ chef-solo -c solo.rb -j node.json&amp;nbsp;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;ohai!&lt;/code&gt;&lt;br /&gt;
&lt;br /&gt;
What the heck did we just do? The solo.rb tells chef where the cookbooks are, i.e. where the recipes live, and node.json tells chef-solo which recipe to actually apply.&lt;br /&gt;
&lt;br /&gt;
file:node.json&lt;br /&gt;
&lt;code&gt;
{&lt;br /&gt;
&amp;nbsp; &quot;run_list&quot;: [ &quot;recipe[dirty]&quot; ]&lt;br /&gt;
}&lt;br /&gt;
&lt;/code&gt;
&lt;br /&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
This loads the recipe in cookbooks/dirty/default.rb&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
If you get any errors here, you should make sure that you changed the paths in solo.rb to reflect the location of dirty-chef/&lt;br /&gt;
&lt;br /&gt;
Now let us do something more significant.

You can use chef to declare &quot;resources&quot; in this case a package. Let&#39;s install subversion. In chef recipes, you spend most of your time declaring &lt;a href=&quot;http://wiki.opscode.com/display/chef/Resources&quot;&gt;resources&lt;/a&gt;, in this case I declare that I want subversion installed and chef takes care of the rest.&lt;br /&gt;
&lt;code&gt;&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: inherit;&quot;&gt;file:cookbooks/dirty/recipes/example1.rb&lt;/span&gt;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;package &quot;subversion&quot;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;$ chef-solo -c solo.rb -j example1.json&amp;nbsp;&lt;/code&gt;&lt;br /&gt;
&lt;br /&gt;
file:example1.json&lt;br /&gt;
&lt;br /&gt;
&lt;code&gt;{&lt;br /&gt;&amp;nbsp; &quot;run_list&quot;: [ &quot;recipe[dirty::example1]&quot; ]&lt;br /&gt;}&lt;/code&gt;&lt;br /&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
This loads the recipe in cookbooks/dirty/example1.rb&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
Here is an example of installing multiple packages, take a look at cookbooks/dirty/recipes/example2.rb&lt;br /&gt;
&lt;br /&gt;
&lt;code&gt;$ chef-solo -c solo.rb -j example2.json&amp;nbsp;&lt;/code&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;code&gt;&lt;/code&gt;What is that syntax of the configuration language? Why it is pure ruby. If you like perl, you will like ruby as it is the lovechild of perl and smalltalk.

Here is a &lt;a href=&quot;http://wiki.opscode.com/display/chef/Just+Enough+Ruby+for+Chef&quot;&gt;good quick reference&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
You still are not impressed? True you could do all these things in a kickstart more easily and without having to go to so much trouble. There are several reasons chef is better than kickstart.

You can use chef to maintain the state of your server while you can only use kickstart to initially set up your server.
Once you install your server from a kickstart, you cannot rerun it w/out reformatting it. Chef on the other hand is &quot;idempotent&quot; Meaning it has the same effect whether run once or 100 times. Say for some reason subversion is removed from your machine. The above chef recipe will reinstall it w/out needing your intervention.

You can seamlessly handle different platform versions. You can write one recipe that handles both RHEL 5 and RHEL 6 by doing reasoning on node attributes.
Maybe you are like me and love nothing better than a good REPL (Read-Eval Print Loop), i.e. console. Chef comes with an awesome REPL, shef. Let us use it to play node attributes and even load recipes interactively&lt;br /&gt;
&lt;br /&gt;
&lt;code&gt;[root@woof-chef recipes]# shef&amp;nbsp;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;loading configuration: none (standalone shef session)&amp;nbsp;
&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;Session type: standalone&amp;nbsp;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;Ohai2u root@woof-chef!&amp;nbsp;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;chef &amp;gt; if node[&quot;platform_version&quot;] =~ /6./&amp;nbsp;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;chef ?&amp;gt; puts &quot;hi rhel 6!&quot;&amp;nbsp;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;chef ?&amp;gt; end&amp;nbsp;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;hi rhel 6!&amp;nbsp;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;[ type ctl-D to exit ]&amp;nbsp;&lt;/code&gt;&lt;br /&gt;
&lt;br /&gt;
In shef, you have access to all the node attributes and cookbooks on your system. Now let us put the same logic in a recipe.&lt;br /&gt;
&lt;code&gt;&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;$ chef-solo -c solo.rb -j example3.json&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;
&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: inherit;&quot;&gt;Now we still haven&#39;t actually done anything useful. We will get to that in Part II&lt;/span&gt;&lt;/div&gt;
</content><link rel='replies' type='application/atom+xml' href='http://devopsanywhere.blogspot.com/feeds/2643145307113580497/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://devopsanywhere.blogspot.com/2011/10/stupid-simple-chef-tutorial-for-dirty.html#comment-form' title='9 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1083699665345453745/posts/default/2643145307113580497'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1083699665345453745/posts/default/2643145307113580497'/><link rel='alternate' type='text/html' href='http://devopsanywhere.blogspot.com/2011/10/stupid-simple-chef-tutorial-for-dirty.html' title='A Stupid, Simple Chef Tutorial for Dirty, Lazy Fry Cooks (Like Me) Part I'/><author><name>Anonymous</name><uri>http://www.blogger.com/profile/10631977500882582704</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>9</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1083699665345453745.post-1349270735738108110</id><published>2011-10-03T01:47:00.000-07:00</published><updated>2011-10-03T06:17:26.480-07:00</updated><title type='text'>What is devopsanywhere?</title><content type='html'>&lt;div dir=&quot;ltr&quot; style=&quot;text-align: left;&quot; trbidi=&quot;on&quot;&gt;
Why DevopsAnywhere? Because our profession is undergoing some profound changes. On the positive side, the best of us are in &lt;a href=&quot;http://www.businessweek.com/magazine/puppet-chef-ease-transition-to-cloud-computing-09012011.html&quot;&gt;increasing demand&lt;/a&gt;. On the other hand, it will take increasing sophistication on our parts to keep up w/ the blistering pace of change in our industry. I believe that to really keep up-to-date, you have be an &lt;a href=&quot;http://en.wikipedia.org/wiki/Autodidacticism&quot;&gt;autodidact&lt;/a&gt;, that is someone who is primarily self-taught.&lt;br /&gt;
&lt;br /&gt;
In my experience, autodidacts are randomly distributed around the planet. Linux obsessing, python hacking, ruby scripting geeks are even more randomly distributed. Should companies really want to recruit us, they will have to hire us where we are, be that Kathmandu, Sicily, or Utah. Gone are the days where system administrators lived at the datacenter, as I explain in greater detail later.&lt;br /&gt;
&lt;br /&gt;
As system administrators we were tied to the datacenter. Even if we worked remotely, we had to be within easy driving distance. We were software/hardware hybrids that understood all the various permutations of RAID 0/1/5/6/10. We looked on with envy at the alpha programmers who could do their jobs while lying on the beach in Thailand or while huddled in a cozy cabin in the French Alps.&lt;br /&gt;
&lt;br /&gt;
Our profession is transforming from System Administrators to Devops Engineers. &lt;i&gt;Devop&lt;/i&gt;s is a bit tricky as it is as vague a term as &lt;i&gt;agile&lt;/i&gt;. Still, it points to a new class of engineers that are focused on &lt;b&gt;op&lt;/b&gt;eration&lt;b&gt;s&lt;/b&gt; and work seamlessly with software &lt;b&gt;dev&lt;/b&gt;elopers. We are self-taught engineers who have the luxury to work remotely. This blog will be entirely focused on the concerns and interests of devops engineers working remotely. Further, I won&#39;t talk about expensive proprietary software or hardware. Actually, I will rarely talk about hardware at all.&lt;br /&gt;
&lt;br /&gt;
Some, like &lt;a href=&quot;http://www.johnmwillis.com/&quot;&gt;John Willis&lt;/a&gt; and &lt;a href=&quot;http://twitter.com/#!/damonedwards&quot;&gt;Damon Edwards&lt;/a&gt;&amp;nbsp;of the awesome &lt;a href=&quot;http://devopscafe.org/&quot;&gt;Devops Cafe&lt;/a&gt;, will argue that process is more important tooling. I agree with this 100%. However, as system administrators we often aren&#39;t in the position to reorganize our team&#39;s management structure. We are in a position to introduce new tools and lobby for better ways of working.&lt;br /&gt;
&lt;br /&gt;
Here is a comparison of the requirements for being a SysAdmin and that for Devops Engineer&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-size: large;&quot;&gt;A new Set of Skills&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
System Administration today requires:&lt;br /&gt;
&lt;br /&gt;
&lt;ul style=&quot;text-align: left;&quot;&gt;
&lt;li&gt;deep knowledge of *nix, including linux, solaris, and even some proprietary unices like HP-UX&lt;/li&gt;
&lt;li&gt;you really __know__ bash&lt;/li&gt;
&lt;li&gt;some basic version control&amp;nbsp;w/ cvs/svn&lt;/li&gt;
&lt;li&gt;simple scripting w/ bash/perl/python&lt;/li&gt;
&lt;li&gt;understanding of virtualization&lt;/li&gt;
&lt;li&gt;You can troubleshoot hardware, firmware issues, even flip a dip switch or change SCSI IDs if necessary&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
Devops requires:&lt;br /&gt;
&lt;br /&gt;
&lt;ul style=&quot;text-align: left;&quot;&gt;
&lt;li&gt;deep knowledge of Linux -- generally not Solaris, AIX or&amp;nbsp;HP-UX&lt;/li&gt;
&lt;li&gt;you __know__ bash&lt;/li&gt;
&lt;li&gt;you are very proficient in svn and/or git&lt;/li&gt;
&lt;li&gt;You are a practicioner of puppet or chef&lt;/li&gt;
&lt;li&gt;system scripting with ruby&lt;/li&gt;
&lt;li&gt;System packaging -- ruby gems, rpms, debian packages&lt;/li&gt;
&lt;li&gt;You can setup package repositiories on a whim&lt;/li&gt;
&lt;li&gt;you understand unit testing and behavior-driven testing, hopefully you practice it w/ &lt;a href=&quot;http://cukes.info/&quot;&gt;Cucumber&lt;/a&gt;&amp;nbsp;or something like it&lt;/li&gt;
&lt;li&gt;AWS, Rackspace, cloud provisioning -- &amp;nbsp;but of course&lt;/li&gt;
&lt;/ul&gt;
&lt;b&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-size: large;&quot;&gt;Hardware is now (mostly) irrelevant&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
The only NIC cards a devops engineer cares about are the Intel e1000 or whatever paravirtualized driver your hypervisor of choice offers.&amp;nbsp;We know that working on hardware issues only lowers our hourly billing rate. Now, more than ever, the power is in software and hardware-oriented solutions are to be avoided.&lt;br /&gt;
&lt;br /&gt;
I must confess that I have an ulterior motive for starting this blog. I am a linux system administrator who is following his wife&#39;s career around the world. Previously we were in Nepal, now we are in Italy, next up who knows! But I want to work with top-notch teams wherever I end up and not be tied to whatever opportunities are locally available. If you are a devops guy and you feel the same, let me know!&lt;/div&gt;
</content><link rel='replies' type='application/atom+xml' href='http://devopsanywhere.blogspot.com/feeds/1349270735738108110/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://devopsanywhere.blogspot.com/2011/10/what-is-devopsanywhere.html#comment-form' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1083699665345453745/posts/default/1349270735738108110'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1083699665345453745/posts/default/1349270735738108110'/><link rel='alternate' type='text/html' href='http://devopsanywhere.blogspot.com/2011/10/what-is-devopsanywhere.html' title='What is devopsanywhere?'/><author><name>Anonymous</name><uri>http://www.blogger.com/profile/10631977500882582704</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1083699665345453745.post-3289398787867988793</id><published>2011-09-16T11:12:00.000-07:00</published><updated>2011-10-03T07:00:18.809-07:00</updated><title type='text'>How Ruby is beating Python in the battle for the Soul of System Administration</title><content type='html'>&lt;div dir=&quot;ltr&quot; style=&quot;text-align: left;&quot; trbidi=&quot;on&quot;&gt;
&lt;div&gt;
Roughly three years ago I purchased the book &lt;a href=&quot;http://www.amazon.com/Python-Unix-Linux-System-Administration/dp/0596515820/ref=sr_1_3?ie=UTF8&amp;amp;qid=1316171701&amp;amp;sr=8-3&quot;&gt;&quot;Python for Unix and Linux System Administration&quot;&lt;/a&gt; and it convinced me that Python would be the default scripting language for linux system administrators for the foreseeable future. I was working on the One Laptop Per Child project at the time, where Python was the lingua franca. It seemed that Red Hat was using Python for almost every new project. Further, &lt;a href=&quot;http://en.wikipedia.org/wiki/Unladen_Swallow&quot;&gt;Unladen Swallow&lt;/a&gt; was making rapid progress. I couldn&#39;t have been more wrong.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
Through a combination of historical accident and some seemingly minor feature differences, ruby is inexorably becoming the dominant scripting language for linux system administration. &lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
Before I go any farther you die-hard sysadmins are probably screaming &quot;We already have a scripting language, Bash!&quot; While we love bash and &lt;a href=&quot;http://www.commandlinefu.com/commands/browse&quot;&gt;commandlinefu&lt;/a&gt;, Bash becomes a liability not an asset once your script exceeds 100 lines and a total nightmare if you need to parse or output HTML, CSV, XML, JSON, etc.  &lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;b&gt;Historical Accidents&lt;/b&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
In 2004, Luke Kanies set about building &lt;a href=&quot;http://www.puppetlabs.com/&quot;&gt;Puppet&lt;/a&gt;,  a configuration management system to improve upon the deficiencies he saw in CFEngine. From the excellent &lt;a href=&quot;http://on-ruby.blogspot.com/2008/02/puppet-interview-with-luke-kanies.html&quot;&gt;On Ruby blog&lt;/a&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span class=&quot;Apple-style-span&quot; style=&quot;background-color: white; color: #333333; line-height: 16px;&quot;&gt;&lt;/span&gt;&lt;br /&gt;
&lt;blockquote&gt;
&lt;span class=&quot;Apple-style-span&quot; style=&quot;background-color: white; color: #333333; line-height: 16px;&quot;&gt;&lt;span class=&quot;Apple-style-span&quot;&gt;I tried to implement my idea in perl, but I just couldn’t get the class relationships to work (the attributes and resource types each needed to be classes, according to the design in my head). This was back when Python was the shiznit, so I naturally tried it, but Python just makes my eyes bleed (and no, it wasn’t the whitespace, it was things like the fact that ‘print’ was a statement instead of a function, and ‘len’ was a function instead of a method).&lt;/span&gt;&lt;/span&gt;&lt;/blockquote&gt;
&lt;span class=&quot;Apple-style-span&quot; style=&quot;background-color: white; color: #333333; line-height: 16px;&quot;&gt;&lt;/span&gt;&lt;br /&gt;
&lt;blockquote&gt;
&lt;span class=&quot;Apple-style-span&quot; style=&quot;background-color: white; color: #333333; line-height: 16px;&quot;&gt;&lt;span class=&quot;Apple-style-span&quot;&gt;I had a friend who had heard Ruby was cool but hadn’t actually tried it himself. Since I was just messing around at the time, I figured I’d give it a go. Four hours in, never having seen a line of Ruby previously, I had a functional prototype.&lt;/span&gt;&lt;/span&gt;&lt;/blockquote&gt;
&lt;span class=&quot;Apple-style-span&quot; style=&quot;background-color: white; color: #333333; line-height: 16px;&quot;&gt;
&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
A couple years, a number of Puppet developers felt that Puppet didn&#39;t meet their needs. They started their own configuration management tool, &lt;a href=&quot;http://wiki.opscode.com/display/chef/Home&quot;&gt;Chef&lt;/a&gt;, heavily inspired by Puppet. The biggest outward difference between Puppet and Chef is that Chef uses pure ruby as its &quot;recipes&quot; whereas Puppet uses its own configuration language based on ruby. &lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
Both Puppet and Chef are seeing rapid adoption by big companies &lt;a href=&quot;http://www.businessweek.com/magazine/puppet-chef-ease-transition-to-cloud-computing-09012011.html&quot;&gt;according to BusinessWeek&lt;/a&gt;. If you aren&#39;t yet using Puppet or Chef, you should be planning on it in the near future. Whether you choose Chef or Puppet, you are effectively scripting your infrastructure with ruby. After spending 25% of your time working with Puppet, you will be much more likely to reach for ruby for your next scripting task.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span class=&quot;Apple-style-span&quot;&gt;&lt;b&gt;Popular Projects&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
Off-hand here is a non-definitive list of sysadmin/devops related projects in ruby&lt;/div&gt;
&lt;div&gt;
&lt;ul&gt;
&lt;li&gt;puppet&lt;/li&gt;
&lt;li&gt;chef&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://vagrantup.com/&quot;&gt;vagrant&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;mcollective&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://cukes.info/&quot;&gt;cucumber&lt;/a&gt; (behavior-driven testing)&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/capistrano/capistrano/wiki/Documentation-v2.x&quot;&gt;capistrano&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;rake (ruby Make)&lt;/li&gt;
&lt;li&gt;aeolus project/openshift&lt;/li&gt;
&lt;li&gt;cloud foundry&lt;/li&gt;
&lt;li&gt;graylog2&lt;/li&gt;
&lt;li&gt;logstash&lt;/li&gt;
&lt;li&gt;travis-ci&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div&gt;
and in Python:&lt;/div&gt;
&lt;div&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http://openstack.org/&quot;&gt;openstack&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://fedorahosted.org/cobbler/&quot;&gt;cobbler&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://fabfile.org/&quot;&gt;fabric&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://fedorahosted.org/func/&quot;&gt;func&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;buildbot&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div&gt;
What&#39;s important here isn&#39;t the length of the respective lists but the importance of the individual projects. Chef, Puppet, and Vagrant are the new hammers and screwdrivers of system administration. If you are a sysadmin and aren&#39;t yet using these tools, don&#39;t worry, you will be sooner or later.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
Openstack deserves special attention as it is a very exciting but early stage project. It could play a big role in your future as a system administrator.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
Please notify me of significant devops projects that are missing from this list.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;b&gt;&lt;span class=&quot;Apple-style-span&quot;&gt;What a &lt;strike&gt;Girl&lt;/strike&gt; Sysadmin Wants&lt;/span&gt;&lt;/b&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
Here are the features in a scripting language that a sysadmin wants&lt;/div&gt;
&lt;div&gt;
&lt;ul&gt;
&lt;li&gt;A DSL for the problem domain &lt;/li&gt;
&lt;li&gt;High productivity, i.e. concise and expressive syntax&lt;/li&gt;
&lt;li&gt;Easy to interaction with shell commands&lt;/li&gt;
&lt;li&gt;Regular Expressions&lt;/li&gt;
&lt;li&gt;powerful one-liners&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div&gt;
Notice that performance is not on this list of requirements. Ruby is significantly slower than Python and this was particularly true for the 1.8.* series of Matz Ruby Interpreter (MRI). However, performance just isn&#39;t critical for 90% of our work as sysadmins. We care about productivity more than we care about performance. Readability is nice but it is a distant second to productivity.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
Python doesn&#39;t have regular expressions embedded in the language, probably to improve readability. It also limits the number of top-level built-in global variables. From a language design perspective, this is much cleaner. From the perspective of your average street-trained, stress-laden, vi-addicted sysadmin, it is annoying.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
These top-level variables also make one-liners more concise. Here are just a few&lt;/div&gt;
&lt;div&gt;
&lt;/div&gt;
&lt;div style=&quot;text-align: -webkit-auto;&quot;&gt;
&lt;span class=&quot;Apple-style-span&quot;&gt;&lt;code&gt;&lt;/code&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: -webkit-auto;&quot;&gt;
&lt;code&gt;&lt;span class=&quot;Apple-style-span&quot;&gt;&lt;code&gt;&lt;/code&gt;&lt;/span&gt;&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: -webkit-auto;&quot;&gt;
&lt;code&gt;&lt;code&gt;&lt;span class=&quot;Apple-style-span&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/code&gt;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&lt;code&gt;&lt;span class=&quot;Apple-style-span&quot;&gt;$_        last line read from STDIN&lt;/span&gt;&lt;/code&gt;&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: -webkit-auto;&quot;&gt;
&lt;code&gt;&lt;code&gt;&lt;span class=&quot;Apple-style-span&quot;&gt;$?        last exit code from a child process&lt;/span&gt;&lt;/code&gt;&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: -webkit-auto;&quot;&gt;
&lt;code&gt;&lt;code&gt;&lt;span class=&quot;Apple-style-span&quot;&gt;$stdin    reference to stdin&lt;/span&gt;&lt;/code&gt;&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: -webkit-auto;&quot;&gt;
&lt;code&gt;&lt;code&gt;&lt;span class=&quot;Apple-style-span&quot;&gt;$stderr   reference to stdout&lt;/span&gt;&lt;/code&gt;&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: -webkit-auto;&quot;&gt;
&lt;code&gt;&lt;code&gt;&lt;span class=&quot;Apple-style-span&quot;&gt;$stdout   reference to stdout&lt;/span&gt;&lt;/code&gt;&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: -webkit-auto;&quot;&gt;
&lt;code&gt;&lt;code&gt;&lt;span class=&quot;Apple-style-span&quot;&gt;&lt;/span&gt;&lt;/code&gt;&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: -webkit-auto;&quot;&gt;
&lt;code&gt;&lt;span class=&quot;Apple-style-span&quot;&gt;&lt;/span&gt;&lt;/code&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: -webkit-auto;&quot;&gt;
&lt;span class=&quot;Apple-style-span&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: -webkit-auto;&quot;&gt;
&lt;span class=&quot;Apple-style-span&quot;&gt;Here is an irb session to show you these values in action&lt;/span&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: -webkit-auto;&quot;&gt;
&lt;span class=&quot;Apple-style-span&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: -webkit-auto;&quot;&gt;
&lt;span class=&quot;Apple-style-span&quot;&gt;&lt;code&gt;&lt;/code&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: -webkit-auto;&quot;&gt;
&lt;code&gt;&lt;span class=&quot;Apple-style-span&quot;&gt;&lt;/span&gt;&lt;/code&gt;&lt;br /&gt;
&lt;div&gt;
&lt;code&gt;&lt;span class=&quot;Apple-style-span&quot;&gt;hitman@hiroko:~/pr$ irb&lt;/span&gt;&lt;/code&gt;&lt;/div&gt;
&lt;div&gt;
&lt;code&gt;&lt;span class=&quot;Apple-style-span&quot;&gt;irb(main):001:0&amp;gt; %x[ ls -a ]&lt;/span&gt;&lt;/code&gt;&lt;/div&gt;
&lt;div&gt;
&lt;code&gt;&lt;span class=&quot;Apple-style-span&quot;&gt;=&amp;gt; &quot;.\n..\nfoo1\nfoo2\nfoo3\n&quot;&lt;/span&gt;&lt;/code&gt;&lt;/div&gt;
&lt;div&gt;
&lt;code&gt;&lt;span class=&quot;Apple-style-span&quot;&gt;irb(main):002:0&amp;gt; puts $?&lt;/span&gt;&lt;/code&gt;&lt;/div&gt;
&lt;div&gt;
&lt;code&gt;&lt;span class=&quot;Apple-style-span&quot;&gt;0&lt;/span&gt;&lt;/code&gt;&lt;/div&gt;
&lt;div&gt;
&lt;code&gt;&lt;span class=&quot;Apple-style-span&quot;&gt;=&amp;gt; nil&lt;/span&gt;&lt;/code&gt;&lt;/div&gt;
&lt;div&gt;
&lt;code&gt;&lt;span class=&quot;Apple-style-span&quot;&gt;irb(main):003:0&amp;gt; %x[ ls xys ]&lt;/span&gt;&lt;/code&gt;&lt;/div&gt;
&lt;div&gt;
&lt;code&gt;&lt;span class=&quot;Apple-style-span&quot;&gt;ls: cannot access xys: No such file or directory&lt;/span&gt;&lt;/code&gt;&lt;/div&gt;
&lt;div&gt;
&lt;code&gt;&lt;span class=&quot;Apple-style-span&quot;&gt;=&amp;gt; &quot;&quot;&lt;/span&gt;&lt;/code&gt;&lt;/div&gt;
&lt;div&gt;
&lt;code&gt;&lt;span class=&quot;Apple-style-span&quot;&gt;irb(main):004:0&amp;gt; puts $?&lt;/span&gt;&lt;/code&gt;&lt;/div&gt;
&lt;div&gt;
&lt;code&gt;&lt;span class=&quot;Apple-style-span&quot;&gt;512&lt;/span&gt;&lt;/code&gt;&lt;/div&gt;
&lt;div&gt;
&lt;code&gt;&lt;span class=&quot;Apple-style-span&quot;&gt;=&amp;gt; nil&lt;/span&gt;&lt;/code&gt;&lt;/div&gt;
&lt;span class=&quot;Apple-style-span&quot;&gt;&lt;/span&gt;&lt;br /&gt;
&lt;div&gt;
&lt;span class=&quot;Apple-style-span&quot;&gt;&lt;code&gt;&lt;/code&gt;&lt;/span&gt;&lt;/div&gt;
&lt;span class=&quot;Apple-style-span&quot;&gt;
&lt;/span&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: -webkit-auto;&quot;&gt;
&lt;span class=&quot;Apple-style-span&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: -webkit-auto;&quot;&gt;
&lt;span class=&quot;Apple-style-span&quot;&gt;&quot;IRB?&quot; you scoff &quot;You will have to tear IPython from my cold dead hands.&quot; &lt;/span&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: -webkit-auto;&quot;&gt;
&lt;span class=&quot;Apple-style-span&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: -webkit-auto;&quot;&gt;
&lt;span class=&quot;Apple-style-span&quot;&gt;I love IPython. I have used IPython for 4+ years and IRB doesn&#39;t hold a candle to it. That said, ruby&#39;s shortcuts are really useful, enough to compensate for IRB&#39;s shortcomings. There is something called &lt;a href=&quot;http://pablotron.org/software/wirble/&quot;&gt;wirble&lt;/a&gt; that I haven&#39;t tried yet that may make irb a lot more&amp;nbsp;&lt;/span&gt;productive.&lt;/div&gt;
&lt;div style=&quot;text-align: -webkit-auto;&quot;&gt;
&lt;span class=&quot;Apple-style-span&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span class=&quot;Apple-style-span&quot;&gt;Here some python code to detect whether a machine is a VMware VM.&lt;/span&gt;&lt;br /&gt;
&lt;code&gt;&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;
&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: monospace;&quot;&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;background-color: #f6f6ef; font-family: Verdana; font-size: 12px;&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;pre style=&quot;max-width: 600px; overflow-x: auto; overflow-y: auto; padding-bottom: 2px; padding-left: 2px; padding-right: 2px; padding-top: 2px;&quot;&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: monospace;&quot;&gt;&lt;code&gt;# edit: fixed python code tks to kstrauser&lt;/code&gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre style=&quot;max-width: 600px; overflow-x: auto; overflow-y: auto; padding-bottom: 2px; padding-left: 2px; padding-right: 2px; padding-top: 2px;&quot;&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: monospace;&quot;&gt;&lt;code&gt;  import os
    if &#39;vmware&#39; in os.popen(&#39;dmidecode&#39;).upper():
        print &#39;this is a vmware vm&#39;
    else:
        print &#39;this is not a vmware vm&#39;&lt;/code&gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre style=&quot;max-width: 600px; overflow-x: auto; overflow-y: auto; padding-bottom: 2px; padding-left: 2px; padding-right: 2px; padding-top: 2px;&quot;&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: monospace;&quot;&gt;
&lt;/span&gt;&lt;/pre&gt;
&lt;pre style=&quot;max-width: 600px; overflow-x: auto; overflow-y: auto; padding-bottom: 2px; padding-left: 2px; padding-right: 2px; padding-top: 2px;&quot;&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: monospace;&quot;&gt;
&lt;/span&gt;&lt;/pre&gt;
&lt;br /&gt;
Here the same code in ruby&lt;br /&gt;
&lt;br /&gt;
`dmidecode`&lt;br /&gt;
if $_ ~= /vmware/i&lt;br /&gt;
&amp;nbsp; &amp;nbsp; puts &#39;this is a vmware vm&#39;&lt;br /&gt;
else&lt;br /&gt;
&amp;nbsp; &amp;nbsp; puts &#39;this is not a vmware vm&#39;

&lt;span class=&quot;Apple-style-span&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
Frankly, this kind of code makes my eyes bleed. The python example is far more readable and maintainable. That said, a lot of sysadmins would appreciate the terseness of the ruby example.&lt;br /&gt;
&lt;br /&gt;
Let&#39;s look at writing one-liners in both languages.&lt;br /&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
This code prints out the first 10 lines in a file using Python&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
&lt;code&gt;python -c &quot;import sys; sys.stdout.write(&#39;&#39;.join(sys.stdin.readlines()[:10]))&quot; &amp;lt; /path/to/your/file&lt;/code&gt;&lt;br /&gt;
&lt;br /&gt;
here is the same in Ruby&lt;br /&gt;
&lt;code&gt;&lt;br /&gt;ruby -ne &#39;puts $_ if $. &amp;lt;= 10 &#39; &amp;lt; /path/to/your/file &lt;/code&gt;&lt;br /&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
Compare for yourself between these collections of oneliners in &lt;a href=&quot;http://wiki.python.org/moin/Powerful%20Python%20One-Liners&quot;&gt;python&lt;/a&gt; and &lt;a href=&quot;http://reference.jumpingmonkey.org/programming_languages/ruby/ruby-one-liners.html&quot;&gt;ruby&lt;/a&gt;. If ruby reminds of perl, your eyes do not deceive you. In many ways it is the love child of perl and smalltalk.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;b&gt;&lt;span class=&quot;Apple-style-span&quot;&gt;DSLs FTW&lt;/span&gt;&lt;/b&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
Some time ago, I tried to watch all the &lt;a href=&quot;http://mitpress.mit.edu/sicp/&quot;&gt;Structure and Interpretation of Computing&lt;/a&gt; lectures. This endeavor failed miserably but I recall Harold Abelson saying that every large program should have its own internal DSL suited to the problem space. This is debatable in regards to the larger world of programming but I think it is very apt for system administration. We spend our entire careers with &lt;i&gt;n&lt;/i&gt; different DSLs. Each different configuration file format is its own DSL.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
If you compare rake (Ruby Make) to rails code, they look quite different, almost like different languages. If you compare &lt;a href=&quot;http://fabfile.org/&quot;&gt;fabric&lt;/a&gt; code to a django class, they look quite similar. This is both a strength and a liability. I am not a language lawyer but it seems much easier to create DSL&#39;s (Domain Specific Languages). Ruby certainly spawns DSLs with much greater frequency than python. No single pythonic build tool dominates the problem space like rake does in the ruby community. Most python projects seems to use &lt;a href=&quot;http://docs.python.org/distutils/setupscript.html&quot;&gt;setup.py&lt;/a&gt; for administrative tasks even though that is not its explicit purpose.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
Both puppet and chef are DSLs for system administration. Capistrano is a DSL for application deployment. Ruby&#39;s operator overriding and blocks lend themselves to the easy creation of DSLs.&lt;/div&gt;
&lt;div&gt;
&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/div&gt;
&lt;div&gt;
&lt;b&gt;&lt;span class=&quot;Apple-style-span&quot;&gt;In Summary&lt;/span&gt;&lt;/b&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
Ruby&#39;s greatest strength is its amazing flexibility. There is a lot of &quot;magic&quot; in ruby and sometimes it is dark magic. Python intentionally has minimal magic. It&#39;s greatest strengths are the best practices it enforces across its community. These practices make Python very readable across different projects; they ensure high quality documentation; they make the standard library kick ass. But the fact is that we sysadmins need flexibility more than we need raw power or consistency. Still, these are not the real reasons that ruby is overtaking python.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
Ruby is fast becoming the default scripting language for sysadmins because back in 2004, Luke Kanies looked at Python and &lt;a href=&quot;http://on-ruby.blogspot.com/2008/02/puppet-interview-with-luke-kanies.html&quot;&gt;felt ill&lt;/a&gt; (I had the opposite reaction). As a sysadmin you either currently are or soon will be using Puppet or Chef on a daily basis, spending a heck of a lot of time essentially coding in ruby. Personally, I much prefer writing python but am shifting to writing my scripts in ruby because I spend so much time with Chef.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;/div&gt;
</content><link rel='replies' type='application/atom+xml' href='http://devopsanywhere.blogspot.com/feeds/3289398787867988793/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://devopsanywhere.blogspot.com/2011/09/how-ruby-is-beating-python-in-battle.html#comment-form' title='45 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1083699665345453745/posts/default/3289398787867988793'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1083699665345453745/posts/default/3289398787867988793'/><link rel='alternate' type='text/html' href='http://devopsanywhere.blogspot.com/2011/09/how-ruby-is-beating-python-in-battle.html' title='How Ruby is beating Python in the battle for the Soul of System Administration'/><author><name>Anonymous</name><uri>http://www.blogger.com/profile/10631977500882582704</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>45</thr:total></entry></feed>