<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
 
 <title>The blog of Leonid Mirsky</title>
 <link href="http://leonidmirsky.com/atom.xml" rel="self"/>
 <link href="http://leonidmirsky.com"/>
 <updated>2013-11-28T04:25:10-08:00</updated>
 <id>http://leonidmirsky.com</id>
 <author>
   <name>Leonid Mirsky</name>
   <email>leonidlm@gmail.com</email>
 </author>

 
 <entry>
   <title>Creating hadoop test environment with ansible and vagrant</title>
   <link href="http://leonidmirsky.com/ansible/hadoop/devops/2013/11/19/creating-hadoop-test-environment-with-ansible-and-vagrant.html"/>
   <updated>2013-11-19T18:31:00Z</updated>
   <id>http://leonidmirsky.com/ansible/hadoop/devops/2013/11/19/creating-hadoop-test-environment-with-ansible-and-vagrant</id>
   <content type="html">&lt;p&gt;I love Puppet!&lt;/p&gt;

&lt;p&gt;I always hated shell scripting.&lt;/p&gt;

&lt;p&gt;When I discovered Puppet a year ago, I finally found a good programmable way to describe the infrastructure I am working with. A lot changed since my first encounter with Puppet, especially, since plenty of new and interesting tools appeared which compete with Puppet for the heart of a sysadmin.&lt;/p&gt;

&lt;p&gt;One of these shiny new configuration management tools is &lt;a href=&#39;http://www.ansibleworks.com/&#39;&gt;Ansible&lt;/a&gt;. I decided to give it a try, and to configure a local Hadoop development environment using it and vagrant.&lt;/p&gt;
&lt;hr /&gt;
&lt;h2 id=&#39;prerequisites&#39;&gt;Prerequisites&lt;/h2&gt;

&lt;p&gt;In this tutorial I will use vagrant version &lt;a href=&#39;http://docs.vagrantup.com/v2/installation/&#39;&gt;1.3.5&lt;/a&gt;, and VirtualBox version 4.1.12 on Ubuntu. Ansible must be installed on the same system as vagrant because the vagrant Ansible provisioner relies on that to perform it&amp;#8217;s magic. I used &lt;a href=&#39;http://www.ansibleworks.com/docs/intro_installation.html&#39;&gt;ansible&lt;/a&gt; version 1.3.3 since it supports the roles functionality which we will use in this tutorial.&lt;/p&gt;

&lt;h2 id=&#39;vagrant_configuration&#39;&gt;Vagrant configuration&lt;/h2&gt;

&lt;p&gt;Let&amp;#8217;s start by downloading Ansible example modules into your working directory. We will use the Hadoop playbook to do most of the heavy lifting for us.&lt;/p&gt;

&lt;p&gt;&lt;div class=&#39;highlight&#39;&gt;&lt;pre&gt;&lt;code class=&#39;shell-session&#39;&gt;&lt;span class=&#39;gp&#39;&gt;[leonid@laptop ~]$&lt;/span&gt; wget https://github.com/ansible/ansible-examples/archive/master.zip
&lt;span class=&#39;gp&#39;&gt;[leonid@laptop ~]$&lt;/span&gt; unzip master.zip ansible-examples-master/hadoop/*
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/p&gt;

&lt;p&gt;For the Vagrant configuration, I used the following Vagrantfile.&lt;/p&gt;
&lt;div class=&#39;highlight&#39;&gt;&lt;pre&gt;&lt;code class=&#39;ruby&#39;&gt;&lt;span class=&#39;no&#39;&gt;VAGRANTFILE_API_VERSION&lt;/span&gt; &lt;span class=&#39;o&#39;&gt;=&lt;/span&gt; &lt;span class=&#39;s2&#39;&gt;&amp;quot;2&amp;quot;&lt;/span&gt;

&lt;span class=&#39;no&#39;&gt;Vagrant&lt;/span&gt;&lt;span class=&#39;o&#39;&gt;.&lt;/span&gt;&lt;span class=&#39;n&#39;&gt;configure&lt;/span&gt;&lt;span class=&#39;p&#39;&gt;(&lt;/span&gt;&lt;span class=&#39;no&#39;&gt;VAGRANTFILE_API_VERSION&lt;/span&gt;&lt;span class=&#39;p&#39;&gt;)&lt;/span&gt; &lt;span class=&#39;k&#39;&gt;do&lt;/span&gt; &lt;span class=&#39;o&#39;&gt;|&lt;/span&gt;&lt;span class=&#39;n&#39;&gt;config&lt;/span&gt;&lt;span class=&#39;o&#39;&gt;|&lt;/span&gt;
  &lt;span class=&#39;n&#39;&gt;config&lt;/span&gt;&lt;span class=&#39;o&#39;&gt;.&lt;/span&gt;&lt;span class=&#39;n&#39;&gt;vm&lt;/span&gt;&lt;span class=&#39;o&#39;&gt;.&lt;/span&gt;&lt;span class=&#39;n&#39;&gt;box&lt;/span&gt; &lt;span class=&#39;o&#39;&gt;=&lt;/span&gt; &lt;span class=&#39;s2&#39;&gt;&amp;quot;centos_6_3_x86_64&amp;quot;&lt;/span&gt;
  &lt;span class=&#39;n&#39;&gt;config&lt;/span&gt;&lt;span class=&#39;o&#39;&gt;.&lt;/span&gt;&lt;span class=&#39;n&#39;&gt;vm&lt;/span&gt;&lt;span class=&#39;o&#39;&gt;.&lt;/span&gt;&lt;span class=&#39;n&#39;&gt;box_url&lt;/span&gt; &lt;span class=&#39;o&#39;&gt;=&lt;/span&gt; &lt;span class=&#39;s2&#39;&gt;&amp;quot;http://files.vagrantup.com/precise64.box&amp;quot;&lt;/span&gt;

  &lt;span class=&#39;n&#39;&gt;config&lt;/span&gt;&lt;span class=&#39;o&#39;&gt;.&lt;/span&gt;&lt;span class=&#39;n&#39;&gt;vm&lt;/span&gt;&lt;span class=&#39;o&#39;&gt;.&lt;/span&gt;&lt;span class=&#39;n&#39;&gt;synced_folder&lt;/span&gt; &lt;span class=&#39;s2&#39;&gt;&amp;quot;.&amp;quot;&lt;/span&gt;&lt;span class=&#39;p&#39;&gt;,&lt;/span&gt; &lt;span class=&#39;s2&#39;&gt;&amp;quot;/vagrant&amp;quot;&lt;/span&gt;

  &lt;span class=&#39;n&#39;&gt;config&lt;/span&gt;&lt;span class=&#39;o&#39;&gt;.&lt;/span&gt;&lt;span class=&#39;n&#39;&gt;vm&lt;/span&gt;&lt;span class=&#39;o&#39;&gt;.&lt;/span&gt;&lt;span class=&#39;n&#39;&gt;provider&lt;/span&gt; &lt;span class=&#39;s2&#39;&gt;&amp;quot;virtualbox&amp;quot;&lt;/span&gt; &lt;span class=&#39;k&#39;&gt;do&lt;/span&gt; &lt;span class=&#39;o&#39;&gt;|&lt;/span&gt;&lt;span class=&#39;n&#39;&gt;v&lt;/span&gt;&lt;span class=&#39;o&#39;&gt;|&lt;/span&gt;
    &lt;span class=&#39;n&#39;&gt;v&lt;/span&gt;&lt;span class=&#39;o&#39;&gt;.&lt;/span&gt;&lt;span class=&#39;n&#39;&gt;customize&lt;/span&gt; &lt;span class=&#39;o&#39;&gt;[&lt;/span&gt;&lt;span class=&#39;s2&#39;&gt;&amp;quot;modifyvm&amp;quot;&lt;/span&gt;&lt;span class=&#39;p&#39;&gt;,&lt;/span&gt; &lt;span class=&#39;ss&#39;&gt;:id&lt;/span&gt;&lt;span class=&#39;p&#39;&gt;,&lt;/span&gt; &lt;span class=&#39;s2&#39;&gt;&amp;quot;--cpus&amp;quot;&lt;/span&gt;&lt;span class=&#39;p&#39;&gt;,&lt;/span&gt; &lt;span class=&#39;s2&#39;&gt;&amp;quot;1&amp;quot;&lt;/span&gt;&lt;span class=&#39;p&#39;&gt;,&lt;/span&gt; &lt;span class=&#39;s2&#39;&gt;&amp;quot;--memory&amp;quot;&lt;/span&gt;&lt;span class=&#39;p&#39;&gt;,&lt;/span&gt; &lt;span class=&#39;s2&#39;&gt;&amp;quot;512&amp;quot;&lt;/span&gt;&lt;span class=&#39;o&#39;&gt;]&lt;/span&gt;
  &lt;span class=&#39;k&#39;&gt;end&lt;/span&gt;

  &lt;span class=&#39;n&#39;&gt;config&lt;/span&gt;&lt;span class=&#39;o&#39;&gt;.&lt;/span&gt;&lt;span class=&#39;n&#39;&gt;vm&lt;/span&gt;&lt;span class=&#39;o&#39;&gt;.&lt;/span&gt;&lt;span class=&#39;n&#39;&gt;define&lt;/span&gt; &lt;span class=&#39;s2&#39;&gt;&amp;quot;hadoop_master&amp;quot;&lt;/span&gt; &lt;span class=&#39;k&#39;&gt;do&lt;/span&gt; &lt;span class=&#39;o&#39;&gt;|&lt;/span&gt;&lt;span class=&#39;n&#39;&gt;hadoop_master&lt;/span&gt;&lt;span class=&#39;o&#39;&gt;|&lt;/span&gt;
    &lt;span class=&#39;n&#39;&gt;hadoop_master&lt;/span&gt;&lt;span class=&#39;o&#39;&gt;.&lt;/span&gt;&lt;span class=&#39;n&#39;&gt;vm&lt;/span&gt;&lt;span class=&#39;o&#39;&gt;.&lt;/span&gt;&lt;span class=&#39;n&#39;&gt;network&lt;/span&gt; &lt;span class=&#39;s2&#39;&gt;&amp;quot;private_network&amp;quot;&lt;/span&gt;&lt;span class=&#39;p&#39;&gt;,&lt;/span&gt; &lt;span class=&#39;ss&#39;&gt;ip&lt;/span&gt;&lt;span class=&#39;p&#39;&gt;:&lt;/span&gt; &lt;span class=&#39;s2&#39;&gt;&amp;quot;192.168.50.4&amp;quot;&lt;/span&gt;
    &lt;span class=&#39;n&#39;&gt;hadoop_master&lt;/span&gt;&lt;span class=&#39;o&#39;&gt;.&lt;/span&gt;&lt;span class=&#39;n&#39;&gt;vm&lt;/span&gt;&lt;span class=&#39;o&#39;&gt;.&lt;/span&gt;&lt;span class=&#39;n&#39;&gt;hostname&lt;/span&gt; &lt;span class=&#39;o&#39;&gt;=&lt;/span&gt; &lt;span class=&#39;s2&#39;&gt;&amp;quot;master.internal&amp;quot;&lt;/span&gt;
  &lt;span class=&#39;k&#39;&gt;end&lt;/span&gt;

  &lt;span class=&#39;n&#39;&gt;config&lt;/span&gt;&lt;span class=&#39;o&#39;&gt;.&lt;/span&gt;&lt;span class=&#39;n&#39;&gt;vm&lt;/span&gt;&lt;span class=&#39;o&#39;&gt;.&lt;/span&gt;&lt;span class=&#39;n&#39;&gt;define&lt;/span&gt; &lt;span class=&#39;s2&#39;&gt;&amp;quot;hadoop_slave1&amp;quot;&lt;/span&gt; &lt;span class=&#39;k&#39;&gt;do&lt;/span&gt; &lt;span class=&#39;o&#39;&gt;|&lt;/span&gt;&lt;span class=&#39;n&#39;&gt;hadoop_slave1&lt;/span&gt;&lt;span class=&#39;o&#39;&gt;|&lt;/span&gt;
    &lt;span class=&#39;n&#39;&gt;hadoop_slave1&lt;/span&gt;&lt;span class=&#39;o&#39;&gt;.&lt;/span&gt;&lt;span class=&#39;n&#39;&gt;vm&lt;/span&gt;&lt;span class=&#39;o&#39;&gt;.&lt;/span&gt;&lt;span class=&#39;n&#39;&gt;network&lt;/span&gt; &lt;span class=&#39;s2&#39;&gt;&amp;quot;private_network&amp;quot;&lt;/span&gt;&lt;span class=&#39;p&#39;&gt;,&lt;/span&gt; &lt;span class=&#39;ss&#39;&gt;ip&lt;/span&gt;&lt;span class=&#39;p&#39;&gt;:&lt;/span&gt; &lt;span class=&#39;s2&#39;&gt;&amp;quot;192.168.50.5&amp;quot;&lt;/span&gt;
    &lt;span class=&#39;n&#39;&gt;hadoop_slave1&lt;/span&gt;&lt;span class=&#39;o&#39;&gt;.&lt;/span&gt;&lt;span class=&#39;n&#39;&gt;vm&lt;/span&gt;&lt;span class=&#39;o&#39;&gt;.&lt;/span&gt;&lt;span class=&#39;n&#39;&gt;hostname&lt;/span&gt; &lt;span class=&#39;o&#39;&gt;=&lt;/span&gt; &lt;span class=&#39;s2&#39;&gt;&amp;quot;slave1.internal&amp;quot;&lt;/span&gt;
  &lt;span class=&#39;k&#39;&gt;end&lt;/span&gt;

  &lt;span class=&#39;n&#39;&gt;config&lt;/span&gt;&lt;span class=&#39;o&#39;&gt;.&lt;/span&gt;&lt;span class=&#39;n&#39;&gt;vm&lt;/span&gt;&lt;span class=&#39;o&#39;&gt;.&lt;/span&gt;&lt;span class=&#39;n&#39;&gt;define&lt;/span&gt; &lt;span class=&#39;s2&#39;&gt;&amp;quot;hadoop_slave2&amp;quot;&lt;/span&gt; &lt;span class=&#39;k&#39;&gt;do&lt;/span&gt; &lt;span class=&#39;o&#39;&gt;|&lt;/span&gt;&lt;span class=&#39;n&#39;&gt;hadoop_slave2&lt;/span&gt;&lt;span class=&#39;o&#39;&gt;|&lt;/span&gt;
    &lt;span class=&#39;n&#39;&gt;hadoop_slave2&lt;/span&gt;&lt;span class=&#39;o&#39;&gt;.&lt;/span&gt;&lt;span class=&#39;n&#39;&gt;vm&lt;/span&gt;&lt;span class=&#39;o&#39;&gt;.&lt;/span&gt;&lt;span class=&#39;n&#39;&gt;network&lt;/span&gt; &lt;span class=&#39;s2&#39;&gt;&amp;quot;private_network&amp;quot;&lt;/span&gt;&lt;span class=&#39;p&#39;&gt;,&lt;/span&gt; &lt;span class=&#39;ss&#39;&gt;ip&lt;/span&gt;&lt;span class=&#39;p&#39;&gt;:&lt;/span&gt; &lt;span class=&#39;s2&#39;&gt;&amp;quot;192.168.50.6&amp;quot;&lt;/span&gt;
    &lt;span class=&#39;n&#39;&gt;hadoop_slave2&lt;/span&gt;&lt;span class=&#39;o&#39;&gt;.&lt;/span&gt;&lt;span class=&#39;n&#39;&gt;vm&lt;/span&gt;&lt;span class=&#39;o&#39;&gt;.&lt;/span&gt;&lt;span class=&#39;n&#39;&gt;hostname&lt;/span&gt; &lt;span class=&#39;o&#39;&gt;=&lt;/span&gt; &lt;span class=&#39;s2&#39;&gt;&amp;quot;slave2.internal&amp;quot;&lt;/span&gt;
    
    &lt;span class=&#39;n&#39;&gt;hadoop_slave2&lt;/span&gt;&lt;span class=&#39;o&#39;&gt;.&lt;/span&gt;&lt;span class=&#39;n&#39;&gt;vm&lt;/span&gt;&lt;span class=&#39;o&#39;&gt;.&lt;/span&gt;&lt;span class=&#39;n&#39;&gt;provision&lt;/span&gt; &lt;span class=&#39;ss&#39;&gt;:ansible&lt;/span&gt; &lt;span class=&#39;k&#39;&gt;do&lt;/span&gt; &lt;span class=&#39;o&#39;&gt;|&lt;/span&gt;&lt;span class=&#39;n&#39;&gt;ansible&lt;/span&gt;&lt;span class=&#39;o&#39;&gt;|&lt;/span&gt;
      &lt;span class=&#39;n&#39;&gt;ansible&lt;/span&gt;&lt;span class=&#39;o&#39;&gt;.&lt;/span&gt;&lt;span class=&#39;n&#39;&gt;inventory_path&lt;/span&gt; &lt;span class=&#39;o&#39;&gt;=&lt;/span&gt; &lt;span class=&#39;s2&#39;&gt;&amp;quot;inventory&amp;quot;&lt;/span&gt;
      &lt;span class=&#39;n&#39;&gt;ansible&lt;/span&gt;&lt;span class=&#39;o&#39;&gt;.&lt;/span&gt;&lt;span class=&#39;n&#39;&gt;verbose&lt;/span&gt; &lt;span class=&#39;o&#39;&gt;=&lt;/span&gt; &lt;span class=&#39;s2&#39;&gt;&amp;quot;v&amp;quot;&lt;/span&gt;
      &lt;span class=&#39;n&#39;&gt;ansible&lt;/span&gt;&lt;span class=&#39;o&#39;&gt;.&lt;/span&gt;&lt;span class=&#39;n&#39;&gt;sudo&lt;/span&gt; &lt;span class=&#39;o&#39;&gt;=&lt;/span&gt; &lt;span class=&#39;kp&#39;&gt;true&lt;/span&gt;
      &lt;span class=&#39;n&#39;&gt;ansible&lt;/span&gt;&lt;span class=&#39;o&#39;&gt;.&lt;/span&gt;&lt;span class=&#39;n&#39;&gt;playbook&lt;/span&gt; &lt;span class=&#39;o&#39;&gt;=&lt;/span&gt; &lt;span class=&#39;s2&#39;&gt;&amp;quot;ansible-examples-master/hadoop/site.yml&amp;quot;&lt;/span&gt;
    &lt;span class=&#39;k&#39;&gt;end&lt;/span&gt;
  &lt;span class=&#39;k&#39;&gt;end&lt;/span&gt;
&lt;span class=&#39;k&#39;&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;We are going to provision a simple Hadoop cluster, without HA configuration, which will consist of one master node and 2 slave nodes.&lt;/p&gt;

&lt;p&gt;I limited the VM resources to 1 cpu and 512MB ram per each VM, since I didn&amp;#8217;t want this environment to interfere with other stuff I am running on my laptop:&lt;/p&gt;
&lt;div class=&#39;highlight&#39;&gt;&lt;pre&gt;&lt;code class=&#39;ruby&#39;&gt;&lt;span class=&#39;n&#39;&gt;config&lt;/span&gt;&lt;span class=&#39;o&#39;&gt;.&lt;/span&gt;&lt;span class=&#39;n&#39;&gt;vm&lt;/span&gt;&lt;span class=&#39;o&#39;&gt;.&lt;/span&gt;&lt;span class=&#39;n&#39;&gt;provider&lt;/span&gt; &lt;span class=&#39;s2&#39;&gt;&amp;quot;virtualbox&amp;quot;&lt;/span&gt; &lt;span class=&#39;k&#39;&gt;do&lt;/span&gt; &lt;span class=&#39;o&#39;&gt;|&lt;/span&gt;&lt;span class=&#39;n&#39;&gt;v&lt;/span&gt;&lt;span class=&#39;o&#39;&gt;|&lt;/span&gt;
  &lt;span class=&#39;n&#39;&gt;v&lt;/span&gt;&lt;span class=&#39;o&#39;&gt;.&lt;/span&gt;&lt;span class=&#39;n&#39;&gt;customize&lt;/span&gt; &lt;span class=&#39;o&#39;&gt;[&lt;/span&gt;&lt;span class=&#39;s2&#39;&gt;&amp;quot;modifyvm&amp;quot;&lt;/span&gt;&lt;span class=&#39;p&#39;&gt;,&lt;/span&gt; &lt;span class=&#39;ss&#39;&gt;:id&lt;/span&gt;&lt;span class=&#39;p&#39;&gt;,&lt;/span&gt; &lt;span class=&#39;s2&#39;&gt;&amp;quot;--cpus&amp;quot;&lt;/span&gt;&lt;span class=&#39;p&#39;&gt;,&lt;/span&gt; &lt;span class=&#39;s2&#39;&gt;&amp;quot;1&amp;quot;&lt;/span&gt;&lt;span class=&#39;p&#39;&gt;,&lt;/span&gt; &lt;span class=&#39;s2&#39;&gt;&amp;quot;--memory&amp;quot;&lt;/span&gt;&lt;span class=&#39;p&#39;&gt;,&lt;/span&gt; &lt;span class=&#39;s2&#39;&gt;&amp;quot;512&amp;quot;&lt;/span&gt;&lt;span class=&#39;o&#39;&gt;]&lt;/span&gt;
&lt;span class=&#39;k&#39;&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Also, I configured 3 VM instances which will be provisioned and managed by Vagrant. I assigned ip addresses and hostnames to each VM, which will be very handy later.&lt;/p&gt;
&lt;div class=&#39;highlight&#39;&gt;&lt;pre&gt;&lt;code class=&#39;ruby&#39;&gt;&lt;span class=&#39;n&#39;&gt;config&lt;/span&gt;&lt;span class=&#39;o&#39;&gt;.&lt;/span&gt;&lt;span class=&#39;n&#39;&gt;vm&lt;/span&gt;&lt;span class=&#39;o&#39;&gt;.&lt;/span&gt;&lt;span class=&#39;n&#39;&gt;define&lt;/span&gt; &lt;span class=&#39;s2&#39;&gt;&amp;quot;hadoop_master&amp;quot;&lt;/span&gt; &lt;span class=&#39;k&#39;&gt;do&lt;/span&gt; &lt;span class=&#39;o&#39;&gt;|&lt;/span&gt;&lt;span class=&#39;n&#39;&gt;hadoop_master&lt;/span&gt;&lt;span class=&#39;o&#39;&gt;|&lt;/span&gt;
  &lt;span class=&#39;n&#39;&gt;hadoop_master&lt;/span&gt;&lt;span class=&#39;o&#39;&gt;.&lt;/span&gt;&lt;span class=&#39;n&#39;&gt;vm&lt;/span&gt;&lt;span class=&#39;o&#39;&gt;.&lt;/span&gt;&lt;span class=&#39;n&#39;&gt;network&lt;/span&gt; &lt;span class=&#39;s2&#39;&gt;&amp;quot;private_network&amp;quot;&lt;/span&gt;&lt;span class=&#39;p&#39;&gt;,&lt;/span&gt; &lt;span class=&#39;ss&#39;&gt;ip&lt;/span&gt;&lt;span class=&#39;p&#39;&gt;:&lt;/span&gt; &lt;span class=&#39;s2&#39;&gt;&amp;quot;192.168.50.4&amp;quot;&lt;/span&gt;
  &lt;span class=&#39;n&#39;&gt;hadoop_master&lt;/span&gt;&lt;span class=&#39;o&#39;&gt;.&lt;/span&gt;&lt;span class=&#39;n&#39;&gt;vm&lt;/span&gt;&lt;span class=&#39;o&#39;&gt;.&lt;/span&gt;&lt;span class=&#39;n&#39;&gt;hostname&lt;/span&gt; &lt;span class=&#39;o&#39;&gt;=&lt;/span&gt; &lt;span class=&#39;s2&#39;&gt;&amp;quot;master.internal&amp;quot;&lt;/span&gt;
&lt;span class=&#39;k&#39;&gt;end&lt;/span&gt;

&lt;span class=&#39;n&#39;&gt;config&lt;/span&gt;&lt;span class=&#39;o&#39;&gt;.&lt;/span&gt;&lt;span class=&#39;n&#39;&gt;vm&lt;/span&gt;&lt;span class=&#39;o&#39;&gt;.&lt;/span&gt;&lt;span class=&#39;n&#39;&gt;define&lt;/span&gt; &lt;span class=&#39;s2&#39;&gt;&amp;quot;hadoop_slave1&amp;quot;&lt;/span&gt; &lt;span class=&#39;k&#39;&gt;do&lt;/span&gt; &lt;span class=&#39;o&#39;&gt;|&lt;/span&gt;&lt;span class=&#39;n&#39;&gt;hadoop_slave1&lt;/span&gt;&lt;span class=&#39;o&#39;&gt;|&lt;/span&gt;
  &lt;span class=&#39;n&#39;&gt;hadoop_slave1&lt;/span&gt;&lt;span class=&#39;o&#39;&gt;.&lt;/span&gt;&lt;span class=&#39;n&#39;&gt;vm&lt;/span&gt;&lt;span class=&#39;o&#39;&gt;.&lt;/span&gt;&lt;span class=&#39;n&#39;&gt;network&lt;/span&gt; &lt;span class=&#39;s2&#39;&gt;&amp;quot;private_network&amp;quot;&lt;/span&gt;&lt;span class=&#39;p&#39;&gt;,&lt;/span&gt; &lt;span class=&#39;ss&#39;&gt;ip&lt;/span&gt;&lt;span class=&#39;p&#39;&gt;:&lt;/span&gt; &lt;span class=&#39;s2&#39;&gt;&amp;quot;192.168.50.5&amp;quot;&lt;/span&gt;
  &lt;span class=&#39;n&#39;&gt;hadoop_slave1&lt;/span&gt;&lt;span class=&#39;o&#39;&gt;.&lt;/span&gt;&lt;span class=&#39;n&#39;&gt;vm&lt;/span&gt;&lt;span class=&#39;o&#39;&gt;.&lt;/span&gt;&lt;span class=&#39;n&#39;&gt;hostname&lt;/span&gt; &lt;span class=&#39;o&#39;&gt;=&lt;/span&gt; &lt;span class=&#39;s2&#39;&gt;&amp;quot;slave1.internal&amp;quot;&lt;/span&gt;
&lt;span class=&#39;k&#39;&gt;end&lt;/span&gt;

&lt;span class=&#39;n&#39;&gt;config&lt;/span&gt;&lt;span class=&#39;o&#39;&gt;.&lt;/span&gt;&lt;span class=&#39;n&#39;&gt;vm&lt;/span&gt;&lt;span class=&#39;o&#39;&gt;.&lt;/span&gt;&lt;span class=&#39;n&#39;&gt;define&lt;/span&gt; &lt;span class=&#39;s2&#39;&gt;&amp;quot;hadoop_slave2&amp;quot;&lt;/span&gt; &lt;span class=&#39;k&#39;&gt;do&lt;/span&gt; &lt;span class=&#39;o&#39;&gt;|&lt;/span&gt;&lt;span class=&#39;n&#39;&gt;hadoop_slave2&lt;/span&gt;&lt;span class=&#39;o&#39;&gt;|&lt;/span&gt;
  &lt;span class=&#39;n&#39;&gt;hadoop_slave2&lt;/span&gt;&lt;span class=&#39;o&#39;&gt;.&lt;/span&gt;&lt;span class=&#39;n&#39;&gt;vm&lt;/span&gt;&lt;span class=&#39;o&#39;&gt;.&lt;/span&gt;&lt;span class=&#39;n&#39;&gt;network&lt;/span&gt; &lt;span class=&#39;s2&#39;&gt;&amp;quot;private_network&amp;quot;&lt;/span&gt;&lt;span class=&#39;p&#39;&gt;,&lt;/span&gt; &lt;span class=&#39;ss&#39;&gt;ip&lt;/span&gt;&lt;span class=&#39;p&#39;&gt;:&lt;/span&gt; &lt;span class=&#39;s2&#39;&gt;&amp;quot;192.168.50.6&amp;quot;&lt;/span&gt;
  &lt;span class=&#39;n&#39;&gt;hadoop_slave2&lt;/span&gt;&lt;span class=&#39;o&#39;&gt;.&lt;/span&gt;&lt;span class=&#39;n&#39;&gt;vm&lt;/span&gt;&lt;span class=&#39;o&#39;&gt;.&lt;/span&gt;&lt;span class=&#39;n&#39;&gt;hostname&lt;/span&gt; &lt;span class=&#39;o&#39;&gt;=&lt;/span&gt; &lt;span class=&#39;s2&#39;&gt;&amp;quot;slave2.internal&amp;quot;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;I assigned the Ansible provisioner to the last VM not by chance, this step is actually very important. In Vagrant, in a multi-vm configuration, VM machines will be started according to their declaration order. I used that knowledge to my advantage, in order to make sure that the provisioning process will be executed only after all the VMs are up and running.&lt;/p&gt;

&lt;p&gt;Why it is important? because otherwise Ansible will fail, since it will try to connect to some not-yet-created machines. This technique (others will call it a hack) is described in more detail &lt;a href=&#39;https://github.com/mitchellh/vagrant/issues/1784&#39;&gt;in this github issue&lt;/a&gt;&lt;/p&gt;
&lt;div class=&#39;highlight&#39;&gt;&lt;pre&gt;&lt;code class=&#39;ruby&#39;&gt;&lt;span class=&#39;n&#39;&gt;hadoop_slave2&lt;/span&gt;&lt;span class=&#39;o&#39;&gt;.&lt;/span&gt;&lt;span class=&#39;n&#39;&gt;vm&lt;/span&gt;&lt;span class=&#39;o&#39;&gt;.&lt;/span&gt;&lt;span class=&#39;n&#39;&gt;provision&lt;/span&gt; &lt;span class=&#39;ss&#39;&gt;:ansible&lt;/span&gt; &lt;span class=&#39;k&#39;&gt;do&lt;/span&gt; &lt;span class=&#39;o&#39;&gt;|&lt;/span&gt;&lt;span class=&#39;n&#39;&gt;ansible&lt;/span&gt;&lt;span class=&#39;o&#39;&gt;|&lt;/span&gt;
  &lt;span class=&#39;n&#39;&gt;ansible&lt;/span&gt;&lt;span class=&#39;o&#39;&gt;.&lt;/span&gt;&lt;span class=&#39;n&#39;&gt;inventory_path&lt;/span&gt; &lt;span class=&#39;o&#39;&gt;=&lt;/span&gt; &lt;span class=&#39;s2&#39;&gt;&amp;quot;inventory&amp;quot;&lt;/span&gt;
  &lt;span class=&#39;n&#39;&gt;ansible&lt;/span&gt;&lt;span class=&#39;o&#39;&gt;.&lt;/span&gt;&lt;span class=&#39;n&#39;&gt;verbose&lt;/span&gt; &lt;span class=&#39;o&#39;&gt;=&lt;/span&gt; &lt;span class=&#39;s2&#39;&gt;&amp;quot;v&amp;quot;&lt;/span&gt;
  &lt;span class=&#39;n&#39;&gt;ansible&lt;/span&gt;&lt;span class=&#39;o&#39;&gt;.&lt;/span&gt;&lt;span class=&#39;n&#39;&gt;sudo&lt;/span&gt; &lt;span class=&#39;o&#39;&gt;=&lt;/span&gt; &lt;span class=&#39;kp&#39;&gt;true&lt;/span&gt;
  &lt;span class=&#39;n&#39;&gt;ansible&lt;/span&gt;&lt;span class=&#39;o&#39;&gt;.&lt;/span&gt;&lt;span class=&#39;n&#39;&gt;playbook&lt;/span&gt; &lt;span class=&#39;o&#39;&gt;=&lt;/span&gt; &lt;span class=&#39;s2&#39;&gt;&amp;quot;ansible-examples-master/hadoop/site.yml&amp;quot;&lt;/span&gt;
&lt;span class=&#39;k&#39;&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&#39;ansible&#39;&gt;Ansible&lt;/h2&gt;

&lt;p&gt;I am not willing to dive deep into Ansible, but it is important to note it&amp;#8217;s 2 main configuration files: Ansibles &lt;strong&gt;inventory&lt;/strong&gt; and &lt;strong&gt;playbook.yml&lt;/strong&gt; files.&lt;/p&gt;

&lt;p&gt;The inventory file defines which machines will be managed by Ansible and which groups these machines are assigned to (and by group assignment you actually telling which roles should be assigned to these nodes). I think that it is a very powerful concept, which as everything else in Ansible, is implemented radically simpler than in Puppet. You can find more information about the inventory file &lt;a href=&#39;http://www.ansibleworks.com/docs/intro_inventory.html&#39;&gt;here&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Here is the content of the inventory file I used:&lt;/p&gt;
&lt;div class=&#39;highlight&#39;&gt;&lt;pre&gt;&lt;code class=&#39;ini&#39;&gt;&lt;span class=&#39;k&#39;&gt;[hadoop_all:children]&lt;/span&gt;
&lt;span class=&#39;err&#39;&gt;hadoop_masters&lt;/span&gt;
&lt;span class=&#39;err&#39;&gt;hadoop_slaves&lt;/span&gt;

&lt;span class=&#39;k&#39;&gt;[hadoop_master_primary]&lt;/span&gt;
&lt;span class=&#39;na&#39;&gt;master.internal ansible_ssh_host&lt;/span&gt;&lt;span class=&#39;o&#39;&gt;=&lt;/span&gt;&lt;span class=&#39;s&#39;&gt;192.168.50.4&lt;/span&gt;

&lt;span class=&#39;k&#39;&gt;[hadoop_master_secondary]&lt;/span&gt;

&lt;span class=&#39;k&#39;&gt;[hadoop_masters:children]&lt;/span&gt;
&lt;span class=&#39;err&#39;&gt;hadoop_master_primary&lt;/span&gt;
&lt;span class=&#39;err&#39;&gt;hadoop_master_secondary&lt;/span&gt;

&lt;span class=&#39;k&#39;&gt;[hadoop_slaves]&lt;/span&gt;
&lt;span class=&#39;na&#39;&gt;slave1.internal ansible_ssh_host&lt;/span&gt;&lt;span class=&#39;o&#39;&gt;=&lt;/span&gt;&lt;span class=&#39;s&#39;&gt;192.168.50.5&lt;/span&gt;
&lt;span class=&#39;na&#39;&gt;slave2.internal ansible_ssh_host&lt;/span&gt;&lt;span class=&#39;o&#39;&gt;=&lt;/span&gt;&lt;span class=&#39;s&#39;&gt;192.168.50.6&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Another important file is the playbook yml file. I used the default site.yml (&lt;code&gt;ansible-examples-master/hadoop/site.yml&lt;/code&gt;) which comes with the example repository. It is easier to view this file as the starting point of the whole provisioning process, and Ansible&amp;#8217;s execution process starts from there.&lt;/p&gt;

&lt;h2 id=&#39;adjusting_hadoop_playbooks&#39;&gt;Adjusting Hadoop playbooks&lt;/h2&gt;

&lt;p&gt;I think I never had a chance to download a community playbook/module/cookbook that worked from the first run, and Ansible&amp;#8217;s hadoop playbooks aren&amp;#8217;t an exception. In order to make them work with our setup, we need to adjust a bit the default configuration.&lt;/p&gt;

&lt;p&gt;First of all, we will needed to install the &lt;code&gt;libselinux-python&lt;/code&gt; as a prerequisite for the selinux module to work. To do that add the following line to the &lt;code&gt;ansible-examples-master/hadoop/roles/common/tasks/common.yml&lt;/code&gt; file:&lt;/p&gt;
&lt;div class=&#39;highlight&#39;&gt;&lt;pre&gt;&lt;code class=&#39;yaml&#39;&gt;&lt;span class=&#39;p-Indicator&#39;&gt;-&lt;/span&gt; &lt;span class=&#39;l-Scalar-Plain&#39;&gt;name&lt;/span&gt;&lt;span class=&#39;p-Indicator&#39;&gt;:&lt;/span&gt; &lt;span class=&#39;l-Scalar-Plain&#39;&gt;Install SElinux ansible module dependencies&lt;/span&gt;
  &lt;span class=&#39;l-Scalar-Plain&#39;&gt;yum&lt;/span&gt;&lt;span class=&#39;p-Indicator&#39;&gt;:&lt;/span&gt; &lt;span class=&#39;l-Scalar-Plain&#39;&gt;name=libselinux-python state=installed&lt;/span&gt;
&lt;span class=&#39;p-Indicator&#39;&gt;-&lt;/span&gt; &lt;span class=&#39;l-Scalar-Plain&#39;&gt;name&lt;/span&gt;&lt;span class=&#39;p-Indicator&#39;&gt;:&lt;/span&gt; &lt;span class=&#39;l-Scalar-Plain&#39;&gt;Disable SELinux in conf file&lt;/span&gt;
  &lt;span class=&#39;l-Scalar-Plain&#39;&gt;selinux&lt;/span&gt;&lt;span class=&#39;p-Indicator&#39;&gt;:&lt;/span&gt; &lt;span class=&#39;l-Scalar-Plain&#39;&gt;state=disabled&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Secondly, by default, the example playbooks create the &lt;code&gt;/etc/hosts&lt;/code&gt; file on all the VM&amp;#8217;s with the internal ip. In order that all our VM&amp;#8217;s will be able to communicate with each other, we will change the default parameters to use the extermal ip instead. To do so, change the following line in the &lt;code&gt;ansible-examples-master/hadoop/group_vars/all&lt;/code&gt; file:&lt;/p&gt;
&lt;div class=&#39;highlight&#39;&gt;&lt;pre&gt;&lt;code class=&#39;yaml&#39;&gt;&lt;span class=&#39;l-Scalar-Plain&#39;&gt;iface&lt;/span&gt;&lt;span class=&#39;p-Indicator&#39;&gt;:&lt;/span&gt; &lt;span class=&#39;l-Scalar-Plain&#39;&gt;eth1&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;And as our last change for today, we will needed to explicitly set the permissions of hadoop configuration to 644 in order to make sure we won&amp;#8217;t fail on permissions during the provisioning. Let&amp;#8217;s do so, by adding the &lt;code&gt;mode=644&lt;/code&gt; line to &lt;code&gt;ansible-examples-master/hadoop/roles/hadoop_primary/tasks/hadoop_master_no_ha.yml&lt;/code&gt; file:&lt;/p&gt;
&lt;div class=&#39;highlight&#39;&gt;&lt;pre&gt;&lt;code class=&#39;yaml&#39;&gt;&lt;span class=&#39;p-Indicator&#39;&gt;-&lt;/span&gt; &lt;span class=&#39;l-Scalar-Plain&#39;&gt;name&lt;/span&gt;&lt;span class=&#39;p-Indicator&#39;&gt;:&lt;/span&gt; &lt;span class=&#39;l-Scalar-Plain&#39;&gt;Copy the hadoop configuration files for no ha&lt;/span&gt;
  &lt;span class=&#39;l-Scalar-Plain&#39;&gt;template&lt;/span&gt;&lt;span class=&#39;p-Indicator&#39;&gt;:&lt;/span&gt; &lt;span class=&#39;l-Scalar-Plain&#39;&gt;src=roles/common/templates/hadoop_conf/.j2 dest=/etc/hadoop/conf/ mode=644&lt;/span&gt;
  &lt;span class=&#39;l-Scalar-Plain&#39;&gt;with_items&lt;/span&gt;&lt;span class=&#39;p-Indicator&#39;&gt;:&lt;/span&gt; 
   &lt;span class=&#39;p-Indicator&#39;&gt;-&lt;/span&gt; &lt;span class=&#39;l-Scalar-Plain&#39;&gt;core-site.xml&lt;/span&gt;
   &lt;span class=&#39;p-Indicator&#39;&gt;-&lt;/span&gt; &lt;span class=&#39;l-Scalar-Plain&#39;&gt;hadoop-metrics.properties&lt;/span&gt;
   &lt;span class=&#39;p-Indicator&#39;&gt;-&lt;/span&gt; &lt;span class=&#39;l-Scalar-Plain&#39;&gt;hadoop-metrics2.properties&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&#39;run&#39;&gt;Run!&lt;/h2&gt;

&lt;p&gt;Finally everything is ready for launch! Now just hit &lt;code&gt;vagrant up&lt;/code&gt; at the command line, and in about 10 minutes you will have a working hadoop environment.&lt;/p&gt;

&lt;p&gt;Let&amp;#8217;s go another extra mile, and check that our hadoop is working. Review the jobtracker webpage by accessing &lt;code&gt;http:/192.168.50.4:50030/jobtracker.jsp&lt;/code&gt; in your browser. It should show up some basic jobtracker stats.&lt;/p&gt;

&lt;p&gt;For a more elaborate use of our environment, you will need to adjust the playbooks even more. For example, you will probably need to create the mapred directories. Since Ansible is so easy to start with, I am sure that you will be able to catch up easily, and to complete these extra steps without a hassle.&lt;/p&gt;

&lt;h2 id=&#39;summary&#39;&gt;Summary&lt;/h2&gt;

&lt;p&gt;My first impression of Ansible is quite positive, I can tell that it is much easier to start using this tool than puppet, and actually it seems quite powerful. I will need to test it in a production scenario to see if it will work for a more complex scenarios.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Getting started with MCollective</title>
   <link href="http://leonidmirsky.com/puppet/mcollective/2013/10/08/getting-started-with-mcollective.html"/>
   <updated>2013-10-08T18:31:00Z</updated>
   <id>http://leonidmirsky.com/puppet/mcollective/2013/10/08/getting-started-with-mcollective</id>
   <content type="html">&lt;p&gt;Recently I was working on a simple continuous deployment process for puppet code. The process steps are as follows:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;A new puppet code is pushed to a github repository&lt;/li&gt;

&lt;li&gt;&lt;a href=&#39;http://www.codeship.io&#39;&gt;Codeship.io&lt;/a&gt; service picks the changes, and runs the build&lt;/li&gt;

&lt;li&gt;Using Capistrano (or any other SSH framework), the new code is pushed to puppet servers&lt;/li&gt;

&lt;li&gt;All puppet agents are run immediately to pick up the changes, and re-provision their hosts accordingly&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Although the last step looks trivial, but actually, because of puppet&amp;#8217;s communication module, it isn&amp;#8217;t so easy to do. By default, puppet master can&amp;#8217;t initiate a direct connection to managed agents, so in order to achieve that I decided to give MCollective a try.&lt;/p&gt;
&lt;hr /&gt;
&lt;h2 id=&#39;mcollective_components&#39;&gt;MCollective components&lt;/h2&gt;

&lt;p&gt;&lt;a href=&#39;http://puppetlabs.com/mcollective&#39;&gt;Mcollective&lt;/a&gt; is a framework for building service orchestration on top of puppet regular infrastructure.&lt;/p&gt;

&lt;p&gt;Without going into too much details, MCollective consists of 3 main components:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Server&lt;/strong&gt; - despite it&amp;#8217;s name, it is the agent you are going to install on all your puppet managed nodes. The server daemon will listen to a specified queue for actions, and respond accordingly&lt;/li&gt;

&lt;li&gt;&lt;strong&gt;Client&lt;/strong&gt; - using this component you can fire off your orchestration jobs to all/subset of subscribed nodes (which have the server component configured correctly)&lt;/li&gt;

&lt;li&gt;&lt;strong&gt;Middleware&lt;/strong&gt; - Since MCollective architecture is pub/sub , middleware component is generally a queue, to which you will send jobs using the client, and to which the server will subscribe to listen for new actions.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2 id=&#39;lets_play&#39;&gt;Let&amp;#8217;s play&lt;/h2&gt;

&lt;p&gt;An easy way to start playing around with MCollective is by using a &lt;a href=&#39;https://github.com/ripienaar/mcollective-vagrant&#39;&gt;vagrant ready repository&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;div class=&#39;highlight&#39;&gt;&lt;pre&gt;&lt;code class=&#39;shell-session&#39;&gt;&lt;span class=&#39;gp&#39;&gt;[vagrant@middleware ~]$&lt;/span&gt; git clone https://github.com/ripienaar/mcollective-vagrant.git
&lt;span class=&#39;gp&#39;&gt;[vagrant@middleware ~]$&lt;/span&gt; &lt;span class=&#39;nb&#39;&gt;cd &lt;/span&gt;mcollective-vagrant
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/p&gt;

&lt;p&gt;Edit the Vagrantfile (pay attention to the amount of instances which will be previsioned in addition to the middleware. By default it is 5, and it can be a little bit intensive on some laptops)&lt;/p&gt;

&lt;p&gt;&lt;div class=&#39;highlight&#39;&gt;&lt;pre&gt;&lt;code class=&#39;shell-session&#39;&gt;&lt;span class=&#39;gp&#39;&gt;[vagrant@middleware ~]$&lt;/span&gt; vi Vagrantfile
&lt;span class=&#39;gp&#39;&gt;[vagrant@middleware ~]$&lt;/span&gt; vagrant up
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/p&gt;

&lt;p&gt;After all the VM&amp;#8217;s are up (and it can take a while), connect to the middleware server (since by default the client is installed there), and check that all the nodes are configured correctly&lt;/p&gt;

&lt;p&gt;&lt;div class=&#39;highlight&#39;&gt;&lt;pre&gt;&lt;code class=&#39;shell-session&#39;&gt;&lt;span class=&#39;gp&#39;&gt;[vagrant@middleware ~]$&lt;/span&gt; mco ping
&lt;span class=&#39;go&#39;&gt;node0.example.net                        time=85.38 ms&lt;/span&gt;
&lt;span class=&#39;go&#39;&gt;middleware.example.net                   time=90.15 ms&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/p&gt;

&lt;p&gt;To get all the available information on a specific node run:&lt;/p&gt;

&lt;p&gt;&lt;div class=&#39;highlight&#39;&gt;&lt;pre&gt;&lt;code class=&#39;shell-session&#39;&gt;&lt;span class=&#39;gp&#39;&gt;[vagrant@middleware ~]$&lt;/span&gt; mco inventory node0.example.net
&lt;span class=&#39;go&#39;&gt;Inventory for node0.example.net:&lt;/span&gt;
&lt;span class=&#39;go&#39;&gt; &lt;/span&gt;
&lt;span class=&#39;go&#39;&gt;Agents:&lt;/span&gt;
&lt;span class=&#39;go&#39;&gt;  discovery       filemgr         integration    &lt;/span&gt;
&lt;span class=&#39;go&#39;&gt;  nettest         nrpe            package        &lt;/span&gt;
&lt;span class=&#39;go&#39;&gt;  process         puppet          rpcutil        &lt;/span&gt;
&lt;span class=&#39;go&#39;&gt;  service         urltest                        &lt;/span&gt;
&lt;span class=&#39;go&#39;&gt; &lt;/span&gt;
&lt;span class=&#39;go&#39;&gt;Data Plugins:&lt;/span&gt;
&lt;span class=&#39;go&#39;&gt;  agent           fstat           nettest        &lt;/span&gt;
&lt;span class=&#39;go&#39;&gt;  nrpe            process         puppet         &lt;/span&gt;
&lt;span class=&#39;go&#39;&gt;  resource        service                        &lt;/span&gt;
&lt;span class=&#39;go&#39;&gt; &lt;/span&gt;
&lt;span class=&#39;go&#39;&gt;Configuration Management Classes:&lt;/span&gt;
&lt;span class=&#39;go&#39;&gt;  default                        mcollective                   &lt;/span&gt;
&lt;span class=&#39;go&#39;&gt;  mcollective::agent::filemgr    mcollective::agent::integration&lt;/span&gt;
&lt;span class=&#39;go&#39;&gt;  mcollective::agent::nettest    mcollective::agent::nrpe      &lt;/span&gt;
&lt;span class=&#39;go&#39;&gt;  mcollective::agent::package    mcollective::agent::process   &lt;/span&gt;
&lt;span class=&#39;go&#39;&gt;  mcollective::agent::puppet     mcollective::agent::service   &lt;/span&gt;
&lt;span class=&#39;go&#39;&gt;  mcollective::agent::urltest    mcollective::config           &lt;/span&gt;
&lt;span class=&#39;go&#39;&gt;  mcollective::install           mcollective::service          &lt;/span&gt;
&lt;span class=&#39;go&#39;&gt;  motd                           nagios                        &lt;/span&gt;
&lt;span class=&#39;go&#39;&gt;  nrpe                           nrpe::params                  &lt;/span&gt;
&lt;span class=&#39;go&#39;&gt;  puppet                         repos                         &lt;/span&gt;
&lt;span class=&#39;go&#39;&gt;  roles::node                    settings                      &lt;/span&gt;
&lt;span class=&#39;go&#39;&gt; &lt;/span&gt;
&lt;span class=&#39;go&#39;&gt;Facts:&lt;/span&gt;
&lt;span class=&#39;go&#39;&gt;  architecture =&amp;gt; x86_64&lt;/span&gt;
&lt;span class=&#39;go&#39;&gt;  augeasversion =&amp;gt; 0.9.0&lt;/span&gt;
&lt;span class=&#39;go&#39;&gt;  caller_module_name =&amp;gt; mcollective&lt;/span&gt;
&lt;span class=&#39;go&#39;&gt;  clientcert =&amp;gt; node0.example.net&lt;/span&gt;
&lt;span class=&#39;go&#39;&gt;  clientversion =&amp;gt; 2.7.17&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/p&gt;

&lt;p&gt;The output here is actually very helpful:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You can see all the classes applied to the node (Configuration Management Classes)&lt;/li&gt;

&lt;li&gt;All the node facts, and their values&lt;/li&gt;

&lt;li&gt;The MCollective data plugins and available MCollective agents (for a matter of simplicity, consider them all as MCollective functionality you can request from that node. The original terminology is a bit confusing)&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&#39;filters&#39;&gt;Filters&lt;/h2&gt;

&lt;p&gt;Till now, we were addressing all the managed nodes or a specific server. However usually you would like to communicate with a subset of your environment. For that reason MCollective provides an easy way to define command filters.&lt;/p&gt;

&lt;p&gt;For example, we can see a summary of all the node&amp;#8217;s &lt;strong&gt;rubysitedir&lt;/strong&gt; fact&lt;/p&gt;

&lt;p&gt;&lt;div class=&#39;highlight&#39;&gt;&lt;pre&gt;&lt;code class=&#39;shell-session&#39;&gt;&lt;span class=&#39;gp&#39;&gt;[vagrant@middleware ~]$&lt;/span&gt; mco facts rubysitedir
&lt;span class=&#39;go&#39;&gt;Report for fact: rubysitedir&lt;/span&gt;
&lt;span class=&#39;go&#39;&gt; &lt;/span&gt;
&lt;span class=&#39;go&#39;&gt;        /usr/lib/ruby/site_ruby/1.8             found 2 times&lt;/span&gt;
&lt;span class=&#39;go&#39;&gt;        /usr/lib/ruby/site_ruby/1.9.3           found 1 times&lt;/span&gt;
&lt;span class=&#39;go&#39;&gt; &lt;/span&gt;
&lt;span class=&#39;go&#39;&gt;Finished processing 3 / 3 hosts in 60.00 ms&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/p&gt;

&lt;p&gt;&amp;#8230; and then we can easily filter the nodes with ruby version 1.8&lt;/p&gt;

&lt;p&gt;&lt;div class=&#39;highlight&#39;&gt;&lt;pre&gt;&lt;code class=&#39;shell-session&#39;&gt;&lt;span class=&#39;gp&#39;&gt;[vagrant@middleware ~]$&lt;/span&gt; mco ping -F &lt;span class=&#39;nv&#39;&gt;rubysitedir&lt;/span&gt;&lt;span class=&#39;o&#39;&gt;=&lt;/span&gt;/usr/lib/ruby/site_ruby/1.8
&lt;span class=&#39;go&#39;&gt;node0.example.net                        time=53.12 ms&lt;/span&gt;
&lt;span class=&#39;go&#39;&gt;middleware.example.net                   time=54.14 ms&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/p&gt;

&lt;p&gt;&amp;#8230; or we can query by applied classes (which nodes has nagios class applied to them?)&lt;/p&gt;

&lt;p&gt;&lt;div class=&#39;highlight&#39;&gt;&lt;pre&gt;&lt;code class=&#39;shell-session&#39;&gt;&lt;span class=&#39;gp&#39;&gt;[vagrant@middleware ~]$&lt;/span&gt; mco ping -C nagios
&lt;span class=&#39;go&#39;&gt;node0.example.net                        time=49.30 ms&lt;/span&gt;
&lt;span class=&#39;go&#39;&gt;middleware.example.net                   time=52.98 ms&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/p&gt;

&lt;p&gt;&amp;#8230; also we can combine the filters for a more complex query expression&lt;/p&gt;

&lt;p&gt;&lt;div class=&#39;highlight&#39;&gt;&lt;pre&gt;&lt;code class=&#39;shell-session&#39;&gt;&lt;span class=&#39;gp&#39;&gt;[vagrant@middleware ~]$&lt;/span&gt; mco ping -S &lt;span class=&#39;s2&#39;&gt;&amp;quot;operatingsystem=CentOS and roles::node&amp;quot;&lt;/span&gt;
&lt;span class=&#39;go&#39;&gt;node0.example.net                        time=38.22 ms&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/p&gt;

&lt;h2 id=&#39;plugins&#39;&gt;Plugins&lt;/h2&gt;

&lt;p&gt;Since MCollective is a framework, by performing the default installation you actually will get very limit set of commands. The vagrant repository we were working with till now, already installed some plugins for you, but remember that in production you will need to take care of the plugins installation in addition to the basic MCollective components configuration. You can check out the available community plugins &lt;a href=&#39;http://projects.puppetlabs.com/projects/mcollective-plugins/wiki&#39;&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;For the continuous deployment process I mentioned earlier, I needed the &lt;strong&gt;puppet&lt;/strong&gt; plugin, which provides an easy way to &lt;strong&gt;enable, disable and run puppet daemons&lt;/strong&gt;. For example, to rerun all puppet agents, you can just execute the following command&lt;/p&gt;

&lt;p&gt;&lt;div class=&#39;highlight&#39;&gt;&lt;pre&gt;&lt;code class=&#39;shell-session&#39;&gt;&lt;span class=&#39;gp&#39;&gt;[vagrant@middleware ~]$&lt;/span&gt; mco puppet runonce
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/p&gt;

&lt;h2 id=&#39;conclusion&#39;&gt;Conclusion&lt;/h2&gt;

&lt;p&gt;MCollective isn&amp;#8217;t so intuitive for a beginner, probably because of all the different components terminology and a over complicated documentation. I hope this post will ease a bit the first steps, and make this solid tool more available for a wider audience.&lt;/p&gt;

&lt;p&gt;For advanced MCollective topics, you should review the following sources:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href=&#39;http://www.slideshare.net/PuppetLabs/presentation-16281121&#39;&gt;Great presentation by @repienaar&lt;/a&gt; with lots of useful examples&lt;/li&gt;

&lt;li&gt;&lt;a href=&#39;http://docs.puppetlabs.com/mcollective/overview_components.html&#39;&gt;MCollective architecture review&lt;/a&gt; by puppetlabs&lt;/li&gt;

&lt;li&gt;&lt;a href=&#39;http://docs.puppetlabs.com/mcollective/reference/basic/basic_cli_usage.html&#39;&gt;Additional CLI tricks and examples&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</content>
 </entry>
 
 
</feed>
