<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Kartar.Net &#187; configuration management</title>
	<atom:link href="http://www.kartar.net/tag/configuration-management/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.kartar.net</link>
	<description>the truth about a man lies in what he hides</description>
	<lastBuildDate>Fri, 30 Jul 2010 00:25:22 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.1</generator>
		<item>
		<title>Yes Mum, still behaving</title>
		<link>http://www.kartar.net/2010/04/yes-mum-still-behaving/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=yes-mum-still-behaving</link>
		<comments>http://www.kartar.net/2010/04/yes-mum-still-behaving/#comments</comments>
		<pubDate>Thu, 22 Apr 2010 06:18:29 +0000</pubDate>
		<dc:creator>kartar</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[devops]]></category>
		<category><![CDATA[open source]]></category>
		<category><![CDATA[behavioural driven development]]></category>
		<category><![CDATA[behavioural driven infrastructure]]></category>
		<category><![CDATA[configuration management]]></category>
		<category><![CDATA[cucumber]]></category>
		<category><![CDATA[Nagios]]></category>
		<category><![CDATA[puppet]]></category>
		<category><![CDATA[test driven development]]></category>

		<guid isPermaLink="false">http://www.kartar.net/?p=2130</guid>
		<description><![CDATA[In a previous post I talked about using Cucumber and Cucumber-Nagios to do what I crudely called &#8220;Behaviour Driven Infrastructure&#8221;. In that post I gave you a very brief introduction to Cucumber&#8217;s syntax.  This post explores another piece of syntax called outlining that allows you to shortcut some of your testing scenarios. In the tests [...]]]></description>
			<content:encoded><![CDATA[<p>In <a title="Yes Mum, I'll behave" href="http://www.kartar.net/2009/12/yes-mum-ill-behave-beginning-behaviour-driven-infrastructure/" target="_blank">a previous post</a> I talked about using <a href="http://cukes.info/" target="_blank">Cucumber</a> and <a href="http://holmwood.id.au/~lindsay/2009/02/23/web-app-integration-testing-for-sysadmins-with-cucumber-nagios/" target="_blank">Cucumber-Nagios</a> to do what I crudely called &#8220;Behaviour Driven Infrastructure&#8221;. In that post I gave you a very brief introduction to Cucumber&#8217;s syntax.  This post explores another piece of syntax called outlining that allows you to shortcut some of your testing scenarios.</p>
<p>In the tests we demonstrated you could potentially end up with some quite repetitive scenarios, for example:</p>
<pre>  Scenario: Visiting home page
    When I go to http://www.google.com
    Then the request should succeed</pre>
<p>If we have multiple websites we can end up with repetitive scenarios like:</p>
<pre>  Scenario: Visiting home page
    When I go to http://www.google.com
    Then the request should succeed
  Scenario: Visiting home page
    When I go to http://www.nextsite.com
    Then the request should succeed
  Scenario: Visiting home page
    When I go to http://www.anothersite.com
    Then the request should succeed
</pre>
<p>We can summarise this series of scenarios with a nifty bit of refactoring using some Gherkin (Cucumber&#8217;s <a href="http://www.kartar.net/tag/dsl/" class="st_tag internal_tag" rel="tag" title="Posts tagged with DSL">DSL</a>) syntax called an Outline.  Using an outline we can create a kind of template like so:</p>
<pre>Scenario Outline: Home
  When I go to &lt;url&gt;
  Then the request should succeed
  Examples:
  | url            |
  | http://www.google.com |
  | http://www.nextsite.com |
  | http://www.nextsite.com |
</pre>
<p>Cucumber turns each example—each table row—into a concrete scenario before looking for matching step definitions.  And hey presto when it runs you get:</p>
<pre>
$ bin/cucumber --require features/ features/home/outline.feature
Scenario Outline: Home            # features/home/outline2.feature:1
When I go to &lt;url&gt;              # features/steps/webrat_steps.rb:1
Then the request should succeed # features/steps/result_steps.rb:13

Examples:
| url                     |
| http://www.google.com   |
| http://www.nextsite.com |
| http://www.nextsite.com |

3 scenarios (3 passed)
6 steps (6 passed)
0m3.123s
</pre>
<p><b>Update &#8211; you need cucumber-nagios version 0.7.2 later to use outlines&#8230;</b></p>
]]></content:encoded>
			<wfw:commentRss>http://www.kartar.net/2010/04/yes-mum-still-behaving/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Puppet, Chef, deterministic ordering and the much maligned DSL</title>
		<link>http://www.kartar.net/2010/01/puppet-chef-deterministic-ordering-and-the-much-maligned-dsl/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=puppet-chef-deterministic-ordering-and-the-much-maligned-dsl</link>
		<comments>http://www.kartar.net/2010/01/puppet-chef-deterministic-ordering-and-the-much-maligned-dsl/#comments</comments>
		<pubDate>Thu, 14 Jan 2010 06:20:12 +0000</pubDate>
		<dc:creator>kartar</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[puppet]]></category>
		<category><![CDATA[chef]]></category>
		<category><![CDATA[configuration management]]></category>
		<category><![CDATA[deterministic]]></category>
		<category><![CDATA[DSL]]></category>

		<guid isPermaLink="false">http://www.kartar.net/?p=2166</guid>
		<description><![CDATA[This morning I came across a post entitled Puppet versus Chef: 10 reasons why Puppet wins.  The post attempts to explain the differences between Chef and Puppet and why Puppet is superior.  The post wasn&#8217;t great IMHO, personally I thought it was fairly poorly reasoned and made some, potentially accurate, but throughly unsubstantiated claims. Leaving [...]]]></description>
			<content:encoded><![CDATA[<p>This morning I came across a post entitled <a title="Puppet versus Chef: 10 reasons why Puppet wins" href="http://bitfieldconsulting.com/puppet-vs-chef" target="_self">Puppet versus Chef: 10 reasons why Puppet wins</a>.  The post attempts to explain the differences between <a href="http://www.kartar.net/tag/chef/" class="st_tag internal_tag" rel="tag" title="Posts tagged with chef">Chef</a> and <a href="http://www.kartar.net/tag/puppet/" class="st_tag internal_tag" rel="tag" title="Posts tagged with puppet">Puppet</a> and why <a href="http://www.kartar.net/tag/puppet/" class="st_tag internal_tag" rel="tag" title="Posts tagged with puppet">Puppet</a> is superior.  The post wasn&#8217;t great IMHO, personally I thought it was fairly poorly reasoned and made some, potentially accurate, but throughly unsubstantiated claims.</p>
<p>Leaving aside the issues with the post itself though, it did prompt an interesting comment thread, particularly comments  between <a title="comment from Adam Jacob" href="http://bitfieldconsulting.com/puppet-vs-chef#comment-19" target="_blank">Opcode&#8217;s CTO Adam Jacob</a> and <a title="Teyo Tyree on ordering" href="http://bitfieldconsulting.com/puppet-vs-chef#comment-36" target="_blank">Reductive Lab&#8217;s Teyo Tyree</a> (links are to the respective comments &#8211; Adam&#8217;s and Teyo&#8217;s reply).</p>
<p>I&#8217;m going to quote Teyo&#8217;s comment in full because I think it answers a lot of question that people have had about some of the key differences between <a href="http://www.kartar.net/tag/puppet/" class="st_tag internal_tag" rel="tag" title="Posts tagged with puppet">Puppet</a> and <a href="http://www.kartar.net/tag/chef/" class="st_tag internal_tag" rel="tag" title="Posts tagged with chef">Chef</a> &#8211; dependency modelling and <a href="http://www.kartar.net/tag/dsl/" class="st_tag internal_tag" rel="tag" title="Posts tagged with DSL">DSL</a>:</p>
<p><em>There is a misstatement in your assessment of <a href="http://www.kartar.net/tag/puppet/" class="st_tag internal_tag" rel="tag" title="Posts tagged with puppet">Puppet</a>&#8217;s dependency handling. You express <a href="http://www.kartar.net/tag/chef/" class="st_tag internal_tag" rel="tag" title="Posts tagged with chef">Chef</a>&#8217;s ordering as <a href="http://www.kartar.net/tag/deterministic/" class="st_tag internal_tag" rel="tag" title="Posts tagged with deterministic">deterministic</a> and imply that <a href="http://www.kartar.net/tag/puppet/" class="st_tag internal_tag" rel="tag" title="Posts tagged with puppet">Puppet</a> is in someway non-<a href="http://www.kartar.net/tag/deterministic/" class="st_tag internal_tag" rel="tag" title="Posts tagged with deterministic">deterministic</a>. This is not the first time you have implied this publicly, so I thought I should bring some clarity to your misstatement. The actual differentiation is procedural ordering versus a dependency graph. <a href="http://www.kartar.net/tag/puppet/" class="st_tag internal_tag" rel="tag" title="Posts tagged with puppet">Puppet</a> provides a graphing model for ordering versus a procedural model. Sure, you get procedural ordering for free with Ruby, it seems easier, and I am aware that this was a design decision for you guys. We also know that you were frustrated by &#8220;having&#8221; to express dependencies in <a href="http://www.kartar.net/tag/puppet/" class="st_tag internal_tag" rel="tag" title="Posts tagged with puppet">Puppet</a> in order to ensure consistent ordering. Properly expressed dependencies in <a href="http://www.kartar.net/tag/puppet/" class="st_tag internal_tag" rel="tag" title="Posts tagged with puppet">Puppet</a> provide ordering where you care to have it. Procedural ordering is implicit even if you don&#8217;t care. This is a BIG difference, perhaps the fundamental difference between <a href="http://www.kartar.net/tag/puppet/" class="st_tag internal_tag" rel="tag" title="Posts tagged with puppet">Puppet</a> and <a href="http://www.kartar.net/tag/chef/" class="st_tag internal_tag" rel="tag" title="Posts tagged with chef">Chef</a> and one that was designed into <a href="http://www.kartar.net/tag/puppet/" class="st_tag internal_tag" rel="tag" title="Posts tagged with puppet">Puppet</a> because of experiences we had trying to cope with a large code base of procedurally order scripts to manage an enterprise infrastructure. Yeah we were using make, yeah that was crazy, crazy but informative.</em></p>
<p><em>Your omission is related to your design decision to avoid dependency graphing, which you yourself have admitted has some major downsides, namely the inability to provide a reasonable dry-run mode, <a title="http://bit.ly/4Gcz7G" href="http://bit.ly/4Gcz7G">http://bit.ly/4Gcz7G</a>. Frankly, I don&#8217;t know how you develop with out a dry-run mode, but hey I am a sysadmin not a developer.</em></p>
<p><em>Without a graph of resource dependencies, we would have no way of separating concerns. Consider the use case of implementing security standards. Ideally, you would want any given configuration run to bring your system into complete compliance. That sounds great but would you really want security policies not to be implemented because some earlier procedure was unable to succeed, say because it was pulling in data from a source that was not available.</em></p>
<p><em>So here is the difference in a nutshell. <a href="http://www.kartar.net/tag/puppet/" class="st_tag internal_tag" rel="tag" title="Posts tagged with puppet">Puppet</a> generates a catalog of dependent resources. This catalog is shipped to the clients and acted on by the Resource Abstraction Layer (RAL). On the other hand <a href="http://www.kartar.net/tag/chef/" class="st_tag internal_tag" rel="tag" title="Posts tagged with chef">Chef</a>, ships the required Ruby code for any node&#8217;s configuration and orders the execution of that code procedurally. These are the core differences. The <a href="http://www.kartar.net/tag/dsl/" class="st_tag internal_tag" rel="tag" title="Posts tagged with DSL">DSL</a> issues become moot if you consider Shadow <a href="http://www.kartar.net/tag/puppet/" class="st_tag internal_tag" rel="tag" title="Posts tagged with puppet">Puppet</a> or the Ruby <a href="http://www.kartar.net/tag/dsl/" class="st_tag internal_tag" rel="tag" title="Posts tagged with DSL">DSL</a> that we are developing as part of <a href="http://www.kartar.net/tag/puppet/" class="st_tag internal_tag" rel="tag" title="Posts tagged with puppet">Puppet</a>&#8217;s next release. The real difference, and IMHO <a href="http://www.kartar.net/tag/puppet/" class="st_tag internal_tag" rel="tag" title="Posts tagged with puppet">Puppet</a>&#8217;s advantage is our resource model and it&#8217;s dependency graphs versus a monolithic procedural chunk of Ruby code delivered to every client.</em></p>
<p><em>Here are some derived advantages of our model and a little love for the much maligned declarative external <a href="http://www.kartar.net/tag/dsl/" class="st_tag internal_tag" rel="tag" title="Posts tagged with DSL">DSL</a>:</em></p>
<p><em>1) Graphing base branch independence.</em></p>
<p><em>Parts of a catalog can be implemented more often than others. That is to say, we can tag certain resources to be checked and reconfigured more often. Additionally, parts of a configuration can be meaningfully checked but not acted on (See Adam&#8217;s discussion of noop <a title="http://bit.ly/4Gcz7G" href="http://bit.ly/4Gcz7G">http://bit.ly/4Gcz7G</a>).  Our customers/community love this and without a graph I don&#8217;t see how it is possible.</em></p>
<p><em>2) Cross host dependencies.</em></p>
<p><em>Our data model passes dependencies into our catalog caching system, so cross host dependencies can be resolved as well. This isn&#8217;t currently available but the framework exists and we intend to take advantage of it.</em></p>
<p><em>3) Failures are contained.</em></p>
<p><em>Critical parts of a configuration run are not excluded because of non-dependent failures.</em></p>
<p><em>4) Low barrier to entry for non-rubyist.</em></p>
<p><em>Non-rubyist can take advantage of the specification language out of the gate and Ruby developers can take advantage of the current <a href="http://www.kartar.net/tag/puppet/" class="st_tag internal_tag" rel="tag" title="Posts tagged with puppet">Puppet</a> plugin API and the future Ruby <a href="http://www.kartar.net/tag/dsl/" class="st_tag internal_tag" rel="tag" title="Posts tagged with DSL">DSL</a>, so everyone gets to use their favorite hammer.</em></p>
<p><em>5) Don&#8217;t like our <a href="http://www.kartar.net/tag/dsl/" class="st_tag internal_tag" rel="tag" title="Posts tagged with DSL">DSL</a>, don&#8217;t like Ruby?</em></p>
<p><em>Because we are only generating a catalog from the configuration language it should be fairly straight forward for anyone to generate a catalog using whatever language they choose and the RAL would be able to act on it. Come on Python people you know you want to generate catalogs with Python.</em></p>
<p><em>6) I can&#8217;t run Ruby on my switch!</em></p>
<p><em>Because we are using a data model for resources, devices that can&#8217;t/don&#8217;t have access to Ruby could still use the catalog as a basis for configuring themselves. Routers, switches, firewalls, could all be configured using the same specification language independent of how the specification is implemented, but with the resource model intact.</em></p>
<p><em>Finally, I think that you were a little hard on John about his comments on <a href="http://www.kartar.net/tag/chef/" class="st_tag internal_tag" rel="tag" title="Posts tagged with chef">Chef</a> being Rails focused. Certainly he misspoke, but the truth is that <a href="http://www.kartar.net/tag/chef/" class="st_tag internal_tag" rel="tag" title="Posts tagged with chef">Chef</a> development has been focused on web-application rollout in fairly homogeneous environments. Sure you can use <a href="http://www.kartar.net/tag/chef/" class="st_tag internal_tag" rel="tag" title="Posts tagged with chef">Chef</a> to manage the initial deployment of a web application, but in environments where you may have lots of teams utilizing compute resources for various application architectures, <a href="http://www.kartar.net/tag/puppet/" class="st_tag internal_tag" rel="tag" title="Posts tagged with puppet">Puppet</a>&#8217;s resource model shines. Security administrators can develop their <a href="http://www.kartar.net/tag/puppet/" class="st_tag internal_tag" rel="tag" title="Posts tagged with puppet">Puppet</a> manifests and not need to worry that security policies are not going to be applied because the DBA teams manifests failed. Operations teams can run <a href="http://www.kartar.net/tag/puppet/" class="st_tag internal_tag" rel="tag" title="Posts tagged with puppet">Puppet</a> in noop mode persistently and be notified if their configuration is out of compliance. Developers can make sure that the infrastructure they need for successful application deployment is available without having to worry that the security policy failed to be applied. Everyone gets to be friendlier with one and other and perhaps even get to the pub earlier on occasion.</em></p>
<p><strong>Disclosure &amp; Disclaimer &#8211; I am <a href="http://www.kartar.net/tag/puppet/" class="st_tag internal_tag" rel="tag" title="Posts tagged with puppet">Puppet</a>&#8217;s Release Manager and obviously heavily involved with the Reductive Lab&#8217;s team and the project.  My opinions are my own and not representative of my employer or Reductive Labs.</strong></p>
]]></content:encoded>
			<wfw:commentRss>http://www.kartar.net/2010/01/puppet-chef-deterministic-ordering-and-the-much-maligned-dsl/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Yes Mum, I&#8217;ll Behave: Beginning Behaviour Driven Infrastructure</title>
		<link>http://www.kartar.net/2009/12/yes-mum-ill-behave-beginning-behaviour-driven-infrastructure/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=yes-mum-ill-behave-beginning-behaviour-driven-infrastructure</link>
		<comments>http://www.kartar.net/2009/12/yes-mum-ill-behave-beginning-behaviour-driven-infrastructure/#comments</comments>
		<pubDate>Mon, 21 Dec 2009 12:07:30 +0000</pubDate>
		<dc:creator>kartar</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[devops]]></category>
		<category><![CDATA[open source]]></category>
		<category><![CDATA[puppet]]></category>
		<category><![CDATA[behavioural driven development]]></category>
		<category><![CDATA[behavioural driven infrastructure]]></category>
		<category><![CDATA[configuration management]]></category>
		<category><![CDATA[cucumber]]></category>
		<category><![CDATA[Nagios]]></category>
		<category><![CDATA[test driven development]]></category>

		<guid isPermaLink="false">http://www.kartar.net/?p=1948</guid>
		<description><![CDATA[So I like to think I know a bit about enterprise monitoring and configuration management.&#160; I&#39;ve done a lot of it over the years across multiple platforms and using a bunch of tools &#8211; both proprietary and open source.&#160; I&#39;ve even written two books about the open source tools, Nagios and Puppet.&#160; But all this [...]]]></description>
			<content:encoded><![CDATA[<p>So I like to think I know a bit about enterprise monitoring and <a href="http://www.kartar.net/tag/configuration-management/" class="st_tag internal_tag" rel="tag" title="Posts tagged with configuration management">configuration management</a>.&nbsp; I&#39;ve done a lot of it over the years across multiple platforms and using a bunch of tools &#8211; both proprietary and open source.&nbsp; I&#39;ve even written <a href="http://tunyurl.com/pronagios" target="_blank" title="Pro Nagios 2.0">two</a> <a href="http://tinyurl.com/pupbook" target="_blank" title="Pulling Strings with Puppet">books</a> about the open source tools, <a href="http://www.nagios.org" target="_blank" title="Nagios">Nagios</a> and <a href="http://reductivelabs.com/products/puppet/" target="_blank" title="Puppet">Puppet</a>.&nbsp; But all this time I&#39;ve been doing it wrong.&nbsp; Really badly wrong. </p>
<p>The typical enterprise monitoring and <a href="http://www.kartar.net/tag/configuration-management/" class="st_tag internal_tag" rel="tag" title="Posts tagged with configuration management">configuration management</a> set-up is generally something like this: central server(s) manage and monitor a number of services on local and/or remote hosts.&nbsp; Digging down, for a web server these checks might be something like:</p>
<ul>
<li>Is the Apache package installed and the appropriate version?</li>
<li>Is the Apache service running?</li>
<li>Can I connect to the HTTP port and is HTML returned?</li>
</ul>
<p>Multiply this by a few hundred iterations of hosts and types of services and you&#39;re probably looking at your typical Nagios, <a href="http://www.kartar.net/tag/puppet/" class="st_tag internal_tag" rel="tag" title="Posts tagged with puppet">Puppet</a>, Cfengine, Hyperic, Tivoli or Patrol set-up. Add logging, alerts, graphs and reporting and this is probably pretty close to the environment that most system administrators manage and monitor every day. All the bases covered, appropriate alerts when things go down, reporting for your management, etc, etc.</p>
<p>So that&#39;s all good right and we don&#39;t need to do anything more?&nbsp; Nope, not quite.&nbsp; All this monitoring misses something critical &#8211; we&#39;re not actually monitoring that the service does what it should.&nbsp; Yes, it matters whether Apache is installed, the Apache service is running, and you can connect to HTTP but does this actually prove anything about the availability of the service we&#39;re managing and providing for our customers?&nbsp; No again.&nbsp; You can connect to the port, have the service running and still not be delivering the right content or providing the appropriate functionality to the customer. And ultimately that&#39;s what our jobs are all about &#8211; delivering service to the customer.&nbsp; Whether internal (&quot;the business&quot;) or an external customer, they don&#39;t care about the infrastructure.&nbsp; Nor the technology, its configuration or anything else about the widgets that deliver the services they use.&nbsp; They just want &quot;technology&quot; to be:</p>
<ol>
<li>Available,</li>
<li>Functional, and</li>
<li>Cost-effective.</li>
</ol>
<p>To deliver (and measure) the first two items on that list we&#39;re going to need more than just a check that says the Apache server is up.&nbsp; We need to demonstrate that the service delivered by that infrastructure was available to our customers AND functioning as intended.&nbsp; If it isn&#39;t functioning as intended, all the availability in the world is meaningless because the customer isn&#39;t getting what they want.</p>
<p>(Needless to say most enterprise monitoring measures of &quot;availability&quot; are bogus.&nbsp; Using an ICMP ping of a host, <em>uptime</em> or checking a process as a measure of availability merely demonstrates that the asset is up.&nbsp; It doesn&#39;t demonstrate that the asset is performing the function it should hence doesn&#39;t actually measure &quot;availability&quot;.)</p>
<p>All is not lost though, we have the technology, we can rebuild your monitoring environment: better, stronger and more relevant.&nbsp; How?&nbsp; By stealing someone else&#39;s idea.&nbsp; You see developers face the same challenge of delivering appropriate functionality.&nbsp; In their case an application may compile and run but produce incorrect output or worse no output at all.&nbsp; Like our monitoring, this leaves our developer short on knowing whether they are delivering functionality to the customer. So to ensure that their applications do what they have promised, developers test them.&nbsp;</p>
<p>There are lots of different kinds of testing: functional tests to confirm things work, performance testing, user acceptance tests to ensure user experience is suitable.&nbsp; But one kind of testing has become increasing important: behavioural testing.&nbsp; Behavioural testing checks that each function, method or procedure not only works but behaves in the intended way. Developers call this methodology Behaviour Driven Development or <a href="http://www.kartar.net/tag/test-driven-development/" class="st_tag internal_tag" rel="tag" title="Posts tagged with test driven development">Test Driven Development</a> (BDD and TDD for short). In a BDD/TDD environment each component of your code is tested to ensure it is behaving correctly.&nbsp; The basic element of this testing is called a unit test.&nbsp; In BDD, unit tests are developed for each function to determine whether it is fit for use.&nbsp; Let&#39;s look a simple example of a function, one that adds numbers, and a unit test to confirm its behaviour is correct.&nbsp; We&#39;ll start by articulating our function (in pseudo code).</p>
<pre>def addition(val1,val2)
  print &quot;Total =&quot; val1 + val2
end
</pre>
<p>So if our function compiles, executes and returns a result does that mean it works?&nbsp; No, because we can&#39;t guarantee it returns the right result.&nbsp; To overcome this gap in our knowledge, we devise a simple unit test (again in pseudo code).</p>
<pre>test addition
  val1 = 4
  val2 = 6
  total = 10

  result = addition(val1,val2)
  if result != total then print &quot;Function addition failed - incorrect total&quot;
end
</pre>
<p>In our test we first set the input values and what the resulting output should be (in the object-orientated world these are called &quot;mock&quot; objects and are designed to simulate real objects in a controlled way).&nbsp; We then run the function we&#39;d like to test and check that the returned result matches the mock output.&nbsp; If the result doesn&#39;t match then we return an error message and we know we need to fix the function. This combination of functional tests and behavioural testing means that not only do we ensure our applications runs but that when it does run it is behaving correctly.</p>
<p>So can we apply Behaviour Driven Development to our infrastructure to test that it is behaving correctly?&nbsp; Enter Behaviour Driven Infrastructure.&nbsp;<a href="http://holmwood.id.au/~lindsay/2009/11/09/behaviour-driven-infrastructure-through-cucumber/" target="_blank" title="Behaviour driven infrastructure through Cucumber ">Behavioural Driven Infrastructure or BDI</a> applies the principles of <a href="http://www.kartar.net/tag/behavioural-driven-development/" class="st_tag internal_tag" rel="tag" title="Posts tagged with behavioural driven development">Behavioural Driven Development</a> to the management of infrastructure.&nbsp; And boy is it cool. Let&#39;s jump right in and see what a BDI check might look like.&nbsp; Remember our Apache checks?&nbsp; Let&#39;s design some simple behavioural checks to supplement these, checks that step up from monitoring our infrastructure into monitoring the behaviour of our service:</p>
<ul>
<li>The site contains some static value or content</li>
<li>The site contains some dynamic content that can be validated, for example data drawn from a database</li>
<li>When I click or follow links I get the right pages returned</li>
<li>When I fill in a form the values are validated</li>
<li>When I press a button the form is submitted</li>
<li>When I select a field or drop-down the right values are populated</li>
</ul>
<p>Notice the key difference between the checks we defined earlier and these checks?&nbsp; These checks involve the <em>behaviour</em> of the service rather than its binary status.&nbsp; Instead of the site being &quot;up&quot; we&#39;re testing that the site returns the right content or in other words that the site <em>behaves</em> correctly. We can see that determining tests for a website is relatively easy but what about other types of infrastructure and services? &nbsp;You can develop similar tests for a wide variety of infrastructure:</p>
<ul>
<li>SSH &#8211; check that a particular user can login, an inappropriate user fails and is logged or alerted</li>
<li>SMTP &#8211; check that the daemon receives an email and delivers it, check it rejects mail it should reject, check authentication works</li>
<li>IMAP &#8211; Check you can receive email from a mailbox, check authentication works</li>
<li>MySQL/database/LDAP/directories &#8211; check you can query a record and that the record returned is correct</li>
<li>Load balancer &#8211; check connections are switched between hosts</li>
<li>DNS &#8211; check output of DNS queries is correct</li>
<li>Backups &#8211; backup and restore a file</li>
<li>Nagios/Enterprise Monitoring &#8211; Check tests pass, fail, escalate, send notifications</li>
<li>Samba/NFS &#8211; create, change, delete a file</li>
<li>Sudo &#8211; check you can run a sudo command and check inappropriate sudo commands fail and log</li>
</ul>
<p>Notice what we&#39;re trying to do?&nbsp; We&#39;re testing that the service does what the customer expects it to do.&nbsp; This not only proves the service is behaving the way we want it to but also demonstrates that the service is available.</p>
<p>So all of these tests sound easy when written down like this but how do we implement them? We&#39;re going to articulate our BDI tests in plain English using a tool called <a href="http://cukes.info/" target="_blank" title="Cucumber">Cucumber</a> and also introduce you to a spin-off tool called <a href="http://auxesis.github.com/cucumber-nagios/" target="_blank" title="Cucumber-Nagios">Cucumber-Nagios</a> (which I talked about in a <a href="http://www.kartar.net/2009/03/cucumber/" target="_blank" title="Cucumber">previous post</a>).&nbsp;</p>
<p>Cucumber is a behavioural testing framework used heavily in the Ruby community (and in the Java, .NET, Flex communities too) that is simple and easy to learn &#8211; even for non-developers. Cucumber-Nagios takes this a little further to combine Cucumber with built-in testing frameworks (web using <a href="http://github.com/brynary/webrat/" target="_blank" title="Webrat">Webrat</a> and SSH using <a href="http://net-ssh.rubyforge.org/" target="_blank" title="Net::SSH">Net::SSH</a> for example) and outputs test results as <a href="http://www.nagios.org/" target="_blank" title="Nagios">Nagios</a> check data.&nbsp; Perfect for immediate integration into your existing enterprise monitoring solution (and easily hack&#39;able to output as other data formats also).&nbsp; The beauty of Cucumber-Nagios is that it comes with pre-built tests components that we can adapt to suit our environment. Cucumber has two components:</p>
<ol>
<li>Plain text tests called &quot;features&quot; which contain the different scenarios we want to test, and</li>
<li>Supporting code called &quot;steps&quot; to actually test each &quot;feature&quot; and its associated scenarios.</li>
</ol>
<p>Let&#39;s create a simple behavioural test for our website.&nbsp; We start by installing Cucumber-Nagios via a Gem:</p>
<p><code>$ sudo gem install cucumber-nagios</code></p>
<p>On some distributions you may need to install <em>gemcutter </em>first:</p>
<p><code>$ sudo gem install gemcutter </code></p>
<p><code>$ sudo gem tumble</code></p>
<p>The <em>cucumber-nagios</em> gem will install the <em>cucumber-nagios-gen</em> binary which we will use to create a project to hold our tests.</p>
<p><code>$ cucumber-nagios-gen project test_project</code></p>
<p>Here we&#39;ve told the <em>cucumber-nagios-gen</em> binary to create a project called <em>test_project.</em> A project is a mini-application that contains the right directory structure and files to run our tests. Change into the resulting directory:</p>
<p><code>$ cd test_project</code></p>
<p>We then need to bundle some supporting gems into the project to allow it to be self-contained:</p>
<p><code>$ gem bundle</code></p>
<p>Now we have a local version of <em>cucumber-nagios-gen</em> installed in the <em>bin</em> directory of the project and we can use this to create some features to test:</p>
<p><code>$ bin/cucumber-nagios-gen feature www.google.com content</code></p>
<p>This creates a feature in a file called <em>content.feature</em> (each Cucumber file can contain one feature and must have a suffix of <em>.feature</em>).&nbsp; Let&#39;s open this file and examine our feature:</p>
<pre>Feature: www.google.com
  It should be up

  Scenario: Visiting home page
    When I go to http://www.google.com
    Then the request should succeed
</pre>
<p>Cucumber uses a <a href="http://www.martinfowler.com/bliki/BusinessReadableDSL.html">business-readable domain-specific language</a> called <a href="http://wiki.github.com/aslakhellesoy/cucumber/gherkin" target="_blank" title="Gherkin">Gherkin</a> to write its features. Let&#39;s deconstruct what each section of our feature means:</p>
<pre> Feature: Some terse yet descriptive text of what is desired
   In order to realize a named business value
   As an explicit system actor
   I want to gain some beneficial outcome which furthers the goal

   Scenario: Some determinable business situation
     Given some precondition
       And some other precondition
     When some action by the actor
       And some other action
       And yet another action
     Then some testable outcome is achieved
       And something else we can check happens too

   Scenario: A different situation
       ...
</pre>
<p>The feature starts with a description, in our case <em>www.google.com</em> and then some text that describes the business value of the feature, that the website should be up.&nbsp; Each scenario used to validate that business value is then listed, each with it&#39;s own description and a series of steps that they involve.&nbsp; There are three types of steps &#8211; <a href="http://wiki.github.com/aslakhellesoy/cucumber/given-when-then" target="_blank" title="Given, When and Then">Given, When or Then</a>:</p>
<ol>
<li>Givens &#8211; put the system into a known state</li>
<li>Whens &#8211; describe the key action that is being performed</li>
<li>Thens &#8211; observe the outcomes</li>
</ol>
<p>Which can be summarised as: <strong>Given</strong> some condition <strong>When</strong> I do this action <strong>Then</strong> I will see this outcome.</p>
<p>Each step in our scenario has to start with one of these types (but you don&#39;t need to use all of them) and you can see in our example feature we&#39;re using a When and a Then:</p>
<pre> When I go to http://www.google.com
 Then the request should succeed</pre>
<p>Simple and plain English.&nbsp; There is a bit more to <a href="http://wiki.github.com/aslakhellesoy/cucumber/gherkin" target="_blank" title="Gherkin">Gherkin</a> that we haven&#39;t touched on (but you can read about at that link) but let&#39;s try to run our feature now using the <em>cucumber-nagios</em> binary (obviously you need to be connected to the Internet for the feature to work appropriately):</p>
<pre>$ bin/cucumber-nagios features/www.google.com/content.feature
Critical: 0, Warning: 0, 2 okay | passed=2, failed=0, nosteps=0, total=2
</pre>
<p>We can see that we&#39;ve selected and executed our feature and it has returned some Nagios plug-in output (which appears as Critical, Warning, or Okay) and that 2 steps are Okay (or passed).&nbsp;</p>
<p>But wait a second, how have they passed?&nbsp; We haven&#39;t written any code at all and it works?&nbsp; Well as I mentioned Cucumber-Nagios contains a set of pre-defined steps for a variety of common tasks.&nbsp; You can use these steps and not have to write any code.&nbsp; Let&#39;s look at the associated step we&#39;ve just used.&nbsp; This pre-defined step is contained in the <em>features/steps/webrat.steps</em> file in our project:</p>
<pre>When /^I go to (.*)$/ do |path|
  visit path
end
</pre>
<p>You can see it&#39;s a very simple bit of code that uses a regular expression to check our feature file for some specific language, in this case the words &quot;I go to URL&quot;.&nbsp; The regular expression captures a URL and passes it to Webrat which runs the <em>visit</em> function and returns the result.&nbsp; This is passed to the next step:</p>
<pre>Then the request should succeed</pre>
<p>Cucumber-Nagios also contains a set of pre-defined steps for handling the results, the Then steps.&nbsp; These steps are contained in the <em>features/steps/result_steps.rb</em> file.&nbsp; In this case we&#39;ve used the following step:</p>
<pre>Then /^the (.*) ?request should succeed/ do |_|
   success_code?.should be_true
end
</pre>
<p>This step checks the result of the When step and if it registered a success then the step passes and returns an Okay result.</p>
<p>Now, let&#39;s see how we can add another scenario to our feature.</p>
<pre>Feature: www.google.com
  It should be up
  You should be able to click on the Videos link

  Scenario: Visiting home page
    When I go to http://www.google.com
    Then the request should succeed

  Scenario: Clicking on the Videos link
    When I go to http://www.google.com
      And I follow &quot;Videos&quot;
    Then I should see &quot;Google Videos&quot;
</pre>
<p>In our new scenario we&#39;ve tested following a link on the Google site to the Google Videos site.&nbsp; We&#39;ve also used another piece of Cucumber statement, <strong>And</strong>, which is a cleaner way of writing multiple Given-When-Then steps.</p>
<p>This new When step also uses a pre-defined step from Cucumber-Nagios:</p>
<pre>When /^I follow &quot;(.*)&quot;$/ do |link|
   click_link(link)
end
</pre>
<p>And a pre-defined Then step:</p>
<pre>Then /^I should see an? (\w+) message$/ do |message_type|
  response.should have_xpath(&quot;//*[@class=&#39;#{message_type}&#39;]&quot;)
end
</pre>
<p>We can then run our new scenario:</p>
<pre>$ bin/cucumber-nagios features/www.google.com/content.feature
Critical: 0, Warning: 0, 5 okay | passed=5, failed=0, nosteps=0, total=5
</pre>
<p>And see that we&#39;ve now got 5 steps that pass, including our 3 new steps.&nbsp; Simple eh?&nbsp; And readily extensible.</p>
<p>So we&#39;ve seen that Cucumber and BDI allows infrastructure testing but we can also extend this concept further.&nbsp; So we&#39;ve seen that Cucumber can establish that the service is behaving correctly but what if we also used it to test for business logic and business rules also?&nbsp; Let&#39;s take a simple example, expressed here as a feature:</p>
<pre>Feature: homeloansite.com
  It should be up
  And I should be able to find the current Rate

  Scenario: Checking the current interest rate
    When I visit &quot;http://homeloansite.com&quot;
    Then I should see the Rates section
    Then I should see current Rate
      And the current Rate should equal 5%
</pre>
<p>You&#39;d need to write an additional step to return the Rate value in Cucumber-Nagios to get this example to work but assuming we had we could then run our new feature:</p>
<pre>$ cucumber-nagios features/homeloansite.com/homeloan.feature
Critical: 0, Warning: 0, 4 okay | value=4.000000;;;;
</pre>
<p>In this feature we&#39;ve checking four steps:</p>
<ol>
<li>That the Home Loan site is up</li>
<li>That it has a section called &quot;Rates&quot;</li>
<li>That the section contains a Rate, and</li>
<li>That the Rate equals 5%</li>
</ol>
<p>So in this single scenario we&#39;ve killed a lot of birds with one cucumber.&nbsp; We&#39;ve confirmed the site is up, we&#39;ve confirmed that the right content is being delivered and lastly we&#39;ve confirmed that the information being delivered is correct.&nbsp; This goes beyond our traditional infrastructure testing to confirm that a piece of business data, our home loan rate, is correct.&nbsp; Using this test we could then configure Nagios to alert the appropriate business contact that the website was displaying the wrong rate.&nbsp; And hey presto we&#39;re delivering business value.</p>
<p>This feature is just the tip of the iceberg.&nbsp; We could do a whole collection of other things, for example test transaction limits for a finance application, confirm access controls for applications, check the output of reports, and anything else where business logic or rules are exposed and can be exercised and tested.</p>
<p>Lastly, it&#39;s important to remember we&#39;re not replacing our traditional checks when using Cucumber.&nbsp; We still need to watch the low level components we&#39;re just adding another, more powerful and insightful layer to our monitoring.&nbsp; A layer that more accurately represents the value that you offer to the business than graphs of ICMP ping results.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.kartar.net/2009/12/yes-mum-ill-behave-beginning-behaviour-driven-infrastructure/feed/</wfw:commentRss>
		<slash:comments>10</slash:comments>
		</item>
		<item>
		<title>Configuration Management Panel at Open Source Bridge &#8211; Portland June 2009</title>
		<link>http://www.kartar.net/2009/05/configuration-management-panel-at-open-source-bridge-portland-june-2009/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=configuration-management-panel-at-open-source-bridge-portland-june-2009</link>
		<comments>http://www.kartar.net/2009/05/configuration-management-panel-at-open-source-bridge-portland-june-2009/#comments</comments>
		<pubDate>Tue, 19 May 2009 23:56:45 +0000</pubDate>
		<dc:creator>kartar</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[configuration management]]></category>
		<category><![CDATA[opensourcebridge]]></category>
		<category><![CDATA[panel]]></category>
		<category><![CDATA[puppet]]></category>

		<guid isPermaLink="false">http://www.kartar.net/?p=1791</guid>
		<description><![CDATA[So, because I have so much copious spare time, I am running a panel on Configuration Management at OpenSourceBridge in Portland.  The panel is on June 18th and entails: Configuration management tools are finally coming into their own. Powerful, automated infrastructure management is now available in a wide variety of open source tools. Tools written [...]]]></description>
			<content:encoded><![CDATA[<p>So, because I have so much copious spare time, I am running <a title="Configuration Management Panel" href="http://opensourcebridge.org/sessions/49" target="_blank">a panel on Configuration Management</a> at <a title="OpenSourceBridge" href="http://opensourcebridge.org/" target="_blank">OpenSourceBridge</a> in Portland.  The panel is on June 18th and entails:</p>
<p><em><a href="http://www.kartar.net/tag/configuration-management/" class="st_tag internal_tag" rel="tag" title="Posts tagged with configuration management">Configuration management</a> tools are finally coming into their own. Powerful, automated infrastructure management is now available in a wide variety of open source tools. Tools written in different languages, using varying operational methodologies and embracing differing philosophies. Come meet some of the creators and maintainers of these cutting edge tools like cfengine, <a href="http://www.kartar.net/tag/puppet/" class="st_tag internal_tag" rel="tag" title="Posts tagged with puppet">Puppet</a>, AutomateIT, <a href="http://www.kartar.net/tag/chef/" class="st_tag internal_tag" rel="tag" title="Posts tagged with chef">Chef</a>, and bcfg2 and quiz them in the why and hows of their tools and the philosophies behind them.</em></p>
<p>The panel includes the following cool participants:</p>
<p>- Luke Kanies from Reductive Labs for <a href="http://reductivelabs.com/products/puppet/">Puppet</a><br />
- Brendan Strejcek of <a href="http://www.cfengine.org/">Cfengine</a><br />
- Adam Jacob from Opscode for <a href="http://wiki.opscode.com/display/chef/Home">Chef</a><br />
- Narayan Desai of <a href="http://trac.mcs.anl.gov/projects/bcfg2">bcfg2</a><br />
- Igal Koshevoy of <a href="http://automateit.org/">AutomateIt</a></p>
<p>If you have any interest in CM or operations automation I strongly recommend you attend.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.kartar.net/2009/05/configuration-management-panel-at-open-source-bridge-portland-june-2009/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
