<?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>Puppet Labs</title>
	<atom:link href="http://puppetlabs.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://puppetlabs.com</link>
	<description>Puppet Labs: The Leading IT Automation Software Solution</description>
	<lastBuildDate>Fri, 10 Feb 2012 21:56:01 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>Puppet Camp Atlanta: Success!</title>
		<link>http://puppetlabs.com/blog/puppet-camp-atlanta-success/</link>
		<comments>http://puppetlabs.com/blog/puppet-camp-atlanta-success/#comments</comments>
		<pubDate>Tue, 07 Feb 2012 22:15:37 +0000</pubDate>
		<dc:creator>jose</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[Community]]></category>
		<category><![CDATA[Conferences and Workshops]]></category>
		<category><![CDATA[DevOps]]></category>
		<category><![CDATA[General News]]></category>
		<category><![CDATA[Puppet Camp]]></category>
		<category><![CDATA[Users]]></category>
		<category><![CDATA[conference]]></category>
		<category><![CDATA[Configuration Management]]></category>
		<category><![CDATA[Events]]></category>

		<guid isPermaLink="false">http://puppetlabs.com/?p=12080</guid>
		<description><![CDATA[Puppet Camp Atlanta was a fantastic community event and is be the template for our continuing Puppet Camp series. In many ways Atlanta was an experiment to see if our community could support a 1-day event structure. It can, and the meeting was productive and filled with rich content. A loose speaking schedule allowed for [...]]]></description>
			<content:encoded><![CDATA[<p>Puppet Camp Atlanta was a fantastic community event and is be the template for our continuing Puppet Camp series. In many ways Atlanta was an experiment to see if our community could support a 1-day event structure. It can, and the meeting was productive and filled with rich content. A loose speaking schedule allowed for a lot of great conversations over coffee and open Q&#038;A sessions with Puppet Engineers. More than ever before, the Puppet team felt as though we were able to connect with participants to help tackle the tough issues that our users face in real world situations. I strongly encourage you to participate in an <a href="/puppetcamp">upcoming Puppet Camp</a> in your city. </p>
<p>We have 7 Puppet Camps in the works, so look for your city on <a href="/puppetcamp">our complete list</a>. If you don&#8217;t see your greater area represented and think you can help us find 100 puppeteers eager to converse, reach out and we&#8217;ll see what we can do to bring an event to your city. </p>
<p>And don&#8217;t forget PuppetConf is September 27th and 28th at the Mission Bay Conference Center in San Francisco, California. A call for participation, registration details, and sponsorship prospectus will be available by March. PuppetConf has an estimated 60 speaking opportunities and will span all topics operations, DevOps, Puppet, and the Puppet Ecosystem.</p>
]]></content:encoded>
			<wfw:commentRss>http://puppetlabs.com/blog/puppet-camp-atlanta-success/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Managing F5 BIG-IP Network Devices with Puppet</title>
		<link>http://puppetlabs.com/blog/managing-f5-big-ip-network-devices-with-puppet/</link>
		<comments>http://puppetlabs.com/blog/managing-f5-big-ip-network-devices-with-puppet/#comments</comments>
		<pubDate>Wed, 01 Feb 2012 18:43:11 +0000</pubDate>
		<dc:creator>Nan Liu</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[Community]]></category>
		<category><![CDATA[DevOps]]></category>
		<category><![CDATA[Extending Puppet]]></category>
		<category><![CDATA[How to]]></category>
		<category><![CDATA[Modules]]></category>
		<category><![CDATA[Open Source]]></category>
		<category><![CDATA[Puppet Enterprise]]></category>
		<category><![CDATA[Services]]></category>
		<category><![CDATA[Tips]]></category>
		<category><![CDATA[F5]]></category>
		<category><![CDATA[how to]]></category>
		<category><![CDATA[modules]]></category>
		<category><![CDATA[network device management]]></category>
		<category><![CDATA[puppet 2.7]]></category>
		<category><![CDATA[puppet enterprise 2.0]]></category>
		<category><![CDATA[sysadmin]]></category>
		<category><![CDATA[tips]]></category>

		<guid isPermaLink="false">http://puppetlabs.com/?p=12007</guid>
		<description><![CDATA[Management of network devices is one of the exciting new features in Puppet Enterprise 2.0 and Puppet 2.7. In the initial release, support is limited to Cisco devices, but because Puppet is extensible via modules, we are able to build upon the existing framework and add support for F5 BIG-IP. Like most network appliances, installation [...]]]></description>
			<content:encoded><![CDATA[<p>Management of network devices is one of the exciting new features in Puppet Enterprise 2.0 and Puppet 2.7. In the initial release, support is limited to Cisco devices, but because Puppet is extensible via modules, we are able to build upon the existing framework and add support for F5 BIG-IP. Like most network appliances, installation of third party software is prohibited, which eliminates the ability to run an agent. Instead, Puppet takes advantage of F5 iControl API to interact and manage the device. F5 BIG-IP network appliances are capable of load balancing, SSL offloading, application monitoring, as well as <a href="http://www.f5.com/products/big-ip/">many other advanced features</a>, and now Puppet can manage these functionalities. Compared to traditional management methodologies and other third party tools that interact with F5, Puppet not only bridges the gap from deploying applications to bringing the service online to your customers, it also brings the unique benefit of the Puppet resource model to network devices. More specifically, the integration offers the ability to compare if a running configuration matches the desired configuration, and then enforce the changes once they’ve been reviewed.</p>
<p>In this blog post, we will step through the process of installing the F5 module, configuring connectivity, and writing a simple manifest to manage an F5 device with Puppet. If you are unfamiliar with BIG-IP devices, you may want to consult <a href="http://devcentral.f5.com/">devcentral.f5.com</a> for more information on F5 features such as iRules and iControl API.</p>
<p>In the following output, Puppet detects that the F5 device has the wrong iRule. We are running in simulation mode (<tt style="font: 14px Courier New;">--</tt>noop option) so Puppet only shows the changes that <strong>would</strong> be applied if we were enforcing the configuration.</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">$ puppet device <span style="color: #660033;">--noop</span>
...
notice: <span style="color: #000000; font-weight: bold;">/</span>Stage<span style="color: #7a0874; font-weight: bold;">&#91;</span>main<span style="color: #7a0874; font-weight: bold;">&#93;</span><span style="color: #000000; font-weight: bold;">//</span>F5_rule<span style="color: #7a0874; font-weight: bold;">&#91;</span>redirect_404<span style="color: #7a0874; font-weight: bold;">&#93;</span><span style="color: #000000; font-weight: bold;">/</span>definition: current_value: when HTTP_RESPONSE <span style="color: #7a0874; font-weight: bold;">&#123;</span>
<span style="color: #000000; font-weight: bold;">if</span> <span style="color: #7a0874; font-weight: bold;">&#123;</span> <span style="color: #7a0874; font-weight: bold;">&#91;</span>HTTP::status<span style="color: #7a0874; font-weight: bold;">&#93;</span> eq <span style="color: #ff0000;">&quot;404&quot;</span> <span style="color: #7a0874; font-weight: bold;">&#125;</span> <span style="color: #7a0874; font-weight: bold;">&#123;</span>
redirect to <span style="color: #ff0000;">&quot;http://www.puppetlabs.com/404/&quot;</span>
<span style="color: #7a0874; font-weight: bold;">&#125;</span>
<span style="color: #7a0874; font-weight: bold;">&#125;</span>, should be when HTTP_RESPONSE <span style="color: #7a0874; font-weight: bold;">&#123;</span>
<span style="color: #000000; font-weight: bold;">if</span> <span style="color: #7a0874; font-weight: bold;">&#123;</span> <span style="color: #7a0874; font-weight: bold;">&#91;</span>HTTP::status<span style="color: #7a0874; font-weight: bold;">&#93;</span> eq <span style="color: #ff0000;">&quot;404&quot;</span> <span style="color: #7a0874; font-weight: bold;">&#125;</span> <span style="color: #7a0874; font-weight: bold;">&#123;</span>
redirect to <span style="color: #ff0000;">&quot;http://www.puppetlabs.com/redirect/404/&quot;</span>
<span style="color: #7a0874; font-weight: bold;">&#125;</span>
<span style="color: #7a0874; font-weight: bold;">&#125;</span> <span style="color: #7a0874; font-weight: bold;">&#40;</span>noop<span style="color: #7a0874; font-weight: bold;">&#41;</span>
notice: Finished catalog run <span style="color: #000000; font-weight: bold;">in</span> <span style="color: #000000;">5.69</span> seconds</pre></div></div>

<p>Now running Puppet with out the <tt style="font: 14px Courier New;">--</tt>noop option set, the iRules are changed to match our resource declaration.</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">$ puppet device
…
notice: <span style="color: #000000; font-weight: bold;">/</span>Stage<span style="color: #7a0874; font-weight: bold;">&#91;</span>main<span style="color: #7a0874; font-weight: bold;">&#93;</span><span style="color: #000000; font-weight: bold;">//</span>F5_rule<span style="color: #7a0874; font-weight: bold;">&#91;</span>redirect_404<span style="color: #7a0874; font-weight: bold;">&#93;</span><span style="color: #000000; font-weight: bold;">/</span>definition: definition changed when HTTP_RESPONSE <span style="color: #7a0874; font-weight: bold;">&#123;</span>
<span style="color: #000000; font-weight: bold;">if</span> <span style="color: #7a0874; font-weight: bold;">&#123;</span> <span style="color: #7a0874; font-weight: bold;">&#91;</span>HTTP::status<span style="color: #7a0874; font-weight: bold;">&#93;</span> eq <span style="color: #ff0000;">&quot;404&quot;</span> <span style="color: #7a0874; font-weight: bold;">&#125;</span> <span style="color: #7a0874; font-weight: bold;">&#123;</span>
redirect to <span style="color: #ff0000;">&quot;http://www.puppetlabs.com/404/&quot;</span>
<span style="color: #7a0874; font-weight: bold;">&#125;</span>
<span style="color: #7a0874; font-weight: bold;">&#125;</span>, to when HTTP_RESPONSE <span style="color: #7a0874; font-weight: bold;">&#123;</span>
<span style="color: #000000; font-weight: bold;">if</span> <span style="color: #7a0874; font-weight: bold;">&#123;</span> <span style="color: #7a0874; font-weight: bold;">&#91;</span>HTTP::status<span style="color: #7a0874; font-weight: bold;">&#93;</span> eq <span style="color: #ff0000;">&quot;404&quot;</span> <span style="color: #7a0874; font-weight: bold;">&#125;</span> <span style="color: #7a0874; font-weight: bold;">&#123;</span>
redirect to <span style="color: #ff0000;">&quot;http://www.puppetlabs.com/redirect/404/&quot;</span>
<span style="color: #7a0874; font-weight: bold;">&#125;</span>
<span style="color: #7a0874; font-weight: bold;">&#125;</span>
notice: Finished catalog run <span style="color: #000000; font-weight: bold;">in</span> <span style="color: #000000;">5.74</span> seconds</pre></div></div>

<p>In addition to iRules, the initial release supports key features to configure the device certificate, manage applications pool/poolmember/virtualserver, and monitor application health. The module is published on the <a href="http://forge.puppetlabs.com/puppetlabs/f5">Puppet Forge</a>, along with comprehensive documentation of supported F5 resources. The latest development release is available on <a onclick="_gaq.push(['_trackEvent', 'outbound link', 'F5 module blog post', 'GitHub download']);" href="https://github.com/puppetlabs/puppetlabs-f5">GitHub</a>. The ability to extend Puppet is not limited to network devices, and the commands shown later in this post to install the module is applicable for other Puppet modules available on the Puppet Forge and GitHub.</p>
<p>The puppet device command is a new application mode in Puppet intended to manage devices that can’t install Ruby/Puppet and run puppet agent. If you haven’t checked it out yet, I would review Brice’s <a title="Puppet Network Device Management" href="http://puppetlabs.com/blog/puppet-network-device-management/">introduction to network devices</a> first. The high level overview of the entire communication process:</p>
<p><a href="http://puppetlabs.com/wp-content/uploads/2012/01/f5_network.png"><img class="alignnone size-full wp-image-12011" title="f5_network" src="http://puppetlabs.com/wp-content/uploads/2012/01/f5_network.png" alt="" width="583" height="373" /></a></p>
<p>Devices are managed through an intermediate proxy system where Puppet agent is installed. The proxy system stores a certificate on behalf of the device. In the case of F5, it should have iControl gem installed, as well as the account information in device.conf to communicate with the device. The proxy connects to the Puppet master to retrieve the catalog on behalf of the F5 and applies changes as necessary.</p>
<h2>F5 module installation</h2>
<p>Before we get started with the installation process, there are two ways to install F5 module. First, via puppet-module tool which retrieves it from <a href="http://forge.puppetlabs.com/">forge.puppetlabs.com</a> (for stable releases of the module). The latest development release from GitHub is accessible via git. The instructions below are specific for Puppet Enterprise, but open source users can also install the module with some changes to the puppet module path. Puppet Enterprise currently ships with the puppet-module gem, and it’s freely available on <a onclick="_gaq.push(['_trackEvent', 'outbound link', 'F5 module blog post', 'rubygems download']);" href="http://rubygems.org/gems/puppet-module">rubygems.org</a>. Eventually this will become a Puppet Face and turn into the command ‘puppet module’(expected in later release of 2.7). Onwards to the install process:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #666666; font-style: italic;"># Puppet Enterprise:</span>
<span style="color: #7a0874; font-weight: bold;">cd</span> <span style="color: #000000; font-weight: bold;">/</span>etc<span style="color: #000000; font-weight: bold;">/</span>puppetlabs<span style="color: #000000; font-weight: bold;">/</span>puppet<span style="color: #000000; font-weight: bold;">/</span>modules
puppet-module <span style="color: #c20cb9; font-weight: bold;">install</span> puppetlabs-f5</pre></div></div>

<p>This should create a directory called f5. Older versions of puppet-module tool might create a puppetlabs-f5 directory in the modules directory—in that case, change it to f5.</p>
<p>Installing from GitHub:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #666666; font-style: italic;"># Puppet Enterprise:</span>
<span style="color: #7a0874; font-weight: bold;">cd</span> <span style="color: #000000; font-weight: bold;">/</span>etc<span style="color: #000000; font-weight: bold;">/</span>puppetlabs<span style="color: #000000; font-weight: bold;">/</span>puppet<span style="color: #000000; font-weight: bold;">/</span>modules
<span style="color: #c20cb9; font-weight: bold;">git</span> clone <span style="color: #c20cb9; font-weight: bold;">git</span><span style="color: #000000; font-weight: bold;">@</span>github.com:puppetlabs<span style="color: #000000; font-weight: bold;">/</span>puppetlabs-f5.git
<span style="color: #c20cb9; font-weight: bold;">ln</span> <span style="color: #660033;">-s</span> puppetlabs-f5 f5</pre></div></div>

<p>In Puppet 2.7, the transport between proxy agent and device supports telnet/ssh, however neither is suitable for F5 devices. Instead, we rely on F5’s <a onclick="_gaq.push(['_trackEvent', 'outbound link', 'F5 module blog post', 'iControl API']);" href="http://devcentral.f5.com/HotTopics/iControl/tabid/1082201/Default.aspx">iControl API</a>. The iControl gem should be installed on both the master and the proxy system. This gem is available in the F5 module files directory.</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #666666; font-style: italic;"># Puppet Enterprise:</span>
<span style="color: #000000; font-weight: bold;">/</span>opt<span style="color: #000000; font-weight: bold;">/</span>puppet<span style="color: #000000; font-weight: bold;">/</span>bin<span style="color: #000000; font-weight: bold;">/</span>gem <span style="color: #c20cb9; font-weight: bold;">install</span> <span style="color: #000000; font-weight: bold;">/</span>etc<span style="color: #000000; font-weight: bold;">/</span>puppetlabs<span style="color: #000000; font-weight: bold;">/</span>puppet<span style="color: #000000; font-weight: bold;">/</span>modules<span style="color: #000000; font-weight: bold;">/</span>f5<span style="color: #000000; font-weight: bold;">/</span>files<span style="color: #000000; font-weight: bold;">/</span>f5-icontrol-10.2.0.2.gem</pre></div></div>

<h2>Configuration and management</h2>
<p>At this point we have the module installed, so we should configure connectivity for the device. The configuration for network devices by default are stored in /etc/puppet/device.conf:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #7a0874; font-weight: bold;">&#91;</span>f5.puppetlabs.lan<span style="color: #7a0874; font-weight: bold;">&#93;</span>
<span style="color: #7a0874; font-weight: bold;">type</span> f5
url https:<span style="color: #000000; font-weight: bold;">//</span>username:password<span style="color: #000000; font-weight: bold;">@</span>f5.puppetlabs.lan<span style="color: #000000; font-weight: bold;">/</span>partition</pre></div></div>


<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #7a0874; font-weight: bold;">&#91;</span>f5.dev.puppetlabs.lan<span style="color: #7a0874; font-weight: bold;">&#93;</span>
<span style="color: #7a0874; font-weight: bold;">type</span> f5
url https:<span style="color: #000000; font-weight: bold;">//</span>username:password<span style="color: #000000; font-weight: bold;">@</span>f5.dev.puppetlabs.lan<span style="color: #000000; font-weight: bold;">/</span>partition</pre></div></div>

<p>You can also break down each device into it’s own configuration file such as /etc/puppet/f5_device1.conf, /etc/puppet/f5_device2.conf &#8230;, which is especially helpful if you wish to run against each device separately. In the square brackets is the device certificate name, and certificate management process is the same as puppet agent certs. The device type is f5, and the url is https instead of telnet/ssh. Because F5 supports different partitions we can optionally specify them at the end, and it will default to the ‘Common’ partition if it’s not provided. In the module, f5::config define resource type simplifies management of this configuration file on the proxy system:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">f5::config <span style="color: #7a0874; font-weight: bold;">&#123;</span> <span style="color: #ff0000;">'f5.puppetlabs.lan'</span>:
    username =<span style="color: #000000; font-weight: bold;">&gt;</span> <span style="color: #ff0000;">'admin'</span>,
    password =<span style="color: #000000; font-weight: bold;">&gt;</span> <span style="color: #ff0000;">'password'</span>,
    url      =<span style="color: #000000; font-weight: bold;">&gt;</span> <span style="color: #ff0000;">'f5.puppetlabs.lan'</span>,
    target   =<span style="color: #000000; font-weight: bold;">&gt;</span> <span style="color: #ff0000;">'/etc/puppetlabs/puppet/device/f5.puppetlabs.lan.conf'</span>,
<span style="color: #7a0874; font-weight: bold;">&#125;</span></pre></div></div>

<p>Once this configuration file is in place, we can initiate a puppet device run on the proxy server.</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #666666; font-style: italic;"># execute on proxy server</span>
$ puppet device <span style="color: #660033;">--deviceconf</span> <span style="color: #000000; font-weight: bold;">/</span>etc<span style="color: #000000; font-weight: bold;">/</span>puppetlabs<span style="color: #000000; font-weight: bold;">/</span>puppet<span style="color: #000000; font-weight: bold;">/</span>device<span style="color: #000000; font-weight: bold;">/</span>f5.puppetlabs.lan.conf</pre></div></div>

<p>This should generate a certificate request on the master which should be signed:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #666666; font-style: italic;"># execute on puppet master</span>
$ puppet cert <span style="color: #660033;">-l</span>
f5.puppetlabs.lan <span style="color: #7a0874; font-weight: bold;">&#40;</span>2A:0C:A0:F8:C6:EE:EF:9B:B3:<span style="color: #000000;">49</span>:<span style="color: #000000;">74</span>:D1:<span style="color: #000000;">27</span>:<span style="color: #000000;">31</span>:1B:<span style="color: #000000;">60</span><span style="color: #7a0874; font-weight: bold;">&#41;</span>
$ puppet cert <span style="color: #660033;">-s</span> f5.puppetlabs.lan</pre></div></div>

<p>At this point the master should have a node name f5.puppetlabs.lan in site.pp with the appropriate f5 resources:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
</pre></td><td class="code"><pre class="ruby" style="font-family:monospace;">node f5.<span style="color:#9900CC;">puppetlabs</span>.<span style="color:#9900CC;">lan</span> <span style="color:#006600; font-weight:bold;">&#123;</span>
  f5_rule <span style="color:#006600; font-weight:bold;">&#123;</span> <span style="color:#996600;">'redirect_404'</span>:
    <span style="color:#9966CC; font-weight:bold;">ensure</span>     <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">'present'</span>,
    definition <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">'when HTTP_RESPONSE {
if { [HTTP::status] eq &quot;404&quot; } {
redirect to &quot;http://www.puppetlabs.com/redirect/404&quot;
}
}'</span>,
  <span style="color:#006600; font-weight:bold;">&#125;</span>
&nbsp;
  f5_pool <span style="color:#006600; font-weight:bold;">&#123;</span> <span style="color:#996600;">'webapp'</span>:
    <span style="color:#9966CC; font-weight:bold;">ensure</span>                          <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">'present'</span>,
    action_on_service_down          <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">'SERVICE_DOWN_ACTION_NONE'</span>,
    allow_nat_state                 <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">'STATE_ENABLED'</span>,
    allow_snat_state                <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">'STATE_ENABLED'</span>,
    lb_method                       <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">'LB_METHOD_ROUND_ROBIN'</span>,
    member                          <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#006600; font-weight:bold;">&#123;</span>
      <span style="color:#996600;">'10.10.0.1:80'</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#006600; font-weight:bold;">&#123;</span><span style="color:#996600;">'connection_limit'</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">'0'</span>,
                         <span style="color:#996600;">'dynamic_ratio'</span>    <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">'1'</span>,
                         <span style="color:#996600;">'priority'</span>         <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">'0'</span>,
                         <span style="color:#996600;">'ratio'</span>            <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">'1'</span><span style="color:#006600; font-weight:bold;">&#125;</span>,
      <span style="color:#996600;">'10.10.0.2:80'</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#006600; font-weight:bold;">&#123;</span><span style="color:#996600;">'connection_limit'</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">'0'</span>, 
                         <span style="color:#996600;">'dynamic_ratio'</span>    <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">'1'</span>, 
                         <span style="color:#996600;">'priority'</span>         <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">'0'</span>,
                         <span style="color:#996600;">'ratio'</span>            <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">'1'</span><span style="color:#006600; font-weight:bold;">&#125;</span>,
      <span style="color:#996600;">'10.10.0.3:80'</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#006600; font-weight:bold;">&#123;</span><span style="color:#996600;">'connection_limit'</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">'0'</span>,
                         <span style="color:#996600;">'dynamic_ratio'</span>    <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">'1'</span>,
                         <span style="color:#996600;">'priority'</span>         <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">'0'</span>,
                         <span style="color:#996600;">'ratio'</span>            <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">'1'</span><span style="color:#006600; font-weight:bold;">&#125;</span>
    <span style="color:#006600; font-weight:bold;">&#125;</span>,
    minimum_active_member           <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">'1'</span>,
    minimum_up_member               <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">'0'</span>,
  <span style="color:#006600; font-weight:bold;">&#125;</span>
<span style="color:#006600; font-weight:bold;">&#125;</span></pre></td></tr></table></div>

<p>When the puppet device command is executed again this will update the iRule and ensure the appropriate members are in the webapp pool:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">$ puppet device <span style="color: #660033;">--deviceconf</span> <span style="color: #000000; font-weight: bold;">/</span>etc<span style="color: #000000; font-weight: bold;">/</span>puppetlabs<span style="color: #000000; font-weight: bold;">/</span>puppet<span style="color: #000000; font-weight: bold;">/</span>device<span style="color: #000000; font-weight: bold;">/</span>f5.puppetlabs.lan.conf</pre></div></div>

<p><a href="http://puppetlabs.com/wp-content/uploads/2012/01/Screen-Shot-2012-01-30-at-10.58.35-PM.png"><img class="alignnone  wp-image-12012" title="f5_gui" src="http://puppetlabs.com/wp-content/uploads/2012/01/Screen-Shot-2012-01-30-at-10.58.35-PM.png" alt="" width="635" height="320" /></a></p>
<p>A limitation to watch out for in the current Puppet release is that &#8216;puppet apply&#8217; and &#8216;puppet resource&#8217; cannot modify network resources. However, we implemented a feature to allow puppet resource to query a F5 device. (For authors of types/providers, making changes to resources aren’t supported until apply_to_device in resources type are handled differently by puppet apply/resource commands). For now we use url facts to establish connectivity to specific F5 devices:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #7a0874; font-weight: bold;">export</span> <span style="color: #007800;">RUBYLIB</span>=<span style="color: #000000; font-weight: bold;">/</span>etc<span style="color: #000000; font-weight: bold;">/</span>puppetlabs<span style="color: #000000; font-weight: bold;">/</span>puppet<span style="color: #000000; font-weight: bold;">/</span>modules<span style="color: #000000; font-weight: bold;">/</span>f5<span style="color: #000000; font-weight: bold;">/</span>lib<span style="color: #000000; font-weight: bold;">/</span>
<span style="color: #7a0874; font-weight: bold;">export</span> <span style="color: #007800;">FACTER_url</span>=https:<span style="color: #000000; font-weight: bold;">//</span>admin:password<span style="color: #000000; font-weight: bold;">@</span>f5.puppetlabs.lan<span style="color: #000000; font-weight: bold;">/</span>Common
puppet resource f5_rule</pre></div></div>


<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">f5_rule <span style="color:#006600; font-weight:bold;">&#123;</span> <span style="color:#996600;">'_sys_https_redirect'</span>:
  <span style="color:#9966CC; font-weight:bold;">ensure</span>     <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">'present'</span>,
  definition <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">'    when HTTP_REQUEST {
set host [HTTP::host]
HTTP::respond 302 Location &quot;https://$host/&quot;
}'</span>,
<span style="color:#006600; font-weight:bold;">&#125;</span>
f5_rule <span style="color:#006600; font-weight:bold;">&#123;</span> <span style="color:#996600;">'_sys_auth_ssl_cc_ldap'</span>:
  <span style="color:#9966CC; font-weight:bold;">ensure</span>     <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">'present'</span>,
  definition <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">'    when CLIENT_ACCEPTED {
set tmm_auth_ssl_cc_ldap_sid 0
set tmm_auth_ssl_cc_ldap_done 0
}
when CLIENTSSL_CLIENTCERT {
…</span></pre></div></div>

<p>If you don’t have Puppet Enterprise 2.0 in your environment yet, you can either download the <a title="Learning Puppet VM" href="http://info.puppetlabs.com/download-learning-puppet-VM.html">Learning Puppet VM</a>, or <a title="Puppet Enterprise installation packages" href="http://info.puppetlabs.com/download-pe2.html">Puppet Enterprise installation packages</a>. F5 also provides <a onclick="_gaq.push(['_trackEvent', 'outbound link', 'F5 module blog post', 'F5 LTM VE']);" href="https://www.f5.com/trial/">F5 LTM Virtual Edition (VE)</a> for trial on VMWare. Please report any issues or bugs to <a href="http://projects.puppetlabs.com/projects/modules/issues">http://projects.puppetlabs.com/projects/modules/issues</a> under the modules section.</p>
<p><em>Additional Resources</em></p>
<ul>
<li><a href="http://forge.puppetlabs.com/puppetlabs/f5">Download the F5 module</a> from the Puppet Forge</li>
<li>Read the intro to managing network devices with Puppet: <a href="http://puppetlabs.com/blog/puppet-network-device-management/">Puppet Network Device Management</a></li>
<li>Learn how to use Puppet with the <a href="http://info.puppetlabs.com/download-learning-puppet-VM.html">Learning Puppet VM</a> or with a free <a href="http://info.puppetlabs.com/download-pe2.html">ten node download of Puppet Enterprise</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://puppetlabs.com/blog/managing-f5-big-ip-network-devices-with-puppet/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>First Look: Installing and Using Hiera (part 1 of 2)</title>
		<link>http://puppetlabs.com/blog/first-look-installing-and-using-hiera/</link>
		<comments>http://puppetlabs.com/blog/first-look-installing-and-using-hiera/#comments</comments>
		<pubDate>Mon, 30 Jan 2012 19:00:57 +0000</pubDate>
		<dc:creator>Hunter Haugen</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[Community]]></category>
		<category><![CDATA[DevOps]]></category>
		<category><![CDATA[Extending Puppet]]></category>
		<category><![CDATA[Hiera]]></category>
		<category><![CDATA[How to]]></category>
		<category><![CDATA[Tips]]></category>
		<category><![CDATA[hiera]]></category>
		<category><![CDATA[how to]]></category>
		<category><![CDATA[puppet]]></category>
		<category><![CDATA[R.I. Pienaar]]></category>
		<category><![CDATA[sysadmin]]></category>
		<category><![CDATA[systems management]]></category>
		<category><![CDATA[tips]]></category>

		<guid isPermaLink="false">http://puppetlabs.com/?p=11080</guid>
		<description><![CDATA[In a previous blog post, we introduced use cases for separating configuration data from Puppet code. This post (part one of a two part series) will go in-depth with installing, configuring, and using Hiera, but let&#8217;s first look at WHY we would need Hiera. Introduction to the SSH module One of the benefits of Hiera [...]]]></description>
			<content:encoded><![CDATA[<p>In a previous blog post, we introduced <a href="http://puppetlabs.com/blog/the-problem-with-separating-data-from-puppet-code/">use cases for separating configuration data from Puppet code</a>. This post (part one of a two part series) will go in-depth with installing, configuring, and using Hiera, but let&#8217;s first look at WHY we would need Hiera.  </p>
<h2>Introduction to the SSH module</h2>
<p>One of the benefits of Hiera is its ability to take an existing module and adapt it to a hierarchical-based lookup system. Typically, one of the first modules that people adapt to Puppet code is the SSH module. Let&#8217;s look at a simple ssh class definition:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
</pre></td><td class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#9966CC; font-weight:bold;">class</span> ssh <span style="color:#006600; font-weight:bold;">&#123;</span>
  <span style="color:#ff6633; font-weight:bold;">$ssh_packages</span>      = <span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;">'openssh'</span>,<span style="color:#996600;">'openssh-clients'</span>,<span style="color:#996600;">'openssh-server'</span><span style="color:#006600; font-weight:bold;">&#93;</span>
  <span style="color:#ff6633; font-weight:bold;">$permit_root_login</span> = <span style="color:#996600;">'no'</span>
  <span style="color:#ff6633; font-weight:bold;">$ssh_users</span>         = <span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;">'root'</span>,<span style="color:#996600;">'jeff'</span>,<span style="color:#996600;">'gary'</span>,<span style="color:#996600;">'hunter'</span><span style="color:#006600; font-weight:bold;">&#93;</span>
&nbsp;
  package <span style="color:#006600; font-weight:bold;">&#123;</span> <span style="color:#ff6633; font-weight:bold;">$ssh_packages</span>:
    <span style="color:#9966CC; font-weight:bold;">ensure</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> present,
    before <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#CC00FF; font-weight:bold;">File</span><span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;">'/etc/ssh/sshd_config'</span><span style="color:#006600; font-weight:bold;">&#93;</span>,
  <span style="color:#006600; font-weight:bold;">&#125;</span>
&nbsp;
  file <span style="color:#006600; font-weight:bold;">&#123;</span> <span style="color:#996600;">'/etc/ssh/sshd_config'</span>:
    <span style="color:#9966CC; font-weight:bold;">ensure</span>  <span style="color:#006600; font-weight:bold;">=&gt;</span> present,
    owner   <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">'root'</span>,
    group   <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">'root'</span>,
    mode    <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">'0644'</span>,
    <span style="color:#008000; font-style:italic;"># Template uses $permit_root_login and $ssh_users</span>
    content <span style="color:#006600; font-weight:bold;">=&gt;</span> template<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">'ssh/sshd_config.erb'</span><span style="color:#006600; font-weight:bold;">&#41;</span>,
  <span style="color:#006600; font-weight:bold;">&#125;</span>
&nbsp;
  service <span style="color:#006600; font-weight:bold;">&#123;</span> <span style="color:#996600;">'sshd'</span>:
    <span style="color:#9966CC; font-weight:bold;">ensure</span>     <span style="color:#006600; font-weight:bold;">=&gt;</span> running,
    enable     <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#0000FF; font-weight:bold;">true</span>,
    hasstatus  <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#0000FF; font-weight:bold;">true</span>,
    hasrestart <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#0000FF; font-weight:bold;">true</span>,
  <span style="color:#006600; font-weight:bold;">&#125;</span>
<span style="color:#006600; font-weight:bold;">&#125;</span></pre></td></tr></table></div>

<p>The template used above looks like the following:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
</pre></td><td class="code"><pre class="ruby" style="font-family:monospace;">Protocol 2
SyslogFacility AUTHPRIV
PasswordAuthentication yes
ChallengeResponseAuthentication no
GSSAPIAuthentication yes
GSSAPICleanupCredentials yes
&nbsp;
# PermitRootLogin Setting
PermitRootLogin <span style="color:#006600; font-weight:bold;">&lt;%</span>= permit_root_login <span style="color:#006600; font-weight:bold;">%&gt;</span>
&nbsp;
# Allow individual Users
<span style="color:#006600; font-weight:bold;">&lt;%</span> ssh_users.<span style="color:#9900CC;">each</span> <span style="color:#9966CC; font-weight:bold;">do</span> <span style="color:#006600; font-weight:bold;">|</span>user<span style="color:#006600; font-weight:bold;">|</span> <span style="color:#006600; font-weight:bold;">-%&gt;</span>
AllowUser <span style="color:#006600; font-weight:bold;">&lt;%</span>= user <span style="color:#006600; font-weight:bold;">%&gt;</span>
<span style="color:#006600; font-weight:bold;">&lt;%</span> <span style="color:#9966CC; font-weight:bold;">end</span> <span style="color:#006600; font-weight:bold;">-%&gt;</span>
&nbsp;
# Accept locale-related environment variables
AcceptEnv LANG LC_CTYPE LC_NUMERIC LC_TIME LC_COLLATE LC_MONETARY LC_MESSAGES
AcceptEnv LC_PAPER LC_NAME LC_ADDRESS LC_TELEPHONE LC_MEASUREMENT
AcceptEnv LC_IDENTIFICATION LC_ALL
X11Forwarding yes
Subsystem	sftp	/usr/libexec/openssh/sftp-server</pre></td></tr></table></div>

<p>This module declares three packages (<code>openssh</code>, <code>openssh-clients</code>, <code>openssh-server</code>), ensures a proper <code>sshd_config</code> file, and starts the sshd service. While this works fine for RedHat distributions, there will be a problem with this module if we try and use it on other Linux variants (such as Debian or Ubuntu). Normally, logic is introduced into the module that decides which package names to use based on the operating system of the node. Instead of doing that, let&#8217;s use Hiera to solve our problem by changing three lines:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#ff6633; font-weight:bold;">$ssh_packages</span>      = hiera<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">'ssh_packages'</span><span style="color:#006600; font-weight:bold;">&#41;</span>
<span style="color:#ff6633; font-weight:bold;">$permit_root_login</span> = hiera<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">'permit_root_login'</span><span style="color:#006600; font-weight:bold;">&#41;</span>
<span style="color:#ff6633; font-weight:bold;">$ssh_users</span>         = hiera<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">'ssh_users'</span><span style="color:#006600; font-weight:bold;">&#41;</span></pre></div></div>

<p>Instead of providing a simple array, we&#8217;re now going to utilize Hiera and do a data lookup for the packages to declare in our module, the users to permit, and the permit_root_login parameter that will be used in the sshd_config file. An array will still be returned by Hiera for the $ssh_packages and $ssh_users variables, but the elements in that array will change depending on the operating system of the node. Before we can do this, though, we need to setup Hiera, its hierarchy, and the data directory that it will use for parameter lookups.</p>
<h2>Install Hiera</h2>
<p>As of this writing, Hiera is not installed with Puppet or Puppet Enterprise and must be installed using RubyGems—though it will be included in the next version of Puppet. Hiera has two separate gems: <tt style="font: 14px Courier New">hiera</tt> and <tt style="font: 14px Courier New">hiera-puppet</tt>. The <tt style="font: 14px Courier New">hiera</tt> gem contains the hiera library source code, the default YAML backend, and the hiera binary that can be used to execute lookups from the command line. The <tt style="font: 14px Courier New">hiera-puppet</tt> gem contains the custom functions necessary to call Hiera from Puppet. To install these libraries, do the following:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
</pre></td><td class="code"><pre class="shell" style="font-family:monospace;">gem install hiera hiera-puppet</pre></td></tr></table></div>

<p>(Note that if you&#8217;re running Puppet Enterprise, you will need to use the <tt style="font: 14px Courier New">gem</tt> binary that&#8217;s located in <tt style="font: 14px Courier New">/opt/puppet/bin</tt>)</p>
<p>The last step that&#8217;s necessary is to get the custom Hiera functions that Puppet needs to do a parameter lookup loaded into Puppet itself. These functions come bundled with the <tt style="font: 14px Courier New">hiera-puppet</tt> gem, but they currently are placed into your system&#8217;s <tt style="font: 14px Courier New">$GEMPATH</tt> and are not loaded by Puppet. To remedy this, let&#8217;s download a copy of <tt style="font: 14px Courier New">hiera-puppet</tt> from source and place it in our Puppet Master&#8217;s modulepath so it can make the functions available from within Puppet.</p>
<ol>
<ol>
<li>Get your Puppet Master&#8217;s module path by entering <tt style="font: 14px Courier New">puppet master --configprint modulepath</tt></li>
<li>Change to the modulepath directory that was output from the previous step</li>
<li>Enter the following command to download a tarball of the hiera-puppet source code, create a directory called &#8216;hiera-puppet&#8217;, expand the contents of the tarball to the &#8216;hiera-puppet&#8217; directory, and remove the &#8216;hiera-puppet&#8217; tarball:</li>
</ol>
</ol>
<p><strong><br />
</strong></p>

<div class="wp_syntax"><div class="code"><pre class="shell" style="font-family:monospace;">curl -L https://github.com/puppetlabs/hiera-puppet/tarball/master -o \
'hiera-puppet.tar.gz' &amp;&amp; mkdir hiera-puppet &amp;&amp; tar -xzf hiera-puppet.tar.gz \
-C hiera-puppet --strip-components 1 &amp;&amp; rm hiera-puppet.tar.gz</pre></div></div>

<p>Now the custom Hiera functions are available to be used by the Puppet Master. Let&#8217;s move on to configuring Hiera.</p>
<h2>Configuring Hiera with YAML &amp; <tt style="font: 20px Courier New">hiera.yaml</tt></h2>
<p>Hiera is configured through the <tt style="font: 14px Courier New">/etc/puppetlabs/puppet/hiera.yaml</tt> configuration file. This file is written in the markup language called YAML which is simple, human-readable, and is widely supported by scripting languages. (<a href="http://www.yaml.org/">You can read more about YAML here</a>.)</p>
<p>The hiera.yaml configuration file is what Hiera uses to determine the order of its lookup, and the location of the data directory where the YAML files are located. Lets look at an example <tt style="font: 14px Courier New">hiera.yaml</tt> configuration file that we can drop into place for our ssh module and break it down piece by piece:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
</pre></td><td class="code"><pre class="yaml" style="font-family:monospace;">---
:hierarchy:
    - %{operatingsystem}
    - common
:backends:
    - yaml
:yaml:
    :datadir: '/etc/puppetlabs/puppet/hieradata'</pre></td></tr></table></div>

<p>We see that our chosen backend is <tt>YAML</tt>, and that our data will be stored in <tt style="font: 14px Courier New">/etc/puppetlabs/puppet/hieradata</tt> instead of embedding it in our modules. This is looking promising!</p>
<p>The last, and also the most important, piece is the hierarchy itself. We&#8217;ve chosen to have two levels: a <tt style="font: 14px Courier New">common</tt> level that is common to all hosts, and a higher-priority level that contains any operating-system-specific data.</p>
<p>When we query a <tt style="font: 14px Courier New">hiera()</tt> function in Puppet, Hiera looks in its <tt style="font: 14px Courier New">hiera.yaml</tt> configuration file for backends to query, and for the directory where the backend data is kept. Lets look at how we might add configuration data to Hiera&#8217;s datadir.</p>
<h2>Introduction to the YAML data backend</h2>
<p>The YAML data backend is the quickest Hiera backend to begin using, and is included with Hiera. YAML is an extremely readable data serialization format, so it makes sense to utilize it if you don&#8217;t have a specific need for another format. In the <tt style="font: 14px Courier New">hiera.yaml</tt> configuration file above, we created a hierarchy of two levels: <tt style="font: 14px Courier New">%{operatingsystem}</tt> and common. Assuming that we are configuring a RedHat system, Hiera will look in the <tt style="font: 14px Courier New">datadir</tt> directory for two files in this order: RedHat.yaml and <tt style="font: 14px Courier New">common.yaml</tt>. Why? The highest level in the hierarchy queries Facter for the <tt style="font: 14px Courier New">operatingsystem</tt> fact (which, in this case, returns &#8216;RedHat&#8217;), and then searches for a YAML file of that name. The second level is just the string <tt style="font: 14px Courier New">common</tt>, so it looks for a file called &#8216;common.yaml&#8217;. Let&#8217;s take a look at those files:</p>
<h3>RedHat.yaml</h3>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
</pre></td><td class="code"><pre class="yaml" style="font-family:monospace;">---
ssh_packages: - 'openssh'
              - 'openssh-clients'
              - 'openssh-server'</pre></td></tr></table></div>

<h3>common.yaml</h3>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
</pre></td><td class="code"><pre class="yaml" style="font-family:monospace;">---
permit_root_login : 'no'
ssh_users         : - root
                    - jeff
                    - gary
                    - hunter</pre></td></tr></table></div>

<p>With the hiera.yaml configuration file setup and our Hiera data directory containing YAML files, we can actually begin performing lookups and inspecting the resultant data.</p>
<h2>Hiera data lookups</h2>
<p>Using our RedHat node and the current Hiera setup, what would be the value of $permit_root_login in this line from our ssh Puppet manifest:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#ff6633; font-weight:bold;">$permit_root_login</span> = hiera<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">'permit_root_login'</span><span style="color:#006600; font-weight:bold;">&#41;</span></pre></div></div>

<p>The answer is &#8216;no&#8217;. How did we get that? Hiera performed a lookup for &#8216;permit_root_login&#8217; and searched the highest priority file in the hierarchy &#8211; RedHat.yaml (based on the node&#8217;s &#8216;<tt style="font: 14px Courier New">operatingsystem</tt>&#8216; fact being the string &#8216;<tt style="font: 14px Courier New">RedHat</tt>&#8216;). Hiera didn&#8217;t find the parameter in that file so it moved to the next, and final, level of the hierarchy and searched common.yaml. Because the parameter is defined in common.yaml, it returned the value back to Puppet.</p>
<p>What if we wanted all RedHat nodes to set the value of $permit_root_login to be &#8216;without-password&#8217;? Using Hiera, we would modify the RedHat.yaml file and add the following line:</p>

<div class="wp_syntax"><div class="code"><pre class="yaml" style="font-family:monospace;">permit_root_login : 'without-password'</pre></div></div>

<p>Because the RedHat.yaml file is queried BEFORE the common.yaml file, RedHat nodes would get this value, while all other nodes would get the value of &#8216;no&#8217; from common.yaml. Taking this example one step further, what if we wanted all Debian nodes to have the value of $permit_root_login set to &#8216;yes&#8217;? We would need to create a file called Debian.yaml, place it in the Hiera data directory, and enter the following:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
</pre></td><td class="code"><pre class="yaml" style="font-family:monospace;">---
permit_root_login : 'yes'</pre></td></tr></table></div>

<p>Now, when a Debian node contacted Puppet, Hiera would query the Debian.yaml file BEFORE common.yaml, and the value of $permit_root_login would get the value set in Debian.yaml (which, in this case, would be &#8216;yes&#8217;).</p>
<p>This logic could be repeated over and over for any parameter and with as many hierarchy levels as you desire.</p>
<h2>Beyond Basic Lookups: Concatenating Values With Hiera</h2>
<p>By default, Hiera uses a priority lookup—which means that the first time it encounters a parameter in the hierarchy it accepts that value and returns it to Puppet. This is how higher levels in the hierarchy can override values that might be set in lower levels of the hierarchy. What if you wanted to search through ALL levels of the hierarchy and return EVERY value for a specific parameter? Hiera has that ability with the hiera_hash() and hiera_array() functions.</p>
<p>There are two variables that currently return arrays: $ssh_packages and $ssh_users. Right now, the variables are being set with a priority lookup—so the ENTIRE contents of the array is being set when Hiera first encounters the &#8216;ssh_users&#8217; and &#8216;ssh_packages&#8217; parameter in its lookup. What if we wanted this value to always contain the root user, but other users should change depending on what operating system a node was using? The best way to do this would be to use the hiera_array() function that searches ALL hierarchy levels and returns an array containing the value of ssh_users from EVERY hierarchy level in which it encountered the parameter. Let&#8217;s modify our Hiera YAML files to reflect this change:</p>
<h3>common.yaml</h3>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
</pre></td><td class="code"><pre class="yaml" style="font-family:monospace;">---
permit_root_login : 'no'
ssh_users         : - root</pre></td></tr></table></div>

<h3>RedHat.yaml</h3>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
</pre></td><td class="code"><pre class="yaml" style="font-family:monospace;">---
ssh_packages: - 'openssh'
              - 'openssh-clients'
              - 'openssh-server'
ssh_users   : - 'gary'
              - 'jeff'</pre></td></tr></table></div>

<h3>Debian.yaml</h3>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
</pre></td><td class="code"><pre class="yaml" style="font-family:monospace;">---
permit_root_login : 'yes'
ssh_users         : - 'hunter'</pre></td></tr></table></div>

<p>Finally, modify the following line in the ssh module:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#ff6633; font-weight:bold;">$ssh_users</span>         = hiera_array<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">'ssh_users'</span><span style="color:#006600; font-weight:bold;">&#41;</span></pre></div></div>

<p>After making the changes, which users will be added to /etc/ssh/sshd_config file on a RedHat node? The answer is root, gary, and jeff. Why? The root user will ALWAYS be included in /etc/ssh/sshd_config because the common.yaml file that EVERY node evaluates contains the value of &#8216;root&#8217; for the ssh_users parameter. Next, because this is a RedHat node, Hiera will concatenate the values of &#8216;gary&#8217; and &#8216;jeff&#8217; to the array because those are the values for the ssh_users parameter in RedHat.yaml. What if we run this on a Debian node? The answer is root and hunter (because the value of the ssh_users parameter in the Debian.yaml file is &#8216;hunter&#8217;).</p>
<h2>Hiera Best Practices</h2>
<p>Hiera is still new to many people, and the concept of a hierarchical lookup system can seem a bit foreign initially. Because of this, there are a couple of best practices that are important to observe when getting started with Hiera and Puppet.</p>
<h3>Keep hierarchies to a minimum</h3>
<p>This is the time-proven rule of &#8220;Just because you can, doesn&#8217;t mean you should.&#8221; Hierarchy levels are incredibly dynamic tools that will allow you to do a number of things that were previously difficult, but too many of them can lead to problems when debugging (i.e. &#8220;Where was that parameter set, again?&#8221;). Three to four hierarchy levels should be enough for most sites; if you have more than that, you might want to re-think your approach.</p>
<h3>Version control your Hiera data directory separately from your Puppet repository</h3>
<p>The benefit of the :datadir: parameter in hiera.yaml is that you can use Facter fact values to determine the path of your Hiera data directory. For example, a site using two Puppet environments called &#8216;development&#8217; and &#8216;production&#8217; that has implemented the ssh module we outlined above might have the following directory tree at /etc/puppetlabs/puppet/environments</p>

<div class="wp_syntax"><div class="code"><pre class="" style="font-family:monospace;">environments/
    |-- development
    |   |-- hieradata
    |   |   |-- Debian.yaml
    |   |   |-- RedHat.yaml
    |   |   `-- common.yaml
    |   |-- manifests
    |   |   `-- site.pp
    |   `-- modules
    |       `-- ssh
    `-- production
        |-- hieradata
        |   |-- Debian.yaml
        |   |-- RedHat.yaml
        |   `-- common.yaml
        |-- manifests
        |   `-- site.pp
        `-- modules
            `-- ssh</pre></div></div>

<p>This site&#8217;s hiera.yaml configuration file would look like the following:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
</pre></td><td class="code"><pre class="yaml" style="font-family:monospace;">---
:hierarchy:
    - %{operatingsystem}
    - common
:backends:
    - yaml
:yaml:
    :datadir: '/etc/puppetlabs/puppet/environments/%{environment}/hieradata'</pre></td></tr></table></div>

<p>Hiera automatically substitues the value of the current environment for %{environment} in hiera.yaml and allows for a Hiera data directory that&#8217;s completely separate from Puppet manifests/modules.</p>
<h2>What now?</h2>
<p>This post serves as an introduction to using Hiera with Puppet and familiarizes you with the concepts of hierarchical lookup systems, priority lookups, multilevel lookups, and data separation. The concepts in this post will walk you through getting a working Hiera setup, but there is much more that can be done (Hiera as an ENC, custom backends, etc…). The next post in this series will introduce these advanced Hiera concepts and much more. Until then, enjoy experimenting with Hiera!</p>
<p><em>Additional Resources</em></p>
<ul>
<li>Read about <a href="http://puppetlabs.com/blog/the-problem-with-separating-data-from-puppet-code/">separating data from Puppet code</a></li>
<li>Keep an eye on the <a href="http://projects.puppetlabs.com/projects/hiera">Hiera project</a> in RedMine</li>
<li><a href="http://www.craigdunn.org/2011/10/puppet-configuration-variables-and-hiera/">Puppet Configuration Variables and Hiera</a></li>
<li><a href="http://www.craigdunn.org/2011/10/secret-variables-in-puppet-with-hiera-and-gpg/">Secret Variables in Puppet with Hiera and GPG</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://puppetlabs.com/blog/first-look-installing-and-using-hiera/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Open-Future Sponsored Puppet Master Training: Brussels</title>
		<link>http://puppetlabs.com/events/open-future-sponsored-puppet-master-training-brussels/</link>
		<comments>http://puppetlabs.com/events/open-future-sponsored-puppet-master-training-brussels/#comments</comments>
		<pubDate>Fri, 27 Jan 2012 22:11:51 +0000</pubDate>
		<dc:creator>michelle</dc:creator>
				<category><![CDATA[Events]]></category>

		<guid isPermaLink="false">http://puppetlabs.com/events/open-future-sponsored-puppet-master-training-brussels/</guid>
		<description><![CDATA[Puppet Master Curriculum (3 Days) This training is ideal for those who want a Puppet jumpstart. Newer members at an organization already using Puppet, or experienced sysadmins wanting to bring Puppet into their team will get everything they need to deploy solutions. Register Now Attendees should have at least the equivalent experience of a junior [...]]]></description>
			<content:encoded><![CDATA[<h2>Puppet Master Curriculum (3 Days)</h2>
<p>This training is ideal for those who want a Puppet jumpstart. Newer members at an organization already using Puppet, or experienced sysadmins wanting to bring Puppet into their team will get everything they need to deploy solutions.</p>
<p><b><a href="https://open-future.be/puppet-master-training">Register Now</a></b></p>
<p>Attendees should have at least the equivalent experience of a junior Unix/Linux administrator.</p>
<h3>Topics covered include:</h3>
<ul>
<li class="bullet">Configuring Puppet and Puppetmaster</li>
<li class="bullet">Resource Types and the Resource Abstration Layer</li>
<li class="bullet">Virtual Resources, Exported Resources and Stored Configs</li>
<li class="bullet">Meta-parameters, Dependencies and Events</li>
<li class="bullet">Classes, Modules and Definitions</li>
<li class="bullet">Tags and Environments</li>
<li class="bullet">Puppet Language Patterns and Best Practices</li>
</ul>
<p>The topics are covered over 3 days. Sessions will mix theory and practice, balancing lectures with hands-on exercises. (Each student should bring a WiFi enabled laptop with VMWare installed to participate in the labs.)</p>
<h2>Pricing</h2>
<ul>
<li>2 195 € (+21% VAT)</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://puppetlabs.com/events/open-future-sponsored-puppet-master-training-brussels/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>The Problem with Separating Data from Puppet Code</title>
		<link>http://puppetlabs.com/blog/the-problem-with-separating-data-from-puppet-code/</link>
		<comments>http://puppetlabs.com/blog/the-problem-with-separating-data-from-puppet-code/#comments</comments>
		<pubDate>Fri, 27 Jan 2012 17:45:57 +0000</pubDate>
		<dc:creator>Gary Larizza</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[Extending Puppet]]></category>
		<category><![CDATA[How to]]></category>
		<category><![CDATA[Systems Management]]></category>
		<category><![CDATA[enc]]></category>
		<category><![CDATA[hiera]]></category>
		<category><![CDATA[how to]]></category>
		<category><![CDATA[puppet]]></category>
		<category><![CDATA[tips]]></category>

		<guid isPermaLink="false">http://puppetlabs.com/?p=10925</guid>
		<description><![CDATA[You&#8217;ve bought Pro Puppet, downloaded a couple of modules from the Puppet Forge (and have written some of your own too), and you&#8217;re on your way to implementing your Puppet environment when it hits you: something feels bulky with the way you&#8217;ve designed your Puppet code. Your modules may not be portable between environments (development, [...]]]></description>
			<content:encoded><![CDATA[<p>You&#8217;ve bought <a title="Pro Puppet" href="http://www.amazon.com/Pro-Puppet-James-Turnbull/dp/1430230576/ref=sr_1_1?ie=UTF8&amp;qid=1323832335&amp;sr=8-1" target="_blank">Pro Puppet</a>, downloaded a couple of modules from the <a href="http://forge.puppetlabs.com">Puppet Forge</a> (and have written some of your own too), and you&#8217;re on your way to implementing your Puppet environment when it hits you: something feels bulky with the way you&#8217;ve designed your Puppet code. Your modules may not be portable between environments (development, testing, production) without significant tweaks, each of your node declarations may require a number of variables in order for the code to work, or you&#8217;re constantly needing to open up your modules to account for changes in your environment.</p>
<h3><strong>There&#8217;s GOT to be an easier way to do this, right? </strong></h3>
<p>We hear stories from many customers about problems in their Puppet environments, and many of them can be traced back to the way their configuration data is integrated with their Puppet code. Configuration data is the term we use for the environment-specific data that needs to be plugged in to your Puppet code (i.e. variables, class parameters). Take the following bit of Puppet code for example:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
</pre></td><td class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#ff6633; font-weight:bold;">$dnsserver</span>    = <span style="color:#996600;">'8.8.8.8'</span>
<span style="color:#ff6633; font-weight:bold;">$searchdomain</span> = <span style="color:#996600;">'puppetlabs.vm'</span>
&nbsp;
file <span style="color:#006600; font-weight:bold;">&#123;</span> <span style="color:#996600;">'/etc/resolv.conf'</span>:
  <span style="color:#9966CC; font-weight:bold;">ensure</span>  <span style="color:#006600; font-weight:bold;">=&gt;</span> present
  content <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">&quot;search ${searchdomain}<span style="color:#000099;">\n</span> nameserver ${dnsserver}<span style="color:#000099;">\n</span>&quot;</span>,
<span style="color:#006600; font-weight:bold;">&#125;</span></pre></td></tr></table></div>

<p>The configuration data in this example would be the hard-coded variables $dnsserver and $searchdomain and the Puppet code would be the file resource block declaring /etc/resolv.conf. This example is intentionally kept simple in order to highlight the methods by which you will separate your configuration data from your Puppet code, but imagine code that needs to set different variables in different environments (MySQL servers, databases, usernames, and passwords, for example) and you can see how the above example can quickly become unwieldy. How else can this be done?</p>
<h2></h2>
<h2>Legacy Method &#8211; Node Inheritance</h2>
<p>The first method that people usually tried was node inheritance. By defining variables in separate node definition blocks, and inheriting from a nested list of definitions, you could SIMULATE data separation with this method. This was the go-to method before Puppet 2.6 was released, and as such we consider it to be a legacy solution that we don&#8217;t recommend using with versions of Puppet newer than 0.25 (note that if you&#8217;re still using node inheritance, please read this advisory on <a title="http://docs.puppetlabs.com/guides/scope_and_puppet.html" href="http://docs.puppetlabs.com/guides/scope_and_puppet.html" target="_blank">dynamic scoping</a>).</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
</pre></td><td class="code"><pre class="ruby" style="font-family:monospace;">node common <span style="color:#006600; font-weight:bold;">&#123;</span>
  <span style="color:#ff6633; font-weight:bold;">$dnsserver</span>    = <span style="color:#996600;">'8.8.8.8'</span>
  <span style="color:#ff6633; font-weight:bold;">$searchdomain</span> = <span style="color:#996600;">'puppetlabs.vm'</span>
<span style="color:#006600; font-weight:bold;">&#125;</span>
&nbsp;
node production inherits common <span style="color:#006600; font-weight:bold;">&#123;</span>
  <span style="color:#ff6633; font-weight:bold;">$dnsserver</span> = <span style="color:#996600;">'10.13.1.3'</span>
<span style="color:#006600; font-weight:bold;">&#125;</span>
&nbsp;
node <span style="color:#996600;">'agent.puppetlabs.vm'</span> inherits production <span style="color:#006600; font-weight:bold;">&#123;</span>
  file <span style="color:#006600; font-weight:bold;">&#123;</span> <span style="color:#996600;">'/etc/resolv.conf'</span>:
    content <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">&quot;search ${searchdomain}<span style="color:#000099;">\n</span> nameserver ${dnsserver}<span style="color:#000099;">\n</span>&quot;</span>,
  <span style="color:#006600; font-weight:bold;">&#125;</span>
<span style="color:#006600; font-weight:bold;">&#125;</span></pre></td></tr></table></div>

<h3>PROS</h3>
<ul>
<li>It was the easiest method to employ.</li>
<li>Your data was in one location and, technically, separate from your modules.</li>
</ul>
<h3>CONS</h3>
<ul>
<li>There was no easy way to find the value of a variable for a specific node.</li>
<li>FINDING the value of a variable required &#8220;human parsing,&#8221; or reading through each and every node declaration to trace variable values.</li>
<li>The data still resided in your Puppet code repository.</li>
<li>There are better ways to implement this strategy, and <strong>this should be considered a legacy solution provided solely for information purposes</strong>.</li>
</ul>
<h2>Parameterized Classes</h2>
<p>Puppet version 2.6 gave us the ability to pass parameters with class declarations. This allows you to completely remove configuration data from your classes and provide &#8216;sane&#8217; default values should a class declaration not pass a parameter. While this is an entry-level step in beginning to separate your configuration data from your Puppet code (the data is now in its own class—in this case <strong>dns::params</strong>), the configuration data is STILL in your Puppet code repository (and thus isn&#8217;t a full separation). See below for an example:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
</pre></td><td class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#9966CC; font-weight:bold;">class</span> dns::params <span style="color:#006600; font-weight:bold;">&#123;</span>
  <span style="color:#ff6633; font-weight:bold;">$dnsserver</span>    = <span style="color:#996600;">'8.8.8.8'</span>
  <span style="color:#ff6633; font-weight:bold;">$searchdomain</span> = <span style="color:#996600;">'puppetlabs.vm'</span>
<span style="color:#006600; font-weight:bold;">&#125;</span>
&nbsp;
<span style="color:#9966CC; font-weight:bold;">class</span> dns<span style="color:#006600; font-weight:bold;">&#40;</span>
  <span style="color:#ff6633; font-weight:bold;">$dnsserver</span>    = <span style="color:#ff6633; font-weight:bold;">$dns</span>::params::dnsserver,
  <span style="color:#ff6633; font-weight:bold;">$searchdomain</span> = <span style="color:#ff6633; font-weight:bold;">$dns</span>::params::searchdomain
<span style="color:#006600; font-weight:bold;">&#41;</span> inherits dns::params <span style="color:#006600; font-weight:bold;">&#123;</span>
&nbsp;
  file <span style="color:#006600; font-weight:bold;">&#123;</span> <span style="color:#996600;">'/etc/resolv.conf'</span>:
    content <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">&quot;search ${searchdomain}<span style="color:#000099;">\n</span> nameserver ${dnsserver}<span style="color:#000099;">\n</span>&quot;</span>,
  <span style="color:#006600; font-weight:bold;">&#125;</span>
<span style="color:#006600; font-weight:bold;">&#125;</span></pre></td></tr></table></div>

<h3>PROS</h3>
<ul>
<li>Class parameters can be defaulted back to a &#8216;sane&#8217; value as outlined in our <a href="http://docs.puppetlabs.com/guides/parameterized_classes.html#appendix-smart-parameter-defaults">Smart Parameter Defaults</a> document.</li>
<li>Modules that utilize this methodology are more portable—parameters need only be changed in a single &#8216;params&#8217; class.</li>
</ul>
<h3>CONS</h3>
<ul>
<li>All logic must be embedded in each module&#8217;s &#8216;params&#8217; class.</li>
<li>If you use this methodology to keep your configuration data separate, every module must have a &#8216;params&#8217; class and any logic you introduce (picking different values based on operating system, for example) must be repeated in every module.</li>
<li>The data isn&#8217;t truly separate from your Puppet code as it still resides INSIDE the module (and, technically, your Puppet code repository).</li>
</ul>
<h2>External Node Classifier</h2>
<p>Many large sites decide to use an <a title="http://docs.puppetlabs.com/guides/external_nodes.html" href="http://docs.puppetlabs.com/guides/external_nodes.html" target="_blank">External Node Classifier script</a> to solve the problem of looking up configuration data. External Node Classifiers (also known as ENCs) allow you to provide class declarations, parameters, and variables to Puppet in the form of YAML. The previous example would look like this in YAML:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
</pre></td><td class="code"><pre class="yaml" style="font-family:monospace;">classes:
  - dns
parameters:
  searchdomain :  ‘puppetlabs.vm’
  dnsserver    :  ‘8.8.8.8’</pre></td></tr></table></div>

<h3>PROS</h3>
<ul>
<li>Flexible &#8211; you design how the information lookup is done (query a database, parse a hostname or other Facter fact, etc).</li>
<li>Can be written in any language: shell, perl, ruby, python, etc…</li>
<li>Plugs into your existing CMDB (Configuration Management Database) to retrieve information that already exists in another source of truth</li>
</ul>
<h3>CONS</h3>
<ul>
<li>You are responsible for writing and maintaining the External Node Classifier Script</li>
<li>If the script breaks, your Puppet runs are endangered</li>
</ul>
<h2>Extlookup</h2>
<p>Extlookup was <a title="http://docs.puppetlabs.com/references/2.6.1/function.html#extlookup" href="http://docs.puppetlabs.com/references/2.6.1/function.html#extlookup" target="_blank">introduced in Puppet version 2.6.0</a> as a hierarchical way to lookup values of parameters or variables based on a Facter fact value. To use Extlookup, you would first define a data directory that Extlookup would search based on a specific fact value (location, environment, operatingsystem, etc), and then you would specify a lookup precedence (look for a parameter/variable in a file named after the node&#8217;s certname FIRST, and then search in a file named after the node&#8217;s environment SECOND, and so on). Finally, you would assign a parameter/variable&#8217;s value by invoking Extlookup with the built-in (as of Puppet version 2.6.0) &#8216;extlookup()&#8217; function.</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
</pre></td><td class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#ff6633; font-weight:bold;">$extlookup_datadir</span>    = <span style="color:#996600;">&quot;/etc/puppetlabs/puppet/data&quot;</span>
<span style="color:#ff6633; font-weight:bold;">$extlookup_precedence</span> = <span style="color:#006600; font-weight:bold;">&#91;</span>$environment, <span style="color:#996600;">'common'</span><span style="color:#006600; font-weight:bold;">&#93;</span>
&nbsp;
node <span style="color:#996600;">'agent.puppetlabs.vm'</span> <span style="color:#006600; font-weight:bold;">&#123;</span>
  <span style="color:#9966CC; font-weight:bold;">include</span> dns
<span style="color:#006600; font-weight:bold;">&#125;</span>
&nbsp;
<span style="color:#9966CC; font-weight:bold;">class</span> dns <span style="color:#006600; font-weight:bold;">&#123;</span>
  <span style="color:#ff6633; font-weight:bold;">$dnsserver</span>    = extlookup<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">'dnsserver'</span><span style="color:#006600; font-weight:bold;">&#41;</span>
  <span style="color:#ff6633; font-weight:bold;">$searchdomain</span> = extlookup<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">'searchdomain'</span><span style="color:#006600; font-weight:bold;">&#41;</span>
&nbsp;
  file <span style="color:#006600; font-weight:bold;">&#123;</span> <span style="color:#996600;">'/etc/resolv.conf'</span>:
    content <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">&quot;search ${searchdomain}<span style="color:#000099;">\n</span> nameserver ${dnsserver}<span style="color:#000099;">\n</span>&quot;</span>,
  <span style="color:#006600; font-weight:bold;">&#125;</span>
<span style="color:#006600; font-weight:bold;">&#125;</span></pre></td></tr></table></div>

<h3>Sample common.csv file used with Extlookup</h3>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
</pre></td><td class="code"><pre class="csv" style="font-family:monospace;">dnsserver, '8.8.8.8'
searchdomain, 'puppetlabs.vm'</pre></td></tr></table></div>

<h3>PROS</h3>
<ul>
<li>Extlookup supports a dynamic and hierarchical lookup based on a node&#8217;s Facter fact values.</li>
<li>There could be a single node declaration that would use Extlookup to look up the value of every variable/parameter used in Puppet.</li>
<li>The extlookup() function is built into Puppet as of version 2.6.0.</li>
</ul>
<h3>CONS</h3>
<ul>
<li>You must use comma-separated value files (CSV) ONLY for your lookups (i.e. variable, value), so structured data (like arrays and hashes) is not supported.</li>
<li>Data lookups only return the first-matched value.</li>
<li>It doesn&#8217;t have the ability to concatenate a list of matches returned throughout the full hierarchy.</li>
</ul>
<h2>Introducing: Hiera</h2>
<p>Hiera, short for &#8220;hierarchy&#8221; and written by R.I. Pienaar, is a pluggable, hierarchical database that can query YAML and JSON files (and any other data serialization for which you write a custom backend), as well as Puppet manifests, for configuration data. Hiera builds upon the model that Extlookup created and also adds support for structured data. With Hiera, you can dynamically lookup parameters based on a node&#8217;s Facter facts. Let&#8217;s look configuring Hiera for use with the previous example:</p>
<h3>The hiera.yaml configuration file:</h3>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
</pre></td><td class="code"><pre class="yaml" style="font-family:monospace;">---
:backends: - yaml
:hierarchy: - %{environment}
            - common
:yaml:
    :datadir: /etc/puppetlabs/puppet/hieradata</pre></td></tr></table></div>

<h3>The common.yaml file that Hiera uses for parameter lookup:</h3>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
</pre></td><td class="code"><pre class="yaml" style="font-family:monospace;">---
dnsserver    : '8.8.8.8'
searchdomain : 'puppetlabs.vm'</pre></td></tr></table></div>

<h3>Puppet code using Hiera:</h3>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
</pre></td><td class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#9966CC; font-weight:bold;">class</span> dns <span style="color:#006600; font-weight:bold;">&#123;</span>
  <span style="color:#ff6633; font-weight:bold;">$dnsserver</span>    = hiera<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">'dnsserver'</span><span style="color:#006600; font-weight:bold;">&#41;</span>
  <span style="color:#ff6633; font-weight:bold;">$searchdomain</span> = hiera<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">'searchdomain'</span><span style="color:#006600; font-weight:bold;">&#41;</span>
&nbsp;
  file <span style="color:#006600; font-weight:bold;">&#123;</span> <span style="color:#996600;">'/etc/resolv.conf'</span>:
    content <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">&quot;search ${searchdomain}<span style="color:#000099;">\n</span> nameserver ${dnsserver}<span style="color:#000099;">\n</span>&quot;</span>,
  <span style="color:#006600; font-weight:bold;">&#125;</span>
<span style="color:#006600; font-weight:bold;">&#125;</span></pre></td></tr></table></div>

<h3>PROS</h3>
<ul>
<li>Data is truly separated from your Puppet code—it exists in an entirely separate directory structure.</li>
<li>Parameter lookup is hierarchical and dynamic based on Facter facts that describe your node.</li>
<li>Hiera supports structured data—like arrays and hashes—that can be fed back to Puppet.</li>
<li>Using Hiera, your Puppet modules contain zero proprietary data (which makes the module much more portable).</li>
<li>Hiera will be integrated with the next version of Puppet (codenamed Telly).</li>
</ul>
<h3>CONS</h3>
<ul>
<li>As of this writing Hiera is not YET built into Puppet , so utilizing it requires an initial installation step.</li>
</ul>
<h2>Conclusion</h2>
<p>While there are a myriad of options to solve the problem of configuration data and Puppet code separation, we recommend using Hiera for its ability to adapt to every situation. This post only gives a brief glimpse of its awesome functionality. Stay tuned for a post dedicated to Hiera, where we will be looking in-depth at its usage, flexibility, and advanced features that can simplify the management of your environment whether you&#8217;re a sysadmin of 10, 100, or 10,000 nodes!</p>
<p><em>Additional Resources</em></p>
<ul>
<li>Come to <a href="http://atlantapuppetcamp.eventbrite.com/">Puppet Camp Atlanta</a> on February 3, and check out Gary&#8217;s talk on this topic.</li>
<li>Read the docs: <a href="http://docs.puppetlabs.com/guides/parameterized_classes.html#appendix-smart-parameter-defaults">Smart Parameter Defaults</a></li>
<li>Read the docs: <a href="http://docs.puppetlabs.com/guides/external_nodes.html">External Nodes</a></li>
<li>Read the docs: <a href="http://docs.puppetlabs.com/references/2.6.1/function.html#extlookup">Extlookup</a></li>
<li>Check out the <a href="http://projects.puppetlabs.com/projects/hiera">Hiera project</a>, and look for a more in-depth introduction next week.</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://puppetlabs.com/blog/the-problem-with-separating-data-from-puppet-code/feed/</wfw:commentRss>
		<slash:comments>9</slash:comments>
		</item>
		<item>
		<title>R.I. Pienaar Joins Puppet Labs</title>
		<link>http://puppetlabs.com/blog/ri-pineaar-joins-puppet-labs/</link>
		<comments>http://puppetlabs.com/blog/ri-pineaar-joins-puppet-labs/#comments</comments>
		<pubDate>Thu, 26 Jan 2012 17:33:53 +0000</pubDate>
		<dc:creator>Jason</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[Company]]></category>
		<category><![CDATA[General News]]></category>
		<category><![CDATA[MCollective]]></category>
		<category><![CDATA[marionette collective]]></category>
		<category><![CDATA[mcollective]]></category>
		<category><![CDATA[news]]></category>
		<category><![CDATA[puppet labs]]></category>
		<category><![CDATA[R.I. Pienaar]]></category>

		<guid isPermaLink="false">http://puppetlabs.com/?p=11840</guid>
		<description><![CDATA[I am very pleased to announce that R.I. Pienaar, founder and lead developer of the widely used Marionette Collective (MCollective) orchestration tools, has joined Puppet Labs as a Software Architect. R.I.’s message-based orchestration tools have become some of the most widely used tools in systems management, and have literally changed the way that people handle [...]]]></description>
			<content:encoded><![CDATA[<p>I am very pleased to announce that R.I. Pienaar, founder and lead developer of the widely used Marionette Collective (MCollective) orchestration tools, has joined Puppet Labs as a Software Architect. R.I.’s message-based orchestration tools have become some of the most widely used tools in systems management, and have literally changed the way that people handle ad-hoc command and control, orchestration, and parallel job management. Having R.I. join the Puppet Labs team is a significant milestone for us, as R.I. will help shape product efforts in MCollective, Puppet, and Puppet Enterprise.</p>
<p>Puppet Labs acquired MCollective from R.I. in late 2010. Since then, MCollective has become a critical piece of the Puppet infrastructure with direct integration in Puppet Enterprise for <a href="http://puppetlabs.com/blog/live-management-part-1-resource-browsing-and-cloning/">Live Management</a>, as well as standard orchestration functionality. R.I.’s efforts in this regard have had significant impact on product for the company including <a href="http://puppetlabs.com/puppet/puppet-enterprise/">Puppet Enterprise 2.0</a>.</p>
<p>R.I. will continue to work on MCollective (since MCollective is now directly integrated into our products), but will also work on some of our new projects to be announced in the future. We are very glad to have R.I.’s considerable creativity and industry experience on the team helping with new products that will give sysadmins new tools and delight Puppet users.</p>
<p>In R.I.&#8217;s own words:</p>
<blockquote><p>I&#8217;m really excited to finally be part of the Puppet Labs team.  I’ve been part time member for over a year and it&#8217;s great to finally be a full time team member.  I look forward to the opportunities this new venture brings in helping me further the DevOps eco-system.</p></blockquote>
]]></content:encoded>
			<wfw:commentRss>http://puppetlabs.com/blog/ri-pineaar-joins-puppet-labs/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Verifying Puppet: Checking Syntax and Writing Automated Tests</title>
		<link>http://puppetlabs.com/blog/verifying-puppet-checking-syntax-and-writing-automated-tests/</link>
		<comments>http://puppetlabs.com/blog/verifying-puppet-checking-syntax-and-writing-automated-tests/#comments</comments>
		<pubDate>Wed, 25 Jan 2012 16:24:01 +0000</pubDate>
		<dc:creator>Adrien</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[Community]]></category>
		<category><![CDATA[DevOps]]></category>
		<category><![CDATA[How to]]></category>
		<category><![CDATA[Systems Management]]></category>
		<category><![CDATA[Tips]]></category>
		<category><![CDATA[how to]]></category>
		<category><![CDATA[modules]]></category>
		<category><![CDATA[news]]></category>
		<category><![CDATA[puppet]]></category>
		<category><![CDATA[Puppet Enterprise]]></category>
		<category><![CDATA[sysadmin]]></category>
		<category><![CDATA[testing modules]]></category>
		<category><![CDATA[tips]]></category>

		<guid isPermaLink="false">http://puppetlabs.com/?p=11792</guid>
		<description><![CDATA[One of the issues that crops up when working with Puppet is ensuring that your manifests do what you expect. Errors are bound to happen. A missed brace can make a manifest not compile, or forgetting to include a module or set a variable may mean that running Puppet on the host fails to enforce [...]]]></description>
			<content:encoded><![CDATA[<p>One of the issues that crops up when working with Puppet is ensuring that your manifests do what you expect. Errors are bound to happen. A missed brace can make a manifest not compile, or forgetting to include a module or set a variable may mean that running Puppet on the host fails to enforce the expected state. All in all, it would help to have some tools to make sure we’re writing valid code, that it does what it expects, and that if it doesn’t we catch it as soon as possible.</p>
<h2>Syntax Checking</h2>
<p>At the lowest level of checking, you can use the Puppet parser to do syntax validation. Typos and errors are bound to creep into code, so syntax checking at the end of a long day can go far to improve the quality of your life.</p>
<p>There are a couple of places where you can insert syntax validation. One method is by manually running `puppet parser validate selinux.pp` to make sure that the manifest can be parsed before you commit your changes or deploy them to a live environment. If I left out a curly brace in a manifest and then used &#8216;puppet parser validate selinux.pp&#8217;, then:</p>

<div class="wp_syntax"><div class="code"><pre class="shell" style="font-family:monospace;">    % puppet parser validate selinux.pp
    err: Could not parse for environment production: Syntax error at ‘{‘; expected '}' at /Users/adrien/puppetlabs-mrepo/manifests/repo.pp:252
    err: Try 'puppet help parser validate' for usage</pre></div></div>

<p>Puppet parser tells me what went wrong, and which line contains the error.</p>
<p>In addition, you can integrate syntax checking into your editor. Vim has built in code compilation functionality that can be used to run error checking, so you can quickly validate your code and jump to sections of code with syntax errors. There are plugins like <a href="https://github.com/scrooloose/syntastic">Syntastic</a> that will do continuous checking so you&#8217;re immediately alerted when syntax errors are made. For example, if you used Syntastic with the same syntax error, you would see this: </p>
<div id="attachment_11793" class="wp-caption aligncenter" style="width: 610px"><a href="http://puppetlabs.com/wp-content/uploads/2012/01/Syntastic-error-output.png"><img src="http://puppetlabs.com/wp-content/uploads/2012/01/Syntastic-error-output.png" alt="Syntastic error output" title="Syntastic error output" width="600" height="400" class="size-full wp-image-11793" /></a><p class="wp-caption-text">Syntastic output identifies your syntax errors.</p></div>
<p>Lastly, there’s the <a href="https://github.com/rodjek/puppet-lint">puppet-lint</a> tool developed by <a href="http://www.github.com">GitHub</a>’s Tim Sharpe that will analyze your manifests and look for deviations from the Puppet <a href="http://docs.puppetlabs.com/guides/style_guide.html">style guide</a>. It’s a quick and easy way to ensure that everybody is following a common set of conventions, so as your module collection grows, you’ll have a consistent set of modules instead of sections with cobwebs. Running puppet-lint against a manifest could produce something like the following:</p>

<div class="wp_syntax"><div class="code"><pre class="shell" style="font-family:monospace;">% puppet-lint init.pp 
    WARNING: top-scope variable being used without an explicit namespace on line 79
    WARNING: top-scope variable being used without an explicit namespace on line 81
    WARNING: define defined inside a class on line 59
    ERROR: single quoted string containing a variable found on line 124
    WARNING: string containing only a variable on line 81
    WARNING: =&gt; on line isn't properly aligned for resource on line 71
    ERROR: two-space soft tabs not used on line 50
    WARNING: line has more than 80 characters on line 83
    WARNING: line has more than 80 characters on line 84
    ERROR: trailing whitespace found on line 163
    WARNING: mode should be represented as a 4 digit octal value on line 55</pre></div></div>

<p>Be warned that these steps only validate syntax. If you have variables that are incorrectly spelled or have a bad value, your code will still be completely valid—and will not do what you want. That’s why we have additional tools available to make sure you code actually works as intended.</p>
<h2>Writing Automated Tests</h2>
<p>Automated testing is one of the key ways to ensure that your libraries and manifests are meeting your expectations. Out of all the ways that you could test your manifests, I’ll highlight two: testing modules and their catalogs, and testing entire systems.</p>
<h2>Testing Modules</h2>
<p>As mentioned in a previous <a href="http://puppetlabs.com/blog/testing-modules-in-the-puppet-forge/">post</a> by our Release team, you can add rspec and cucumber tests to ensure that your modules are creating resources as you expect. </p>
<p>For example, you can write tests that ensure that when including a module to install Apache, the package Apache is installed and the service is started. If you were to further develop on that Apache module, you could move forward knowing that the tests would always ensure those basic behaviors would still exist, and if something changed by accident you would definitively know it had changed.</p>
<p>The <a href="https://github.com/puppetlabs/puppet-apt">puppet-apt module</a> has been a focus of a lot of testing, and is a great example of how you can test your modules. Given rspec tests looking like this:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">   it <span style="color:#006600; font-weight:bold;">&#123;</span> should create_exec<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">&quot;apt_update&quot;</span><span style="color:#006600; font-weight:bold;">&#41;</span>\
      .<span style="color:#9900CC;">with_subscribe</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;">'File[sources.list]'</span>,<span style="color:#996600;">'File[sources.list.d]'</span><span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">&#41;</span>\
      .<span style="color:#9900CC;">with_refreshonly</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#0000FF; font-weight:bold;">true</span><span style="color:#006600; font-weight:bold;">&#41;</span><span style="color:#006600; font-weight:bold;">&#125;</span></pre></div></div>

<p>would produce output like this:</p>

<div class="wp_syntax"><div class="code"><pre class="shell" style="font-family:monospace;">  apt
    Apt class with no parameters, basic test
      should create Class[&quot;apt&quot;]
      should create Exec[&quot;apt_update&quot;]
&nbsp;
Finished in 0.36027 seconds
2 example, 0 failures</pre></div></div>

<p>Writing tests is a good way to verify your modules are functional and reusable. Testing also serves as a indicator of quality, demonstrating you have taken the time to ensure the module does what you want it to do. Additionally, you can verify modules in the <a href=”http://forge.puppetlabs.com/”>Puppet Forge</a> if they have tests, and more easily check them for correctness. </p>
<h2>Testing Systems</h2>
<p>Unit testing individual modules is a great step to take, but at the end of the day you want to know running Puppet on a host will build the host the way you want, and will have the behavior you expect. Being able to pragmatically verify that services like SSH, Postgres, and nginx are running and serving resources is powerful stuff. </p>
<p>You can use <a href="http://cukes.info/">Cucumber</a> in a standalone manner to ensure that if you run Puppet on a host, you get the host you asked for when all is said and done. You can couple unit tests with system tests, and run everything in a testing environment before your changes go to production systems.</p>
<p>Martin Englund has blogged about his experiences with <a href="http://blogs.oracle.com/martin/entry/behavior_driven_infrastructure">“Behavior Driven Infrastructure”</a> (a play on Behavior Driven Development or BDD) with Cucumber, and did an excellent PuppetConf presentation about his experiences with <a href="http://www.youtube.com/watch?v=14Q0JFEzWXQ">Puppet and Cucumber</a>.</p>
<h2>Benefits of Testing Puppet Code</h2>
<p>Everybody wants to have as smooth and seamless a work flow as possible. Deploying changes to your Puppet manifests only to discover that you forgot a comma or brace, or writing a manifest that can’t actually run successfully, can require debugging time that would be better spent elsewhere. Adding a few proactive tools will prevent errors from propagating out, and being able to automatically verify your systems means that you can deploy changes fearlessly and become more agile in your day to day operations.</p>
<p><em>Additional Resources</em></p>
<ul>
<li><a href="http://docs.puppetlabs.com/guides/style_guide.html">Puppet Labs Style Guide</a></li>
<li><a href="http://puppetlabs.com/blog/testing-modules-in-the-puppet-forge/">Testing Modules in the Puppet Forge</a></li>
<li><a href="https://github.com/scrooloose/syntastic">Syntastic</a></li>
<li><a href="https://github.com/rodjek/puppet-lint">puppet-lint</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://puppetlabs.com/blog/verifying-puppet-checking-syntax-and-writing-automated-tests/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>Puppet Triage-A-Thon: The Results are In!</title>
		<link>http://puppetlabs.com/blog/puppet-triage-a-thon-the-results-are-in/</link>
		<comments>http://puppetlabs.com/blog/puppet-triage-a-thon-the-results-are-in/#comments</comments>
		<pubDate>Mon, 23 Jan 2012 22:33:45 +0000</pubDate>
		<dc:creator>James Turnbull</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[Community]]></category>
		<category><![CDATA[General News]]></category>
		<category><![CDATA[Open Source]]></category>
		<category><![CDATA[Users]]></category>
		<category><![CDATA[contest]]></category>
		<category><![CDATA[DevOps]]></category>
		<category><![CDATA[Events]]></category>
		<category><![CDATA[news]]></category>
		<category><![CDATA[open source]]></category>
		<category><![CDATA[puppet labs]]></category>
		<category><![CDATA[Thank you]]></category>

		<guid isPermaLink="false">http://puppetlabs.com/?p=11760</guid>
		<description><![CDATA[The first Puppet Triage-a-thon was a huge success. Thank you so much to everyone who attended and contributed! Some of our favorite stats from the event: We started the day with 2292 open tickets. Over the course of the day 565 tickets were triaged. We also closed 115 tickets. That&#8217;s almost 25% of the open [...]]]></description>
			<content:encoded><![CDATA[<p>The first Puppet Triage-a-thon was a huge success. Thank you so much to everyone who attended and contributed! Some of our favorite stats from the event:</p>
<ul>
<li>We started the day with 2292 open tickets. Over the course of the day 565 tickets were triaged. We also closed 115 tickets. That&#8217;s almost 25% of the open tickets triaged and 5% closed!</li>
<li>Seventeen community patches were submitted! (And many of these were merged during the day.) Several patches were from people who&#8217;ve never contributed before, which is awesome.</li>
<li>We had about 50 people involved globally. Individuals and teams participated from Germany, Mexico, Australia, United Kingdom, France, and across the United States. And a big shout-out to the Atlanta Puppet Users group who had a team of five people!  We also had about 10 community members onsite in the Puppet Labs offices locally in Portland.</li>
</ul>
<p>Our top contributors from the community were:</p>
<ol>
<li>Dominic Cleal</li>
<li>Devon Peters</li>
<li>Patrick Otto</li>
<li>Oliver Hookins</li>
</ol>
<p>They&#8217;ll be the recipients of $100 Amazon gift vouchers. The full list of participants is here, along with the tally of tickets triaged: <a href="http://triageathon.puppetlabs.com/">http://triageathon.puppetlabs.com/</a></p>
<p>Everyone who contributed will receive a Puppet Labs t-shirt. If you participated you&#8217;ll receive an email shortly asking you for your preferred t-shirt size and where you&#8217;d like us to send it.</p>
<p>We’re going to continue to run these events in the future to keep the ticket database fresh and up-to-date.</p>
<p>Thanks again to everyone who came along and contributed and made it such a great success and an awesome amount of fun!</p>
]]></content:encoded>
			<wfw:commentRss>http://puppetlabs.com/blog/puppet-triage-a-thon-the-results-are-in/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Newsletter &#8211; January 2012</title>
		<link>http://puppetlabs.com/blog/newsletter-january-2012/</link>
		<comments>http://puppetlabs.com/blog/newsletter-january-2012/#comments</comments>
		<pubDate>Fri, 20 Jan 2012 20:24:23 +0000</pubDate>
		<dc:creator>michelle</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[Company]]></category>
		<category><![CDATA[Conferences and Workshops]]></category>
		<category><![CDATA[DevOps]]></category>
		<category><![CDATA[General News]]></category>
		<category><![CDATA[How to]]></category>
		<category><![CDATA[Open Source]]></category>
		<category><![CDATA[Puppet Enterprise]]></category>
		<category><![CDATA[Tips]]></category>
		<category><![CDATA[newsletter]]></category>

		<guid isPermaLink="false">http://puppetlabs.com/?p=11691</guid>
		<description><![CDATA[Getting Started With Puppet Weekly Webinar: Ask Your Puppet Enterprise Questions Get a Live Management demo, and ask your burning PE questions. Puppet Enterprise 2.0 How To: Cloud Provisioning Start provisioning in the public and private cloud today. VIDEO: AWS CloudFormation and Puppet Enterprise 2.0 How to build out Puppet Enterprise stacks with CloudFormation. Forge [...]]]></description>
			<content:encoded><![CDATA[<table style="width: 100%; background-color:#f9fafa;" border="0" cellpadding="0" cellspacing="0">
<table border="0" cellpadding="0" cellspacing="0" width="100%">
<tr>
<td width="68%" style="background-color:#f9fafa; color:#45555f; font-family:Tahoma,Helvetica; font-size:12px; line-height:18px; vertical-align:top; padding:0px;">
<table border="0" cellpadding="0" cellspacing="0" width="100%">
<tr>
<td style="vertical-align:top;  font-size: 12px; font-family: Lucida, Verdana, sans-serif; background-color:#f9fafa; color: #45555f; line-height: 19px">
                                                <font style="font-size:120%;line-height:200%;font-weight:bold;">Getting Started With Puppet</font><br />
                                                <a href="http://puppetlabs.com/resources/webinars/">Weekly Webinar: Ask Your Puppet Enterprise Questions</a><br />
                                                <font style="font-size:100%;line-height:100%">Get a Live Management demo, and ask your burning PE questions.</font></p>
<p>                                                <a href="http://puppetlabs.com/blog/provisioning-in-the-cloud-with-puppet-enterprise-2-0/">Puppet Enterprise 2.0 How To: Cloud Provisioning</a><br />
                                                <font style="font-size:100%;line-height:100%;">Start provisioning in the public and private cloud today.</font></p>
<p>                                                <a href="http://puppetlabs.com/blog/using-cloudformation-to-build-out-fully-functional-stacks-of-puppet-enterprise/">VIDEO: AWS CloudFormation and Puppet Enterprise 2.0</a><br />
                                                <font style="font-size:100%;line-height:100%;">How to build out Puppet Enterprise stacks with CloudFormation.</font></p>
<p>                                                <a href="http://forge.puppetlabs.com/rtyler/jenkins">Forge Module of the Month: Jenkins</a><br />
                                                <font style="font-size:100%;line-height:100%">One of 200+ freely downloadable modules to help you get started.</font></p>
<p>                                                <a href="http://www.example42.com/?q=NextGen">The Next Generation of Example42 Puppet Modules</a><br />
                                                <font style="font-size:100%;line-height:100%;">Updated module collection for version 2.6 and later.</font></p>
<p>                                                <font style="font-size:40%;line-height:40%">&nbsp;</font></p>
<hr style="border:1px solid #cccccc; width:60%;" />
                                            </td>
</tr>
<p><!-- Puppet Master Power-Ups --></p>
<tr>
<td style="vertical-align:top;  font-size: 12px; font-family:  Lucida, Verdana, sans-serif; background-color:#f9fafa; color: #45555f; line-height: 19px">
                                                <font style="font-size:120%;line-height:200%;font-weight:bold;">Puppet Master Power-Ups</font></p>
<p>                                                <a href="http://puppetlabs.com/blog/puppetizing-opennebula/">Puppetizing OpenNebula</a><br />
                                                <font style="font-size:100%;line-height:100%">Provision a virtualized infrastructure.</font> </p>
<p>                                                <a href="http://bombasticmonkey.com/2011/12/27/stop-writing-puppet-modules-that-suck/">&#8220;Stop Writing Puppet Modules That Suck&#8221;</a><br />
                                                <font style="font-size:100%;line-height:100%;">&#8230;With these helpful steps!</font></p>
<p>                                                <a href="https://github.com/rodjek/puppet-profiler">Use it: Tim Sharpe&#8217;s Puppet Profiler</a><br />
                                                <font style="font-size:100%;line-height:100%">&#8220;Find out what&#8217;s making your Puppet runs so bloody slow!&#8221;</font></p>
<p>                                                <a href="http://www.masterzen.fr/2011/12/27/puppet-internals-the-parser/">Puppet Internals: The Parser</a><br />
                                                <font style="font-size:100%;line-height:100%;">Learn how Puppet translates code into configuration catalogs.</font></p>
<p>                                                <a href="http://www.gerapeldoorn.nl/freelance/linux-automation">Taking Puppet Enterprise deployment automation one step further</a><br />
                                                <font style="font-size:100%;line-height:100%">Deploy a server with a single command.</font></p>
<p>                                                <font style="font-size:40%;line-height:40%">&nbsp;</font></p>
<hr style="border:1px solid #cccccc; width:60%;" />
                                            </td>
</tr>
<p><!-- Graphic of the Month --></p>
<tr>
<td style="vertical-align:top; font-size: 12px; font-family:  Lucida, Verdana, sans-serif; background-color:#f9fafa; color: #45555f; line-height: 19px">
                                                <font style="font-size:120%;line-height:160%;font-weight:bold;">Graphic of the Month</font><br />
                                                <font style="font-size:100%;line-height:100%;">Read the blog and watch the video to <a href="http://puppetlabs.com/blog/using-cloudformation-to-build-out-fully-functional-stacks-of-puppet-enterprise/">build out Puppet Enterprise stacks with AWS CloudFormation</a>.</font><br />
                                                <font style="font-size:80%;line-height:90%">&nbsp;</font></p>
<div style="width:200px">
                                                    <a href="http://puppetlabs.com/blog/using-cloudformation-to-build-out-fully-functional-stacks-of-puppet-enterprise/" title="AWS CloudFormation and Puppet Enterprise"><br />
                                                        <img width="320" height="178" style="float:middle" src="http://info.puppetlabs.com/rs/puppetlabs/images/Puppet Enterprise and CloudFormation.png" border="0" alt="Use AWS CloudFormation and Puppet Enterprise 2.0" /><br />
                                                    </a>
                                                </div>
<p>                                                <font style="font-size:80%;line-height:90%">&nbsp;</font></p>
<hr style="border:1px solid #cccccc; width:60%;" />
                                            </td>
</tr>
<p><!-- DevOps In Action --></p>
<tr>
<td style="vertical-align:top;  font-size: 12px; font-family:  Lucida, Verdana, sans-serif; background-color:#f9fafa; color: #45555f; line-height: 19px">
                                                <font style="font-size:120%;line-height:200%;font-weight:bold;">DevOps In Action</font></p>
<p>                                                <a href="http://spin.atomicobject.com/2011/12/29/puppet-gephi-visualizing-infrastructure-as-code/">Puppet + Gephi: Visualizing Infrastructure as Code</a><br />
                                                <font style="font-size:100%;line-height:100%">Use your resource graph for DevOpsy goodness.</font></p>
<p>                                                <a href="http://puppetlabs.com/services/consulting/#devopsconsulting">DevOps Process Consulting</a><br />
                                                <font style="font-size:100%;line-height:100%">Get a jumpstart on your DevOps environment.</font></p>
<p>                                                <font style="font-size:40%;line-height:40%">&nbsp;</font></p>
<hr style="border:1px solid #cccccc; width:60%;" />
                                            </td>
</tr>
<p><!-- Puppet In The News --></p>
<tr>
<td style="vertical-align:top;  font-size: 12px; font-family:  Lucida, Verdana, sans-serif; background-color:#f9fafa; color: #45555f; line-height: 19px">
                                                <font style="font-size:120%;line-height:200%;font-weight:bold;">Puppet In The News</font></p>
<p>                                                <a href="http://servicesangle.com/blog/2011/12/26/open-source-startups-to-watch-in-2012-puppet-labs/">Services ANGLE: &#8220;5 Open Source Startups to Watch in 2012&#8243;</a><br />
                                                <font style="font-size:100%;line-height:100%;">Reading the newsletter is a good start.</font></p>
<p>                                                <a href="http://servicesangle.com/blog/2011/12/29/top-10-developer-and-engineering-skills-employers-will-look-for-going-into-2012/">Services ANGLE: Top 10 Dev &#038; Eng Skills Employers will be Looking for Going into 2012</a><br />
                                                <font style="font-size:100%;line-height:100%;">Check the full list before making your New Year&#8217;s resolutions.</font></p>
<hr style="border:1px solid #cccccc; width:60%;" />
                                            </td>
</tr>
<p><!-- In Case You Missed It --></p>
<tr>
<td style="vertical-align:top;  font-size: 12px; font-family:  Lucida, Verdana, sans-serif; background-color:#f9fafa; color: #45555f; line-height: 19px">
                                                <font style="font-size:120%;line-height:200%;font-weight:bold;">In Case You Missed It</font></p>
<p>                                                <a href="http://puppetlabs.com/blog/looking-forward-to-2012-design-big-data-in-the-infrastructure-and-devops/">From Luke: Looking Forward to 2012</a><br />
                                                <font style="font-size:100%;line-height:100%;">Design, Big Data in the Infrastructure, and DevOps.</font></p>
<p>                                                <a href="http://puppetlabs.com/blog/thank-you-oss-for-puppet-enterprise-2-0/">Thank You, O.S.S. for P.E. 2.0</a><br />
                                                <font style="font-size:100%;line-height:100%">Puppet Enterprise didn&#8217;t come out of nowhere.</font></p>
<p>                                                <a href="http://www.bizjournals.com/portland/event/56361">Portland Business Journal names Top Forty Under 40</a><br />
                                                <font style="font-size:100%;line-height:100%;">Big thanks to the PBJ.</font></p>
<p>                                                <font style="font-size:40%;line-height:40%">&nbsp;</font></p>
</td>
</tr>
</table>
</td>
<p><!-- right column --></p>
<td style="background-color: #f9fafa;color: #45555f; font-family: Tahoma,Helvetica;font-size: 12px; line-height: 18px; vertical-align: top; padding: 0px;">
<table border="0" cellpadding="0" cellspacing="0" width="100%">
<p><!-- Upcoming Puppet Camps --></p>
<tr>
<td style="vertical-align:top;  font-size: 12px; font-family:  Lucida, Verdana, sans-serif; background-color:#f9fafa; color: #45555f; line-height: 19px">
                                                <font style="font-size:120%;line-height:200%;font-weight:bold;">Puppet Camps</font><br /><a href="http://puppetlabs.com/community/puppet-camp/" title="Puppet Camp"></p>
<p>                                                <a href="http://atlantapuppetcamp.eventbrite.com/">Atlanta</a><br />
                                                <font style="font-size:80%;line-height:90%;">Feb 3</font></p>
<p>                                                <a href="http://booking.flossuk.org/">Edinburgh</a><br />
                                                <font style="font-size:80%;line-height:90%;">March 23</font></p>
<p>                                                <a href="http://stockholmpuppetcamp.eventbrite.com/">Stockholm</a><br />
                                                <font style="font-size:80%;line-height:90%">March 28</font></p>
<div align="right">
                                                    <a href="http://puppetlabs.com/community/puppet-camp/">more&#8230;</a><br />
                                                  </font>
                                                </div>
<p><!-- Upcoming Events --></p>
<tr>
<td style="vertical-align:top;  font-size: 12px; font-family:  Lucida, Verdana, sans-serif; background-color:#f9fafa; color: #45555f; line-height: 19px">
                                                <font style="font-size:120%;line-height:200%;font-weight:bold;">Upcoming Events</font></p>
<p>                                                <a href="http://puppetlabs.com/resources/webinars/">Puppet Enterprise 2.0 Q&#038;A webinars</a><br />
                                                <font style="font-size:80%;line-height:90%;">Fri, Jan 13</font></p>
<p>                                                <a href="http://puppetlabs.com/blog/scale10/">SCALE 10X &#8211; Los Angeles</a><br />
                                                <font style="font-size:80%;line-height:90%">Fri, Jan 20 &#8211; Sun, Jan 22</font></p>
<p>                                                <a href="http://puppetlabs.com/events/triagepuppet/">Puppet Triage-A-Thon</a><br />
                                                <font style="font-size:80%;line-height:90%;">Sat, Jan 21</font></p>
<p>                                                <a href="http://www.fosdem.org/2012/">FOSDEM &#8211; Brussels</a><br />
                                                <font style="font-size:80%;line-height:90%;">Sat, Feb 4 &#8211; Sun, Feb 5</font></p>
<hr style="border:1px solid #cccccc; width:70%;" />
                                            </td>
</tr>
<p> <!-- Upcoming Training -->                                       </p>
<tr>
<td style="vertical-align:top;  font-size: 12px; font-family:  Lucida, Verdana, sans-serif; background-color:#f9fafa; color: #45555f; line-height: 19px">
                                                <font style="font-size:80%;line-height:90%">&nbsp;</font>                                                </p>
<p>                                                <font style="font-size:120%;line-height:200%;font-weight:bold;">Upcoming Trainings</font><br />
                                                <a href="http://puppetlabs.com/events/san-jose-puppet-master-training/">San Jose</a><br />
                                                <font style="font-size:80%;line-height:90%;">Mon, Jan 16 &#8211; Wed, Jan 18</font></p>
<p>                                                <a href="http://puppetlabs.com/events/london-puppet-master-training/">London</a><br />
                                                <font style="font-size:80%;line-height:90%;">Tue, Jan 24 &#8211; Thu, Jan 26</font></p>
<p>                                                <a href="http://puppetlabs.com/events/netways-sponsored-puppet-master-training-nuremberg/">Sponsored by Netways &#8211; Nuremberg</a><br />
                                                <font style="font-size:80%;line-height:90%;">Wed, Dec 7 &#8211; Fri, Dec 9</font></p>
<p>                                                <a href="http://puppetlabs.com/events/sao-paulo-puppet-master-training/">Sao Paulo</a><br />
                                                <font style="font-size:80%;line-height:90%;">Mon, Jan 30 &#8211; Wed, Feb 1</font></p>
<p>                                                <a href="http://puppetlabs.com/events/atlanta-puppet-master-training-2/">Atlanta</a><br />
                                                <font style="font-size:80%;line-height:90%;">Tue, Jan 31 &#8211; Thu, Feb 2</font></p>
<div align="right">
                                                        <a href="http://puppetlabs.com/category/events/upcoming">more&#8230;</a><br />
                                                    </font>
                                                </div>
<hr style="border:1px solid #cccccc; width:70%;" />
                                            </td>
</tr>
<p><!-- New Open Source -->                                       </p>
<tr>
<td style="vertical-align:top;  font-size: 12px; font-family:  Lucida, Verdana, sans-serif; background-color:#f9fafa; color: #45555f; line-height: 19px">
                                                <font style="font-size:80%;line-height:90%">&nbsp;</font>                                               </p>
<p>                                                <font style="font-size:120%;line-height:200%;font-weight:bold;">New Open Source</font></p>
<p>                                                <a href="https://github.com/jfryman/puppet-puppetdoc">puppet-puppetdoc</a><br />
                                                <font style="font-size:80%;line-height:90%;">By James Fryman</font></p>
<div align="right">
                                                        <a href="http://forge.puppetlabs.com/">more&#8230;</a><br />
                                                    </font>
                                                </div>
<hr style="border:1px solid #cccccc; width:70%;" />
                                            </td>
</tr>
<p><!-- New Jobs -->                                       </p>
<tr>
<td style="vertical-align:top;  font-size: 12px; font-family:  Lucida, Verdana, sans-serif; background-color:#f9fafa; color: #45555f; line-height: 19px">
                                                <font style="font-size:80%;line-height:90%">&nbsp;</font>                                               </p>
<p>                                                <font style="font-size:120%;line-height:200%;font-weight:bold;">Job Openings</font><br />
                                                <a href="http://puppetlabs.jobscore.com/jobs/puppetlabs/intern-sysadmin-release/bxsN6ykcGr4AsSeJe4bk1X">Release Intern</a></p>
<p>                                                <a href="http://puppetlabs.jobscore.com/jobs/puppetlabs/community-manager/cz-1Zymner4zpZeJe4bk1X">Community Manager</a></p>
<p>                                                <a href="http://puppetlabs.jobscore.com/jobs/puppetlabs/senior-professional-services-engineer-usa-portland-or-remote/c_ib7WlpCr4yhCeJe4bk1X">Sr. Professional Services Engineer (USA)</a></p>
<p>                                                <a href="http://puppetlabs.jobscore.com/jobs/puppetlabs/technical-writer/aLx9FgiSmr4zfmeJe4bk1X">Technical Writer</a></p>
<div align="right">
                                                    <a href="http://www.puppetlabs.com/company/jobs/">more&#8230;</a><br />
                                                  </font>
                                                </div>
<hr style="border:1px solid #cccccc; width:70%;" />
                                            </td>
</tr>
<p><!-- Connect With Users -->                                       </p>
<tr>
<td style="vertical-align:top;  font-size: 12px; font-family:  Lucida, Verdana, sans-serif; background-color:#f9fafa; color: #45555f; line-height: 19px">
                                                <font style="font-size:80%;line-height:90%">&nbsp;</font>                                               </p>
<p>                                                <font style="font-size:120%;line-height:200%;font-weight:bold;">User Groups</font></p>
<p>                                                <a href="http://www.meetup.com/sipmug/">Silicon Valley</a><br />
                                                <a href="http://www.meetup.com/lapmug/">Los Angeles</a><br />
                                                <a href="https://groups.google.com/group/puppet-nyc?pli=1">New York City</a><br />
                                                <a href="http://www.meetup.com/Seattle-Puppet-Meetup/">Seattle</a><br />
                                                <a href="http://www.meetup.com/South-East-Puppet-User-Group/">Atlanta</a><br />
                                                <a href="http://spug.ch/">Switzerland</a><br />
                                                <a href="https://www.facebook.com/home.php?sk=group_192847720730511&#038;ap=1">Italy</a></p>
<p>                                                <font style="font-size:80%;line-height:90%">&nbsp;</font>
                                            </td>
</tr>
<p><!-- Connect With Us -->                                       </p>
<tr>
<td style="vertical-align:top;  font-size: 12px; font-family:  Lucida, Verdana, sans-serif; background-color:#f9fafa; color: #45555f; line-height: 19px">
<p>                                                <font style="font-size:120%;line-height:200%;font-weight:bold;">Connect With Us</font><br />
                                                <font style="font-size:80%;line-height:90%">&nbsp;</font><br />
                                                <a href="http://feeds.feedburner.com/PuppetLabs" target="_blank"><img src="http://www.puppetlabs.com/wp-content/plugins/my-profiles/images/rss.png" border="0" alt="RSS"></a><a href="http://www.facebook.com/pages/Puppet-Labs/219089920711" target="_blank"><img src="http://www.puppetlabs.com/wp-content/plugins/my-profiles/images/facebook.png" border="0" alt="Facebook"></a><a href="http://www.twitter.com/puppetlabs" target="_blank"><img src="http://www.puppetlabs.com/wp-content/plugins/my-profiles/images/twitter.png" border="0" alt="Twitter"></a><a href="http://www.linkedin.com/groups?about=&amp;gid=696467&amp;trk=anet_ug_grppro" target="_blank"><img src="http://www.puppetlabs.com/wp-content/uploads/2011/01/LinkedIn_IN_Icon_32px.png" border="0" alt="LinkedIn"></a><br />
                                                <a href="http://www.slideshare.net/PuppetLabs/" target="_blank"><img src="http://www.presentationadvisors.com/wp-content/uploads/2011/05/slideshare-logo-300x300.png" border="0" alt="SlideShare" width="32" height="32"></a><a href="http://www.youtube.com/user/PuppetLabsInc/featured" target="_blank"><img src="http://puppetlabs.com/wp-content/uploads/2012/01/youtube_logo_red.png" border="0" alt="YouTube" width="32" height="32"></a><a href="http://www.flickr.com/photos/puppetlabs/sets/72157627792058881/"><img src="http://aux.iconpedia.net/uploads/1400296969.png" border="0" alt="flickr" width="32" height="32"></a><a href="http://webchat.freenode.net/?channels=puppet"><img src="https://encrypted-tbn2.google.com/images?q=tbn:ANd9GcTl0DGG6Zr3GCzmxwEC8PDPCbAZ3EGlPqL-8HgC_vUs_kqAvWH_" border="0" alt="IRC" width="32" height="32"></a><br />
                                                <a href="mailto:pe-users@puppetlabs.com">Puppet Enterprise users list</a><br />
                                                <a href="http://groups.google.com/group/puppet-users">Puppet users list</a><br />
                                                <a href="http://groups.google.com/group/puppet-dev">Puppet dev list</a></p>
<p>                                                <font style="font-size:80%;line-height:90%">&nbsp;</font><br />
                                                <a href="http://www.puppetlabs.com/company/contact-us/">&#8230;or contact us directly</a>
                                            </td>
</tr>
</table>
</td>
</tr>
</table>
</td>
</tr>
</table>
</td>
</tr>
</table>
]]></content:encoded>
			<wfw:commentRss>http://puppetlabs.com/blog/newsletter-january-2012/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Melbourne Puppet Master Training</title>
		<link>http://puppetlabs.com/events/melbourne-puppet-master-training/</link>
		<comments>http://puppetlabs.com/events/melbourne-puppet-master-training/#comments</comments>
		<pubDate>Fri, 20 Jan 2012 15:52:05 +0000</pubDate>
		<dc:creator>michelle</dc:creator>
				<category><![CDATA[Events]]></category>

		<guid isPermaLink="false">http://puppetlabs.com/events/melbourne-puppet-master-training/</guid>
		<description><![CDATA[Puppet Master Curriculum (3 Days) This training is ideal for those who want a Puppet jumpstart. Newer members at an organization already using Puppet, or experienced sysadmins wanting to bring Puppet into their team will get everything they need to deploy solutions. Prerequisites: Attendees should have at least the equivalent experience of a junior Unix/Linux [...]]]></description>
			<content:encoded><![CDATA[<h2>Puppet Master Curriculum (3 Days)</h2>
<p>This training is ideal for those who want a Puppet jumpstart. Newer members at an organization already using Puppet, or experienced sysadmins wanting to bring Puppet into their team will get everything they need to deploy solutions.</p>
<p><a href="http://puppet-training-melbourne-march-2012.eventbrite.com?ref=ebtn" target="_blank"  ><img border="0" src="http://www.eventbrite.com/registerbutton?eid=2637652289" alt="Register for Puppet Master Training: Melbourne, Australia  in Melbourne, Victoria  on Eventbrite" /></a></p>
<h3>Prerequisites:</h3>
<p>Attendees should have at least the equivalent experience of a junior Unix/Linux administrator.</p>
<h3>Topics covered include:</h3>
<ul>
<li>Configuring Puppet and Puppetmaster</li>
<li>Resource Types and the Resource Abstration Layer</li>
<li>Virtual Resources, Exported Resources and Stored Configs</li>
<li>Meta-parameters, Dependencies and Events</li>
<li>Classes, Modules and Definitions</li>
<li>Tags and Environments</li>
<li>Puppet Language Patterns and Best Practices</li>
</ul>
<p>The topics are covered over 3 days. Sessions will mix theory and practice, balancing lectures with hands-on exercises. (Each student should bring a WiFi enabled laptop with VMWare installed to participate in the labs.)</p>
<h2>Pricing</h2>
<ul>
<li>$2,395 by March 5, 2012; $2,595 on or after October 6, 2012.</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://puppetlabs.com/events/melbourne-puppet-master-training/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

