Facter 10102 Apr 2013
Facter is what gives Puppet it’s brains. It collects information about the computer it is run on and then passes it to the Puppet Master for use in manifests and can optionally be stored. I know, it doesn’t sound like the most earth shattering revelation of all time, but stop for a moment. Every time your current scripts need to taget a specific OS version or a machine with a certain bit of hardware, you need to code it directly into the script. If the method of extracting that information changes, you need to modify every single script that uses that method. With Facter, you’re editing one file, which is always up to date on the client. Anyway, that’s enough waffle from me. Let’s get started.
- Either a Mac running 10.8 that you don’t mind wiping, or a Virtual Machine running in VMWare Fusion or similar.
- Git (Install the Command Line Tools from within Xcode’s preferences if you don’t have it).
We need a Puppet Master - fortunately there’s one pre-built that has everything we need. Make sure you’ve installed everything in the requirements, and then open up your trusty Terminal:
This will pull down the needed bits to get your own Puppet Master running and then
vagrant up will start things going. If you get errors about Postgres, just issue a
Now for your test Mac: I’ve made a script to automate the process. If you don’t have a DNS entry for your Puppet Master, and you’re using the Vagrant setup described above, run this in your terminal:
If you are using a different setup, please refer to the script’s readme for more information
Learn some Facts
On your client machine, run this in a Terminal
Your test Mac will churn away for a minute and then spit out a ton of information - you’ll see everything from the uptime of the machine to the amount of RAM. Still not overly useful sitting on that one machine. We need this information somewhere central to make use of it.
We need to make one small change to
~/src/facter-101/puppet/manifests/site.pp to get the puppet run working:
This is to stop Puppet complaining that there’s nothing to import - which there isn’t yet.
Assuming your Puppet Master is running, this is on your test Mac:
You’ll see a load of files being synced to your test Mac - these are custom Facts, plugins and assorted other goodies being pulled from the server. We’ll get to using custom Facts in a moment. If you load up http://192.168.33.10:3000 in your browser of choice, you’ll see your client having checked into Puppet. Click on it’s hostname and you’ll be presented with a list of all of the available Facts for that machine.
That’s all very nice, but what can we use it for?
We’re going to install some extra facts from the Puppet Forge onto our Master, and then write some code to target a specific set of machines. In our fictional world, every Mac with 4GB or more of RAM will be designated a “design” Mac. We’ll install Firefox on those (that’s a design app, right?).
First we’ll install the extra Facts onto our Master from the Forge.
Now we’ll write a class that will:
- Test that the client machine is a Mac
- Test that the client machine also has more than 4GB RAM
- If both conditions are satisfied, will install Firefox.
~/src/facter-101/puppet/manifests/classes/design.ppand make it look like the following.
Puppet has a default node - all machines checking into the Master get anything that’s declared in this node by default. Open up
~/src/facter-101/puppet/manifests/site.pp and make it look like:
We’ve added some classes, so the Puppet Master process needs to be restarted - rebooting the whole VM is probably quicker.
On your Test Mac, perform a Puppet run.
Depending on how much memory is in your test Mac, this might or might not do anything. Play with the $::mac_memory_in_gb value, starting high and then bringing it down to the amount of RAM in your test Mac - or if you are running your test Mac in a VM, you could also adjust the amount of memory assigned to it.
So that’s Facter - you’re not limited to using this with the default node, this technique can be used anywhere you write Puppet code. Try changing your design.pp file to look like the following - we’re using Facter Facts directly within our manifest to write data to the test Mac.
Which gives us
This is a very simple example of how you can use Facter to configure your machines. Facter can be used anywhere you’d set a variable manually - the Puppet documentation on Conditional Statements is an excellent next step with dynamically assigning configuration to your machines.