<?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>Silas Sewell - Configuration Management</title>
        <atom:link href="http://www.silassewell.com/blog/tag/configuration-management/rss2.xml" rel="self" type="application/rss+xml" />
        <link>http://www.silassewell.com/blog/tag/configuration-management</link>
        <description>Infrastructure Development</description>
        <lastBuildDate>Sat, 21 Aug 2010 00:00:00 GMT</lastBuildDate>
        <generator>http://www.silassewell.com/</generator>
        <language>en</language>
        <sy:updatePeriod>hourly</sy:updatePeriod>
        <sy:updateFrequency>1</sy:updateFrequency>

        <item>
            <title>Managing Large Networks with Puppet</title>
            <link>http://www.silassewell.com/blog/2009/05/04/managing-large-networks-with-puppet/</link>
            <pubDate>Mon, 04 May 2009 00:00:00 GMT</pubDate>
            <dc:creator>silas</dc:creator>
            <category><![CDATA[Configuration Management]]></category><category><![CDATA[Fedora]]></category><category><![CDATA[Puppet]]></category><category><![CDATA[Ruby]]></category><category><![CDATA[Systems Administration]]></category>
            <guid isPermaLink="true">http://www.silassewell.com/blog/2009/05/04/managing-large-networks-with-puppet/</guid>
            <description><![CDATA[<p><a href="http://projects.puppetlabs.com/projects/puppet" title="Puppet">Puppet</a> is an open source configuration management tool written in
Ruby. It allows a systems administrator to define how a system should be
configured using <a href="http://docs.reductivelabs.com/guides/language_tutorial.html" title="Puppet Language Tutorial">Puppet's</a> <a href="http://en.wikipedia.org/wiki/Declarative_programming" title="Declarative Programming">declarative language</a>. Each Puppet
client pulls its <a href="http://projects.puppetlabs.com/projects/puppet/wiki/Glossary_Of_Terms#catalog" title="Puppet Catalog">catalog</a> at a regular interval and figures out how
to make the catalog definitions true for the local operating system.</p>

<p>The <a href="http://docs.puppetlabs.com/guides/introduction.html" title="Puppet Introduction">Puppet Introduction</a> uses the following diagram to show how
Puppet works.</p>

<p><img src="http://www.silassewell.com/blog/2009/05/04/managing-large-networks-with-puppet/puppet_star.png" alt="Puppet" title="Puppet" /></p>

<p>Currently Puppet is most useful when you have lots of nodes with similar setups. Unfortunately Puppet's declarative language is a bit weak when it comes to inheritance and users familiar with true object oriented systems will soon become frustrated (at least I did). I'm assuming this issue will be addressed in the future, but for now I'm going to tell you how I setup a 100+ node system while adhering to <a href="http://en.wikipedia.org/wiki/Don%27t_repeat_yourself" title="DRY principles">DRY principles</a>.</p>

<p>A quick note, I'm assuming you already know how to use Puppet.</p>

<p>First lets start with the Puppetmaster configuration layout:</p>

<pre><code class="prettyprint">puppet/
 - fileserver.conf
 - manifests/
   - classes/
     - initialize.pp
   - nodes/
     - net/
       - example/
         - web01.pp   # web01.example.net
   - site.pp
   - templates.pp
 - modules/           # application specific modules
   - httpd/
     - files/         # static assets (ex: default HTML file)
     - manifests/     # application configuration logic
     - templates/     # dynamic configuration files (ex: httpd.conf)
</code></pre>

<p><small>The layout was adapted from recommendations in <a href="http://www.amazon.com/Pulling-Strings-Puppet-Configuration-Management/dp/1590599780" title="Pulling Strings with Puppet">Pulling Strings with Puppet</a> by James Turnbull.</small></p>

<p>When I was initially designing my Puppet setup the common practice was to define and initialize the various Puppet types and classes throughout the inheritance tree. So if you had a generic resolv.conf configuration you would include it at the top of the inheritance tree. This worked great until I needed to change one attribute of a class further down. I initially tackled this problem by hacking in if/case statements, but eventually it became unmanageable.</p>

<p>After a couple of rewrites I came up with the idea of wrapping the internals of each class in a conditional statement and initializing all classes at the end of each node.</p>

<p>The key components of my setup were:</p>

<ul>
<li>import all modules in the site.pp manifest</li>
<li>wrap the code of each class in a conditional statement</li>
<li>define and extend attributes throughout the inheritance tree (including the class conditional)</li>
<li>include all classes at the end of each node</li>
</ul>

<p>This lets you both arbitrarily redefine or extend class attributes (including the on/off state) throughout the inheritance tree.</p>

<p>I've created a <a href="http://silassewell.googlecode.com/svn/trunk/2009/05/03/puppet/" title="Simple Example">simple example</a> to show how this setup works. The main files are listed below (you'll want to go through each in order):</p>

<ul>
<li><a href="http://www.silassewell.com/blog/2009/05/04/managing-large-networks-with-puppet/site.pp" title="site.pp">site.pp</a> - import modules</li>
<li><a href="http://www.silassewell.com/blog/2009/05/04/managing-large-networks-with-puppet/templates.pp" title="template.pp">templates.pp</a> - define and extend class attributes</li>
<li><a href="http://www.silassewell.com/blog/2009/05/04/managing-large-networks-with-puppet/web01.pp" title="web01.pp">web01.pp</a> - make use of defaults</li>
<li><a href="http://www.silassewell.com/blog/2009/05/04/managing-large-networks-with-puppet/ns01.pp" title="ns01.pp">ns01.pp</a> - disable a class</li>
<li><a href="http://www.silassewell.com/blog/2009/05/04/managing-large-networks-with-puppet/initialize.pp" title="initialize.pp">initialize.pp</a> - initialize all classes</li>
<li><a href="http://www.silassewell.com/blog/2009/05/04/managing-large-networks-with-puppet/client.pp" title="client.pp">client.pp</a> - class implementation</li>
</ul>

<p>Also note that I designed this setup about 8 months ago and I haven't kept as up-to-date on recent developments as I should. If there is a better way to do this please let me know.</p>]]></description>
        </item>

        <item>
            <title>Profile Management with Git and GitHub</title>
            <link>http://www.silassewell.com/blog/2009/03/08/profile-management-with-git-and-github/</link>
            <pubDate>Sun, 08 Mar 2009 00:00:00 GMT</pubDate>
            <dc:creator>silas</dc:creator>
            <category><![CDATA[Bash]]></category><category><![CDATA[Configuration Management]]></category><category><![CDATA[Git]]></category><category><![CDATA[Projects]]></category><category><![CDATA[Systems Administration]]></category>
            <guid isPermaLink="true">http://www.silassewell.com/blog/2009/03/08/profile-management-with-git-and-github/</guid>
            <description><![CDATA[<p>The following describes a simple way to manage you profile configuration files using GitHub.</p>

<h3>Features</h3>

<ul>
<li>Centralized configuration management</li>
<li>Files live in their native locations (no symbolic linking)</li>
<li>Home directory is not a Git repository</li>
<li>All the power of git with a simple alias</li>
</ul>

<h3>Setup Repository</h3>

<ul>
<li>Log into <a href="http://github.com/" title="GitHub">GitHub</a> and create a repository named config</li>
<li>Add your <a href="http://github.com/guides/providing-your-ssh-key" title="Public Keys to GithHub">public keys to GitHub</a> (if you haven't done so already)</li>
<li><p>Open a terminal and switch to your home directory</p>

<pre><code class="prettyprint">cd ~
</code></pre></li>
<li><p>Create a configuration directory</p>

<pre><code class="prettyprint">mkdir .config.git
</code></pre></li>
<li><p>Add the following alias to your current session and your <code class="prettyprint">.bash_profile</code></p>

<pre><code class="prettyprint">alias config='git --git-dir=$HOME/.config.git/ --work-tree=$HOME'
echo "alias config='git --git-dir=$HOME/.config.git/ --work-tree=$HOME'" &gt;&gt; .bash_profile
</code></pre></li>
<li><p>Add your <code class="prettyprint">.bash_profile</code> to the configuration repository</p>

<pre><code class="prettyprint">config add .bash_profile
</code></pre></li>
<li><p>Commit the changes</p>

<pre><code class="prettyprint">config commit -m 'Initial commit'
</code></pre></li>
<li><p>Change the origin to GitHub</p>

<pre><code class="prettyprint">config remote add origin git@github.com:GITHUB_USERNAME/config.git
</code></pre></li>
<li><p>Push the changes</p>

<pre><code class="prettyprint">config push origin master
</code></pre></li>
</ul>

<p>If you get an error when running <code class="prettyprint">config pull</code> to the effect of <code class="prettyprint">You asked me to pull without...</code> run the follow:</p>

<pre><code class="prettyprint">    echo -e '[branch "master"]\n  remote = origin\n  merge = refs/heads/master' &gt;&gt; ~/.config.git/config
</code></pre>

<h3>Setup Configuration Management on a Different System</h3>

<ol>
<li>Add your <a href="http://github.com/guides/providing-your-ssh-key" title="Public Keys to GithHub">public keys to GitHub</a> (if you haven't done so already)</li>
<li><p>Switch to your home directory</p>

<pre><code class="prettyprint">cd ~
</code></pre></li>
<li><p>Backup your local configuration files, example:</p>

<pre><code class="prettyprint">mv .bash_profile .bash_profile.bk
</code></pre></li>
<li><p>Clone your configuration repository</p>

<pre><code class="prettyprint">git clone git@github.com:GITHUB_USERNAME/config.git config.git
</code></pre></li>
<li><p>Move the git metadata to <code class="prettyprint">~/.config.git</code></p>

<pre><code class="prettyprint">mv config.git/.git .config.git
</code></pre></li>
<li><p>Enable dotglob</p>

<pre><code class="prettyprint">shopt -s dotglob
</code></pre></li>
<li><p>Move your configuration files to your home directory</p>

<pre><code class="prettyprint">mv -i config.git/* .
</code></pre></li>
<li><p>Delete the <code class="prettyprint">config.git</code> directory</p>

<pre><code class="prettyprint">rmdir config.git
</code></pre></li>
<li><p>Logout and log back in</p></li>
</ol>

<h3>Basic Usage</h3>

<ul>
<li><code class="prettyprint">config pull</code> - get latest configuration changes</li>
<li><code class="prettyprint">config add FILENAME</code> - add a configuration file</li>
<li><code class="prettyprint">config commit -a</code> - save all configuration changes</li>
<li><code class="prettyprint">config push</code> - push configuration changes to GitHub</li>
<li>and any other <code class="prettyprint">config GIT_OPTION</code></li>
</ul>

<p>You can see my configuration repository at <a href="http://github.com/silas/config" title="config">http://github.com/silas/config</a>.</p>

<p>Source: <a href="http://robescriva.com/2009/01/manage-your-home-with-git/" title="source">Manage your $HOME with git</a> by Robert Escriva</p>]]></description>
        </item>

    </channel>
</rss>